Guide

Extra Price hooks

Extra Price gives each choice a price of its own and adds the total to the product. Its hooks fall into four groups: how the subtotal is calculated, how prices are displayed in the configurator, how they appear in the cart and order, and the formula engine used by the calculation field.

See the hook reference index for how to register PHP and JavaScript callbacks.

PHP filters

HookArgumentsPurpose
mkl_pc/extra_price/add_extra_pricetrue, $layer, $cartItemWhether a choice contributes to the cart total
mkl_pc/extra_price/qty1, $layer, $cartItemQuantity multiplier applied to a choice's extra price
mkl_pc/extra_price/relative_price$enabledWhether prices are shown relative to the current selection
mkl_pc/extra_price/price_to_display$price, $layer, $product, $itemKeyThe price shown in cart and order meta
mkl_pc/extra_price/hide_extra_price_metafalse, $layer, $itemKeyHide the price for one line item
hide_item_extra_price_in_cart$hiddenHide every per-choice price in the cart
mkl_pc/extra_price/get_tax_rates$taxData, $productThe tax data sent to the browser
mkl_pc_extra_price_order_item_meta__before_price'(', $layer, $productText before the price in order meta
mkl_pc_extra_price_order_item_meta__after_price')', $layer, $productText after the price in order meta
mkl_pc_extra_price_order_item_meta__plus_sign$html, $layer, $productThe + marker before a positive price
mkl_pc_extra_price_order_item_meta__display_null_pricefalse, $meta, $layer, $productWhether a zero price is shown
mkl_pc/math-expression-evaluator/token_definitions$tokensCustom functions available to formulas
mkl_pc/math-expression-evaluator/tokens''Legacy inline script registering formula tokens

PHP actions

HookArgumentsPurpose
mkl_pc/extra_price/before_get_tax_rates$product, $customerBefore tax rates are resolved for the browser
tmpl-mkl-pc-extra-price--before(none)Template hook, before the price markup
tmpl-mkl-pc-extra-price--after(none)Template hook, after the price markup

JavaScript filters

HookArgumentsPurpose
pc.get_extra_priceprice, choice, contextA single choice's extra price, after amount/percentage resolution
PC.extra_price_to_displayprice, choiceThe price stored for display on a choice
PC.fe.extra_price.item_priceprice, choice, layerOne choice's contribution to the subtotal
PC.fe.extra_price.subtotal.before_apply_taxessubtotalThe subtotal before tax is applied
PC.fe.extra_price.subtotalsubtotalThe finished subtotal
PC.fe.extra_price.show_regular_totalfalse, subtotal, subtotalRegularWhether to show a struck-through regular total
PC.fe.show.extra_pricetrue, choice, contextWhether to render the price on a choice or summary row
PC.ExtraPrice.view.extra_price_to_displayprice, model, viewThe amount a price view formats
PC.ExtraPrice.view.datadata, model, viewTemplate data for the price view
PC.fe.extra_price.formula_callbackscallbacks, formulaModel, optionsFunctions callable from a formula
formula_with_valuesresolved, formula, formulaModel, dataTypeA formula after placeholders are substituted

JavaScript actions

HookArgumentsPurpose
PC.fe.extra_price.before.add.extra_pricechoice, layerBefore a choice is added to the subtotal
PC.fe.extra_price.after.setSubTotalbasePrice, subtotalThe subtotal was recalculated
PC.fe.extra_price.after.update_price(none)The displayed price was refreshed

pc.get_extra_price

The single most useful JavaScript filter here. It runs at the very end of the per-choice price calculation, after the amount/percentage type has been resolved, and everything else — subtotal, display, cart preview — is built on its result.

javascript custom.js
wp.hooks.addFilter( 'pc.get_extra_price', 'my-plugin/ep', function ( price, choice, context ) {	// A surcharge on oversized options.	if ( choice.get( 'my_oversized' ) ) {		return price + 25;	}	return price;} );
pc.get_extra_price.

context identifies where the price is being asked for, so you can price a choice differently in the summary than in the toolbar. Return a number, never a formatted string.

PC.fe.extra_price.item_price and the subtotal filters

These run in a fixed order each time the total is recalculated:

  1. PC.fe.extra_price.before.add.extra_price — action, per choice, fires for inactive choices too
  2. PC.fe.extra_price.item_price — filter, per active choice
  3. PC.fe.extra_price.subtotal.before_apply_taxes — filter, once
  4. (taxes applied)
  5. PC.fe.extra_price.subtotal — filter, once
  6. PC.fe.extra_price.after.setSubTotal — action, once, with the base price and subtotal

Use item_price to change what one choice contributes, and subtotal for something that applies to the order as a whole:

javascript custom.js
// Volume discount on the configured extras.wp.hooks.addFilter( 'PC.fe.extra_price.subtotal', 'my-plugin/ep', function ( subtotal ) {	return subtotal > 500 ? subtotal * 0.95 : subtotal;} );
PC.fe.extra_price.item_price and the subtotal filters.

Applying a discount in subtotal rather than subtotal.before_apply_taxes means it is applied after tax — pick the one that matches how the store's prices are entered.

PC.fe.show.extra_price

Decides whether the price element is rendered at all. The third argument is 'choice-item' in the toolbar and 'summary-item' in the summary.

javascript custom.js
wp.hooks.addFilter(	'PC.fe.show.extra_price',	'my-plugin/ep',	function ( show, choice, context ) {		return 'summary-item' === context ? false : show;	});
PC.fe.show.extra_price.

PC.fe.extra_price.formula_callbacks

The calculation field evaluates a formula in the browser. This filter supplies the functions that formula may call, on top of anything already on PC.fe.formula_callbacks.

javascript custom.js
wp.hooks.addFilter(	'PC.fe.extra_price.formula_callbacks',	'my-plugin/ep',	function ( callbacks, formulaModel, options ) {		callbacks.shipping_band = function ( weight ) {			return weight > 20 ? 45 : 15;		};		return callbacks;	});
PC.fe.extra_price.formula_callbacks.

Reference it in a formula as {function:shipping_band(...)}. Keep these functions pure and fast — they run on every recalculation.

formula_with_values

The formula after every {layer} and {function:…} placeholder has been substituted, and just before any remaining unmatched braces are replaced with 0. This is the last point at which you can rewrite the expression.

javascript custom.js
wp.hooks.addFilter(	'formula_with_values',	'my-plugin/ep',	function ( resolved, formula, formulaModel, dataType ) {		return resolved;	});
formula_with_values.

Logging resolved here is the fastest way to debug a formula that returns an unexpected number.

mkl_pc/math-expression-evaluator/token_definitions

The PHP counterpart: it registers functions with the expression evaluator so they exist in the browser. Each entry needs a JavaScript body, a signature and a description — the description is shown to the shop manager in the formula field's help.

php functions.php
add_filter( 'mkl_pc/math-expression-evaluator/token_definitions', function ( $tokens ) {	$tokens[] = array(		'type'        => 3,		'token'       => 'vat',		'show'        => true,		'value'       => 'function( a ) { return a * 1.2; }',		'signature'   => 'vat(value)',		'description' => __( 'adds 20% VAT to value.', 'my-plugin' ),	);	return $tokens;} );
mkl_pc/math-expression-evaluator/token_definitions.

Return an array. Returning anything else makes the plugin fall back to an empty token list, which silently breaks every formula on the site.

mkl_pc/extra_price/add_extra_price and mkl_pc/extra_price/qty

Server-side equivalents of the frontend subtotal filters, applied when the cart total is recalculated. add_extra_price returning false skips a choice entirely; qty multiplies it.

php functions.php
// Charge engraving once, no matter how many units are ordered.add_filter( 'mkl_pc/extra_price/qty', function ( $qty, $layer, $cart_item ) {	return 'engraving' === $layer->get_layer( 'name' ) ? 1 : $qty;}, 10, 3 );
mkl_pc/extra_price/add_extra_price and mkl_pc/extra_price/qty.

These decide what the customer actually pays — the JavaScript filters only decide what they see. Change them in pairs, or the displayed price and the charged price will disagree.

mkl_pc/extra_price/price_to_display and the order meta filters

Control how a choice's price reads in the cart, the order and emails. The default renders as ( + £12.00 ); the three markup filters supply the (, the ) and the +.

php functions.php
add_filter( 'mkl_pc_extra_price_order_item_meta__before_price', function () {	return '— ';} );add_filter( 'mkl_pc_extra_price_order_item_meta__after_price', function () {	return '';} );
mkl_pc/extra_price/price_to_display and the order meta filters.

By default a zero price prints nothing at all; return true from mkl_pc_extra_price_order_item_meta__display_null_price to show "included" style rows.

hide_item_extra_price_in_cart and mkl_pc/extra_price/hide_extra_price_meta

Two levels of suppression. The first mirrors the plugin setting and hides every per-choice price in the cart; the second is per line item and receives the layer and item key.

php functions.php
add_filter( 'mkl_pc/extra_price/hide_extra_price_meta', function ( $hide, $layer, $item_key ) {	return 'internal' === $layer->get_layer( 'name' ) ? true : $hide;}, 10, 3 );
hide_item_extra_price_in_cart and mkl_pc/extra_price/hide_extra_price_meta.

mkl_pc/extra_price/relative_price

When relative pricing is on, each choice shows the difference from the currently selected one rather than its absolute price. This filter overrides the site setting per request.

php functions.php
add_filter( 'mkl_pc/extra_price/relative_price', function ( $relative ) {	return is_user_logged_in() ? $relative : false;} );
mkl_pc/extra_price/relative_price.

mkl_pc/extra_price/get_tax_rates and mkl_pc/extra_price/before_get_tax_rates

The configurator fetches tax rates over AJAX so it can price choices correctly in the browser. The action fires before rates are resolved — the place to switch the customer object — and the filter shapes the payload that is returned.

php functions.php
add_action( 'mkl_pc/extra_price/before_get_tax_rates', function ( $product, $customer ) {	// e.g. force a location before WC_Tax::get_rates() runs}, 10, 2 );add_filter( 'mkl_pc/extra_price/get_tax_rates', function ( $tax_data, $product ) {	return $tax_data;}, 10, 2 );
mkl_pc/extra_price/get_tax_rates and mkl_pc/extra_price/before_get_tax_rates.

tmpl-mkl-pc-extra-price--before and --after

Template hooks around the price markup. They print Underscore template syntax — see Template hooks are different.

php functions.php
add_action( 'tmpl-mkl-pc-extra-price--after', function () { ?>	<# if ( data.on_sale ) { #><span class="sale-flag">Sale</span><# } #><?php } );
tmpl-mkl-pc-extra-price–before and –after.

PC.ExtraPrice.view.data and PC.ExtraPrice.view.extra_price_to_display

The price view's own hooks: the first filters the object handed to the template (useful with the template hooks above), the second filters the number just before it is formatted as money.

mkl_pc/math-expression-evaluator/tokens

Internal. A legacy escape hatch that injects a raw inline script to register evaluator tokens. Use mkl_pc/math-expression-evaluator/token_definitions instead.

extra_price_overrides_product_price is shared with Linked Product Stock Management. PC.fe.extra_price.after.get_tax_rates is fired by the core plugin. The add-on also filters WooCommerce's woocommerce_get_price_including_tax, woocommerce_get_price_excluding_tax and woocommerce_adjust_non_base_location_prices.