• Resolved Kim Clow

    (@kimclow)


    Hi there!
    We recently had an issue on our site, wholyme.com. Wholyme has manually set prices for GPB (£), USD ($) and Euro (€). We experienced an odd issue recently where if a user had added a product to cart in $ or €; it changed the £ price in the backend. £ is the default currency on the site.

    The issue is patched on our site, but will share more info with you:

    Product links:

    The Relief Balm costs £27.

    • It was changed to £31.
    • The number 31 , is what the price of the product in Euros is.

    The Relief Salts costs £16

    • It was changed to £29.
    • The number, 29 is what the price of the product in USD is.

    ——

    Our findings:

    When do_action(‘woocommerce_after_calculate_totals’, [object]) runs, the price plugin executes the code shown on this link: https://d.pr/i/UQa4t2

    This code updates the product price not only within the cart, but globally. Because it does not call save(), the change is not persisted on its own. However, if anything else in the cart process subsequently calls save(), the global product is updated using whichever regional price was applied at that point.

    In this instance, the trigger was custom code, making it straightforward to fix. However, the same issue could be caused by any plugin or custom logic that mutates the product object and then calls save() during the cart lifecycle.

    The likely reason for this approach is that some discount plugins retrieve pricing via
    $product->get_price() during cart calculations. To support this, the alternative price is written directly to the product object, which can lead to unintended side effects.

    A safer approach would be to dynamically add a filter during the cart process to modify the value returned by get_price() without mutating or saving the product itself. This filter could then be removed once the cart calculations are complete.

    We have a PDF version of this saved here: https://d.pr/f/UGTDem

    • This topic was modified 2 months, 3 weeks ago by Kim Clow.

    The page I need help with: [log in to see the link]

Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Author Oscar Gare

    (@oscargare)

    Hi @kimclow,
    Thanks for the detailed description of the problem. No plugin should save a product instance in a cart during a frontend request. This is a bad practice.
    Most discount/wholesale plugins also use the same technique (call to set_price) to apply dynamic discounts to the products in the cart.

    Your workaround is good, but I’ve found that most discount plugins use the get_price function with the context = “edit” as a parameter to calculate the dynamic discount, which skips all price filters. Updating the product price in the woocommerce_get_cart_item_from_session hook early (-10) ensures that discount plugins receive the correct product price, even when they use context = “edit”.
    These issues forced me to make this decision, which is not my preferred option, but removing that part of the code would create conflicts with the popular discount/wholesale and bundle plugins.

    In any case, we will take your study into account and explore a less aggressive alternative.

    Plugin Author Oscar Gare

    (@oscargare)

    Hi @kimclow

    The new plugin version (4.2.0) introduced a fix for this issue and maintains compatibility with discount plugins. Thanks for the feedback 🙂

    Thread Starter Kim Clow

    (@kimclow)

    Thanks @oscargare – will check it out!

Viewing 3 replies - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.