The calculate_dynamic_price() method
Every flow must implement:
$cart_item_data— the full WooCommerce cart item array for a single item. It contains all metadata added byprepare_cart_metadata(), plus WooCommerce internals.- Return value — a
floatprice in the store currency (Colombian pesos for UTB), ornullto leave the WooCommerce product price unchanged.
Return
null — not 0.0 — when you want the default product price to apply. Returning 0.0 sets the item price to zero.Cart metadata flow
The path from form submission to a priced cart item is:Customer submits the form
The form POSTS to
/?add-to-cart={product_id}. Raw field values arrive in $_POST.AbstractFlow calls validate_cart_data()
The
woocommerce_add_to_cart_validation hook fires. AbstractFlow calls your validate_cart_data($_POST). If it returns a string, the item is blocked and the string is shown as a WooCommerce notice.AbstractFlow calls prepare_cart_metadata()
The
woocommerce_add_cart_item_data hook fires. AbstractFlow calls your prepare_cart_metadata($_POST) and merges the returned array into the cart item data. The plugin automatically adds _utb_flow_id (your flow’s ID) and _utb_unique_key (prevents cart item grouping).AbstractFlow calls calculate_dynamic_price()
When WooCommerce recalculates totals (
woocommerce_before_calculate_totals, priority 20), AbstractFlow iterates every cart item. For items whose _utb_flow_id matches your flow, it calls calculate_dynamic_price($cart_item) and passes the result to $cart_item['data']->set_price($price).The woocommerce_before_calculate_totals hook
AbstractFlow hooks into this action at priority 20:
calculate_dynamic_price():
woocommerce_before_calculate_totals yourself — AbstractFlow does it for you.
CEP discount tiers (CEPFlow)
CEPFlow applies a percentage discount to a program’s base price depending on the customer’s relationship with UTB. The discount is looked up via CEPDiscountCalculator, which queries the external Banner API through ApiConnectionManager.
The result of that lookup is stored as cart metadata in prepare_cart_metadata():
calculate_dynamic_price() then reads those keys:
Certificate matrix pricing (CertificadosFlow)
CertificadosFlow uses CertificatePricesRepository to look up a price from a matrix of certificate × academic level × delivery format.
The repository’s key method:
$cert_id— database ID of the certificate type.$formato— delivery format:'digital'or'fisico'.$nivel— academic level of the applicant. Accepted raw values are normalised to'pregrado'or'posgrado'using an internal mapping:
| Raw value | Normalised |
|---|---|
profesional, tecnico, tecnologia, tyt, tecnica, tecnologica | pregrado |
especializacion, maestria, doctorado, postgrado, pos-grado | posgrado |
general (or empty) | Matches any level |
wp_utb_certificate_prices and returns the matched price in Colombian pesos. A CertificadosFlow implementation of calculate_dynamic_price() would read the certificate ID, format, and level from cart metadata and pass them to get_price():
Returning null to keep the default price
When calculate_dynamic_price() returns null, AbstractFlow skips calling set_price() and WooCommerce uses the price set in the product editor. Use this as your fallback when no pricing data is available: