Troubleshooting

Multi-currency & markets gotchas

How money-based rules convert across currencies and markets, and the international-store gotchas merchants hit most.

If you sell in more than one currency or run multiple Shopify markets, money-based rules behave in ways that surprise a lot of merchants. This page explains exactly how thresholds convert across currencies, how market targeting differs from currency, and how to fix the handful of issues that come up again and again.

Every subtotal and price threshold you type — in conditions, cart restrictions, and tier discounts — is defined in your store's base currency. At evaluation time, that base-currency amount is converted into each shopper's presentment currency (the currency they're actually checking out in) before it's compared to their cart total. Almost every "my threshold fired at the wrong amount" report comes from this conversion step, not from a bug.

How money thresholds are evaluated across currencies

You set a money threshold once, in your base currency. You do not type a separate number for every currency you sell in. The app handles the per-currency conversion for you.

At checkout, the checkout validation extension reads the shopper's presentment currency rate — a live rate that Shopify provides for the currency the shopper is buying in — and multiplies your base-currency threshold by that rate before comparing it to the cart total. So the comparison always happens in the shopper's own currency, using Shopify's current rate.

Worked example

Say your base currency is USD and you build a rule "subtotal greater than $50".

  • A shopper checking out in USD triggers the rule at $50, exactly as typed.
  • A shopper checking out in EUR has that $50 converted by their presentment rate. If the live rate makes $50 worth about €46, the rule effectively triggers at roughly €46-equivalent, not a flat €50.

That last point is the crux of it: the EUR shopper's trigger is the converted value of your base amount, not the same number with a euro sign in front. The number looks "off" only because you're comparing it to the digits you typed, which were always USD.

A threshold typed as $50 will almost never trigger at a clean round number like 50 in another currency. The effective trigger floats with Shopify's live exchange rate, so it can shift slightly day to day. This is expected behavior — it keeps the value of your threshold consistent across currencies instead of locking it to one set of digits.

Storefront widget prices vs base prices

The same idea applies to the prices shown inside your storefront widgets and offers, but through a different source. Storefront widget prices are converted using Shopify's published currency rates (the same rates Shopify serves from currencies.js on its CDN), so the offer prices a shopper sees match the currency they've selected on your storefront.

This keeps displayed prices consistent with the rest of your store — but converted prices are rarely "clean."

Base price (USD)Example converted price (EUR)
9.999.43
25.0023.60
50.0047.20

After conversion you'll often see prices like 9.43 instead of a tidy 9.99. That's normal — multiplying a round number by an exchange rate produces an uneven result.

You control how those converted prices are displayed with the Price Decimal Scale setting in Settings → Global settings:

  • Enforce 2 Decimal Places always shows two digits (for example 47.2 is shown as 47.20).
  • Trim Unnecessary Zeros removes trailing zeros (for example 47.20 is shown as 47.2).

See Cart & checkout settings for the full rundown. Note that this setting changes only the display of the number — it does not change the converted amount itself or how thresholds are compared.

Markets targeting vs currency

It's easy to conflate the two, but market targeting and currency are not the same thing. A campaign's market filter is about which Shopify market the shopper is browsing in. It has nothing to do with which currency they've selected — currency follows the shopper's market/currency selector on your storefront, and selecting a market in your campaign targeting does not change pricing.

The market-list behavior has a sharp edge that trips people up:

Market list stateWho the campaign reaches
No market list set (the default)All markets
A list with one or more marketsOnly shoppers in those markets
An empty list (exists but contains no markets)No one

An empty market list is not the same as no market list. No list means "everyone." An empty list means "nobody," and the campaign list shows a warning icon next to a campaign in that state because it can't reach a single shopper. If you open the market selector, you must leave at least one market in it — or clear it back to unset.

For the full breakdown of how market targeting layers on top of schedule and customer-tag filters, see Targeting by schedule, market & customer tags.

Per-region offers recipe

Because market targeting decides who sees a campaign and base-currency thresholds auto-convert per shopper, the cleanest way to run region-specific offers is one campaign per market, each with its own market list, combined with a currency-aware threshold you type once.

Build your US campaign

Create a campaign — for example "Free gift over $75" — and set its market list to your US market. Type the $75 threshold in your base currency, as normal.

Clone it for the EU market

Duplicate the campaign and change the market list to your EU market. Leave the threshold at $75 in base currency — do not retype it in euros. The app converts $75 to each EU shopper's presentment currency automatically at checkout.

Confirm each campaign targets one market

Make sure the US campaign's market list contains only the US market and the EU clone's contains only the EU market, so shoppers see exactly one offer for their region. Watch for the empty-list warning icon on either campaign.

The result: US shoppers see and trigger the offer at $75, EU shoppers trigger it at the converted euro-equivalent of $75 — same value, one number to maintain.

Screenshot: Two near-identical campaigns side by side, one targeting the US market and one targeting the EU market, each with the same base-currency thresholdAdd a real image by setting the `src` prop.
Run one campaign per market, with the threshold typed once in base currency.

Gotchas

Testing across currencies

To confirm a money rule behaves correctly for international shoppers, reproduce a real shopper's context rather than testing only in your base currency.

Switch currency on the storefront

Use the country/currency selector on your storefront to switch into the currency you want to test. Widget prices should update to the converted values.

Test in an incognito window

Open your store in an incognito or private window so you're not carrying over a cached market, currency, or logged-in customer state from earlier testing.

Confirm the market assignment

Check that the storefront has placed you in the market you expect. Market targeting keys off the market, so if you're in the wrong one, a market-targeted campaign won't appear regardless of currency.

Build the cart to the converted trigger

Remember the trigger is the converted value of your base-currency threshold, not the same digits. Add items until the cart reaches that converted amount, then confirm the offer fires.

If a rule looks like it fires at the "wrong" amount during testing, compare it against the converted value of your base threshold for that currency, not the number you typed. They will differ by the exchange rate.

On this page