WooCommerce Double Currency Conversion: Why Cart Prices Are Too High
WooCommerce double currency conversion shows up the same way every time: the product page says CAD 218, the cart says CAD 304. The price was multiplied by the exchange rate twice. FOX converts a price once, so a second conversion always means a second party in the chain: another plugin, the theme, custom code, or a setting that inflates the rate. This guide explains how the second conversion happens, how to tell it apart from a simply wrong rate, how to find the plugin responsible, and how developers fix their own code.
How a price ends up converted twice
With Is multiple allowed set to Yes (the Advanced tab of WooCommerce → Settings → Currency), customers pay in the currency they selected, so FOX converts the product price at the source: every time any code calls $product->get_price(), it receives the amount in the selected currency. That is correct as long as code only reads prices.
The trouble starts with plugins that read a price, change it and write it back. Product options and add-ons, dynamic discounts, B2B and wholesale pricing, bookings, subscriptions, multi-warehouse stock and similar plugins often do this in the cart: they call get_price(), which already returns 218 CAD for a product priced at 157 USD, add their part, and store the result with set_price(). WooCommerce keeps whatever number it gets as the price of that cart item. When the cart reads the price again, FOX converts 218 as if it were USD, and the cart shows 304. The product page never goes through this step, which is why it stays correct.
The other routes to the same result:
- Two currency converters. WooCommerce's own multi-currency feature (part of WooPayments), a theme with a built-in currency selector, or a second currency plugin converts the price as well. Only one of them may be active.
- Theme price functions. A theme that builds price strings itself, for example for variable product ranges, can apply a converted value again.
- Your own code that sets cart prices or converts amounts that FOX already converted.
With Is multiple allowed set to No, prices stay in the base currency internally and FOX converts only what is displayed. That is why a double conversion that disappears in that mode points straight at a plugin that writes prices back.
Double conversion or a wrong rate? Check the ratio
Divide the wrong price by the right one and compare the result with the currency's rate in the Currencies tab.
| What you see | What it points to |
|---|---|
| Product page right, cart or checkout too high; wrong ÷ right equals the rate | Double conversion by a plugin, the theme or custom code |
| Wrong only for some products (variable, with options, bookable) | The plugin that handles those products |
| Every page too high in one currency, product page included | The rate or the interest value of that currency, not a double conversion |
| Prices right on the site, the order email or the payment page multiplied again | A payment gateway's own currency conversion |
The opposite symptom, a price that does not change at all when the visitor switches currency, has other causes; see currency switcher not changing prices.
Rule out the settings first
- Interest. The field after the
+in the Rate+% column adds an amount to the rate. A plain number is added as it is: in a shop priced in Pakistani rupees,5turns the USD rate of 0.0036 into 5.0036, which makes every price in that currency about 1,400 times higher. For a percentage, write it with the sign, for example3%. - The rate itself. Press the refresh button next to the rate and compare it with a reference. If the aggregator returns nonsense, change it; see exchange rates not updating.
- The base currency. The row marked as base must have rate 1 and no interest, and product prices must be entered in that currency. A shop whose prices are in USD while FOX's base is EUR is off by a constant factor in every currency.
Find the plugin that converts again
Work on a staging copy of the site, not on the live shop, and use one product and one non-base currency for every test.
- Note the price on the product page and in the cart in that currency.
- Set Is multiple allowed to No, save, empty the cart and add the product again. If the cart is now right, a plugin is writing prices back. Set it to Yes again for the next steps.
- Deactivate every plugin except WooCommerce and FOX and switch to a default theme such as Storefront. Empty the cart and test. The cart should match the product page now.
- Reactivate the plugins one by one, starting with anything that touches prices: product options, discounts, wholesale, bookings, subscriptions, inventory. Empty the cart and add the product again after each one: some plugins store their price in the cart item when it is added.
- When the cart goes wrong, the plugin you just enabled is the one. Switch the theme back last to check it as well.
Page caches and browser storage can show an old cart. Clear them, or test in a private window, before you conclude anything from a step.
Fix it: adaptations, settings and code
The culprit is a third-party plugin
Many popular price plugins already have an adaptation; check the compatibility list for yours and apply the published code. If it is not there, FOX Labs takes adaptation requests for widely used plugins. Two other options: see whether the plugin has a setting for multi-currency shops or its own conversion that you can switch off, or set Is multiple allowed to No, so customers see prices in their currency and pay in the base currency; showing local prices while charging the base currency explains what changes for customers.
The culprit is your own code
The rule is simple: get_price() gives you the selected currency, set_price() must receive the base currency. Convert the result back with the woocs_back_convert_price filter before you store it:
/*
* Custom cart prices on a FOX shop with "Is multiple allowed" = Yes.
* Child theme functions.php or a code snippets plugin.
*/
add_action('woocommerce_before_calculate_totals', function ($cart) {
if (is_admin() && !wp_doing_ajax()) {
return;
}
if (did_action('woocommerce_before_calculate_totals') >= 2) {
return; // run once per request, or the change is applied again
}
foreach ($cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$price = (float) $product->get_price(); // already in the selected currency
$price = $price * 1.10; // your logic, for example +10 %
// back to the base currency, so FOX converts it only once;
// with "Is multiple allowed" = No the value passes through unchanged
$product->set_price(apply_filters('woocs_back_convert_price', $price, true));
}
}, 20);
Because it is a filter, the code keeps working if FOX is deactivated: the value passes through untouched. Fixed amounts in your logic (a 5.00 fee, a surcharge) are base currency amounts; add them after converting back, not before.
If your code calculates a price that is already final in the selected currency, for example from its own price table per currency, tell FOX not to touch it with woocs_skip_conversion. FOX calls this filter before converting a product price; returning true leaves that price as it is:
/*
* Mark cart products whose price you set in the selected currency,
* for example inside woocommerce_before_calculate_totals:
* $product->set_price($final_price);
* $product->update_meta_data('_price_is_final', 'yes'); // kept in memory, the product is not saved
*/
add_filter('woocs_skip_conversion', function ($skip, $price, $product) {
if ($product instanceof WC_Product && $product->get_meta('_price_is_final') === 'yes') {
return true;
}
return $skip;
}, 10, 3);
The filter receives the product only with Is multiple allowed set to Yes, which is the mode where this problem occurs.
If the cart is still wrong
- Test with a fresh cart every time. An old cart item can carry a price that a plugin stored when it was added.
- Check that only one currency converter is active, including WooCommerce's own multi-currency and currency selectors built into the theme.
- If the cart is right and only the checkout total or the order is wrong, look at fee, shipping and payment plugins, which add their own amounts to the total.
- Compare with the short checklist in price converted twice on the checkout page if the problem appears only at checkout.
If the isolation points to a plugin with no adaptation yet, post its name, version and the product type that goes wrong on the FOX support forum.