Summary
When a product with priced PPOM options is added through WooCommerce AJAX add-to-cart, the selected option values can be accepted but the option price is not included in the cart line total. Expected behavior is for the cart total to include the base product price plus selected PPOM option prices. Actual behavior reported is that the cart keeps only the base product price, so paid options are ignored during checkout/cart calculation for that flow.
Customer context
Reported by a PPOM Pro Essential customer after a recent WordPress update. They observed the issue intermittently across products and noted the affected add-to-cart requests use wc-ajax=add_to_cart. Cache clearing, PPOM JS/CSS cache exclusions, and disabling the caching plugin did not resolve it.
Reproduction notes
Known from transcript and code inspection:
- Use a product with PPOM options where base price is
29 and a selected option adds 10.
- Submit the product through a
wc-ajax=add_to_cart request.
- Expected cart total:
39.
- Reported actual cart total:
29.
- Missing for full runtime reproduction: exact plugin versions, WooCommerce version, theme/AJAX add-to-cart implementation, and the server error body from the AJAX response.
Diagnosis
Conclusion
PPOM has a product-side gap for modern line-item pricing when a PPOM product is added through WooCommerce AJAX add-to-cart. The selected PPOM data is attached to the new cart item, but the modern line-price recalculation is wired to session restore rather than the immediate cart-total calculation path used by wc-ajax=add_to_cart fragments.
Where this likely occurs
src/Cart/WooCommerceCartLifecycleHooks.php:27-39, PPOM\Cart\WooCommerceCartLifecycleHooks::register: modern mode registers ppom_price_check_price_matrix and ppom_price_controller only on woocommerce_get_cart_item_from_session, with fees on woocommerce_cart_calculate_fees. There is no active woocommerce_before_calculate_totals registration for line-item addon pricing.
src/Cart/WooCommerceCartLifecycleHooks.php:41, PPOM\Cart\WooCommerceCartLifecycleHooks::register: ppom_calculate_totals_from_session is attached to woocommerce_cart_loaded_from_session, reinforcing that line repricing is expected after session restore.
src/WooCommerce/Cart/CartHandler.php:341-377, PPOM\WooCommerce\Cart\CartHandler::add_cart_item_data: the add-to-cart request stores posted ppom data on the cart item when ppom[fields] exists, but it does not set the cart item product price in the same request.
src/Pricing/Engine.php:38-91, PPOM\Pricing\Engine::price_controller: this is the active modern session-restore pricing path. It recomputes field prices from ppom[fields] and calls $wc_product->set_price( $ppom_total_price ), but current hook wiring only reaches it through woocommerce_get_cart_item_from_session.
src/Pricing/Engine.php:94-151, PPOM\Pricing\Engine::before_calculate_totals: this method performs similar repricing over live cart contents, but repository search found no active add_action( 'woocommerce_before_calculate_totals', ... ) registration in woocommerce-product-addon or ppom-pro.
classes/plugin.class.php:230-251, NM_PersonalizedProduct::product_supports: PPOM disables WooCommerce ajax_add_to_cart support for PPOM simple products in product-support checks, but the frontend still can reach wc-ajax=add_to_cart when a theme/plugin or WooCommerce flow submits the single product form via AJAX.
- Git history:
v33.0.18 already had the modern woocommerce_before_calculate_totals hook commented out in classes/plugin.class.php with a note that it was replaced by woocommerce_get_cart_item_from_session; commit 34742e09 moved this lifecycle wiring into src/Cart/WooCommerceCartLifecycleHooks.php without adding an immediate totals hook. This looks like an existing compatibility gap exposed by AJAX add-to-cart rather than a clear regression introduced by the latest refactor.
Engineering notes
- The report’s symptom aligns with this data flow: PPOM fields can be present on the new cart item, but line price remains the WooCommerce base price during the AJAX response because modern PPOM addon totals are not applied until a later session-restore path.
- Legacy price mode has a separate
ppom_option_price/fee-based path and should be tested separately; the inspected modern path is the strongest match for “base price remains 29 PLN after selecting +10 PLN”.
- PPOM’s frontend tries to remove the
ajax_add_to_cart class from form.cart button[name="add-to-cart"] in js/ppom.inputs.js:78-79, but that does not cover all AJAX single-product add-to-cart implementations.
- Pro add-ons can contribute price rows through
ppom_fields_prices, but the missing immediate line-price application is in the free/core WooCommerce lifecycle wiring.
Test coverage status
- Relevant unit coverage exists for the isolated modern repricer in
tests/unit/src/Pricing/test-modern-line-item-pricing.php:68-89, which confirms a select addon can set base plus option price when ModernLineItemPricing::apply_to_cart_item() is called directly.
- Existing e2e coverage in
ppom-pro/tests/e2e/specs/add-to-cart-ppom.spec.js:15-67 verifies submitted PPOM text values appear in the cart, but it does not assert paid option totals.
- Existing e2e coverage in
ppom-pro/tests/e2e/specs/add-to-cart-selectqty-quantities.spec.js:31-87 intentionally uses native form submission and then visits the cart page, so it does not cover wc-ajax=add_to_cart pricing fragments.
- No relevant coverage was found during inspection for a priced PPOM option added via WooCommerce AJAX add-to-cart with assertions against the immediate cart/fragments total.
What to verify or explore next
- Reproduce with modern PPOM pricing mode, a simple product priced at
29, and a PPOM select/radio option priced at 10, then submit through wc-ajax=add_to_cart and inspect returned fragments/cart totals.
- Repeat the same product through a native non-AJAX add-to-cart flow and after a fresh cart-page load to confirm whether session restore applies the expected
39 total.
- Check legacy pricing mode separately to confirm whether the issue is limited to modern line-item pricing.
- Run the existing targeted suites around modern pricing and add-to-cart after adding a reproduction:
tests/unit/src/Pricing/test-modern-line-item-pricing.php, tests/unit/src/Pricing/test-modern-cart-fee-applicator.php, and the PPOM Pro add-to-cart e2e specs.
Unknowns / follow-up
- The customer’s exact WooCommerce, WordPress, theme, and AJAX add-to-cart implementation were not available in the transcript.
- The browser/server error text from the
wc-ajax=add_to_cart request was not included, so a separate PHP warning/fatal path may also be present on the affected site.
Confidence
Confidence: 84/100
Code inspection shows PPOM’s modern priced-option line total is only applied on cart-session restore, while the reported failing path is wc-ajax=add_to_cart, which can calculate cart fragments/totals in the same request before that restore hook runs.
Source: HelpScout #3335408241
Generated by bug-report-triage workflow (ID: bug-report-triage_6a16eaf02afde0.96365421)
Summary
When a product with priced PPOM options is added through WooCommerce AJAX add-to-cart, the selected option values can be accepted but the option price is not included in the cart line total. Expected behavior is for the cart total to include the base product price plus selected PPOM option prices. Actual behavior reported is that the cart keeps only the base product price, so paid options are ignored during checkout/cart calculation for that flow.
Customer context
Reported by a PPOM Pro Essential customer after a recent WordPress update. They observed the issue intermittently across products and noted the affected add-to-cart requests use
wc-ajax=add_to_cart. Cache clearing, PPOM JS/CSS cache exclusions, and disabling the caching plugin did not resolve it.Reproduction notes
Known from transcript and code inspection:
29and a selected option adds10.wc-ajax=add_to_cartrequest.39.29.Diagnosis
Conclusion
PPOM has a product-side gap for modern line-item pricing when a PPOM product is added through WooCommerce AJAX add-to-cart. The selected PPOM data is attached to the new cart item, but the modern line-price recalculation is wired to session restore rather than the immediate cart-total calculation path used by
wc-ajax=add_to_cartfragments.Where this likely occurs
src/Cart/WooCommerceCartLifecycleHooks.php:27-39,PPOM\Cart\WooCommerceCartLifecycleHooks::register: modern mode registersppom_price_check_price_matrixandppom_price_controlleronly onwoocommerce_get_cart_item_from_session, with fees onwoocommerce_cart_calculate_fees. There is no activewoocommerce_before_calculate_totalsregistration for line-item addon pricing.src/Cart/WooCommerceCartLifecycleHooks.php:41,PPOM\Cart\WooCommerceCartLifecycleHooks::register:ppom_calculate_totals_from_sessionis attached towoocommerce_cart_loaded_from_session, reinforcing that line repricing is expected after session restore.src/WooCommerce/Cart/CartHandler.php:341-377,PPOM\WooCommerce\Cart\CartHandler::add_cart_item_data: the add-to-cart request stores postedppomdata on the cart item whenppom[fields]exists, but it does not set the cart item product price in the same request.src/Pricing/Engine.php:38-91,PPOM\Pricing\Engine::price_controller: this is the active modern session-restore pricing path. It recomputes field prices fromppom[fields]and calls$wc_product->set_price( $ppom_total_price ), but current hook wiring only reaches it throughwoocommerce_get_cart_item_from_session.src/Pricing/Engine.php:94-151,PPOM\Pricing\Engine::before_calculate_totals: this method performs similar repricing over live cart contents, but repository search found no activeadd_action( 'woocommerce_before_calculate_totals', ... )registration inwoocommerce-product-addonorppom-pro.classes/plugin.class.php:230-251,NM_PersonalizedProduct::product_supports: PPOM disables WooCommerceajax_add_to_cartsupport for PPOM simple products in product-support checks, but the frontend still can reachwc-ajax=add_to_cartwhen a theme/plugin or WooCommerce flow submits the single product form via AJAX.v33.0.18already had the modernwoocommerce_before_calculate_totalshook commented out inclasses/plugin.class.phpwith a note that it was replaced bywoocommerce_get_cart_item_from_session; commit34742e09moved this lifecycle wiring intosrc/Cart/WooCommerceCartLifecycleHooks.phpwithout adding an immediate totals hook. This looks like an existing compatibility gap exposed by AJAX add-to-cart rather than a clear regression introduced by the latest refactor.Engineering notes
ppom_option_price/fee-based path and should be tested separately; the inspected modern path is the strongest match for “base price remains 29 PLN after selecting +10 PLN”.ajax_add_to_cartclass fromform.cart button[name="add-to-cart"]injs/ppom.inputs.js:78-79, but that does not cover all AJAX single-product add-to-cart implementations.ppom_fields_prices, but the missing immediate line-price application is in the free/core WooCommerce lifecycle wiring.Test coverage status
tests/unit/src/Pricing/test-modern-line-item-pricing.php:68-89, which confirms a select addon can set base plus option price whenModernLineItemPricing::apply_to_cart_item()is called directly.ppom-pro/tests/e2e/specs/add-to-cart-ppom.spec.js:15-67verifies submitted PPOM text values appear in the cart, but it does not assert paid option totals.ppom-pro/tests/e2e/specs/add-to-cart-selectqty-quantities.spec.js:31-87intentionally uses native form submission and then visits the cart page, so it does not coverwc-ajax=add_to_cartpricing fragments.What to verify or explore next
29, and a PPOM select/radio option priced at10, then submit throughwc-ajax=add_to_cartand inspect returned fragments/cart totals.39total.tests/unit/src/Pricing/test-modern-line-item-pricing.php,tests/unit/src/Pricing/test-modern-cart-fee-applicator.php, and the PPOM Pro add-to-cart e2e specs.Unknowns / follow-up
wc-ajax=add_to_cartrequest was not included, so a separate PHP warning/fatal path may also be present on the affected site.Confidence
Confidence: 84/100
Code inspection shows PPOM’s modern priced-option line total is only applied on cart-session restore, while the reported failing path is
wc-ajax=add_to_cart, which can calculate cart fragments/totals in the same request before that restore hook runs.Source: HelpScout #3335408241
Generated by bug-report-triage workflow (ID: bug-report-triage_6a16eaf02afde0.96365421)