Multi-Currency on Shopify: Markets & Presentment
·
Learn how to enable and optimize multi-currency in Shopify. Explore Shopify Payments, Markets, apps, and best practices for global sales.
Multi-currency on Shopify is one of the most over-complicated topics in the ecosystem, because most advice predates Shopify Markets. You rarely need a currency app anymore, and you almost never need separate stores. What you need is Markets configured correctly and theme code that reads the buyer's presentment currency instead of the shop's base currency. Get that split wrong and you leak conversions in ways that don't show up in a single-currency test.
Markets replaced the app pile
Shopify Markets lets one store present prices, and take payment, in the shopper's local currency, with local rounding and per-market price adjustments. It supersedes the old "multi-currency app + currency switcher" pattern. Before installing anything, check what Markets already does natively — layering a third-party converter on top of Markets is the number-one cause of prices that display one value and charge another.
Base currency vs presentment currency
This is the distinction everything hinges on. Your products are priced in the shop currency (the base). What the shopper sees is the presentment currency for their market, derived from the base by exchange rate plus your rounding rule. In Liquid, shop.currency is the base; cart.currency and the presentment money fields follow the buyer. Theme code must use the buyer-facing values everywhere a price or currency appears:
<!-- WRONG: always shows the shop's base currency -->
<span>{{ product.price | money }}</span> {%- comment -%} base {%- endcomment -%}
<!-- RIGHT: renders in the buyer's market currency -->
<span>{{ product.price | money }}</span> {%- comment -%}
With Markets enabled and currency in your money format,
the same `money` filter localizes — but confirm the money format
includes {%- endcomment -%}
<span>{{ cart.currency.iso_code }}</span> <!-- reflects the active market -->
The subtle part: Shopify localizes money automatically only when your currency format setting and Markets are configured together. If you hardcoded a currency symbol into the money format long ago, localization silently fails and everyone sees a dollar sign. Audit Settings → Store details → Currency display first.
Rounding is a merchandising decision
A €-converted price of €18.73 reads as cheap-looking noise. Markets' price rounding rules let you snap converted prices to clean endings (e.g. always .00 or .99). Set them per market — Japanese yen has no decimals and must round to whole numbers, or checkout and tax math get ugly. Rounding is not cosmetic; wrong rounding for a zero-decimal currency causes real errors.
The structured-data / price-mismatch trap
If your product JSON-LD prints shop.currency and the base price while the page shows a localized presentment price, Google (crawling as a buyer in that market) sees a mismatch and drops your rich result. Any price you render for machines — schema.org, Meta catalog, Google Merchant feed — must come from the same market-aware source as the visible price. This is the most common reason a Markets store loses its price snippet, and it's invisible until you test as a non-base market.
When you actually need separate stores
- Stay on one store + Markets for currency, local pricing, local domains, and translated content — this covers the large majority of international selling.
- Consider Markets Pro when you want Shopify to act as merchant of record and handle duties/taxes/compliance.
- Separate stores only when catalogs genuinely diverge (different products, legal entities, or fulfillment) — the cost is duplicated ops and no shared inventory, so don't reach for it just for currency.
Don't forget the checkout and the emails
Test an end-to-end order in a non-base market: the price on the product page, in the cart, at checkout, in the confirmation email, and in any structured data must all agree and all be in the presentment currency. A store that displays €74 but charges $79.99 at checkout doesn't have a display bug — it has a refund-and-chargeback problem.
Ninety percent of "multi-currency is broken" tickets aren't Markets failing — they're a theme reading shop.currency somewhere it should read the buyer's presentment currency. Find the one wrong reference and the whole funnel lines up.WS24 — how we debug international pricing
Multi-currency done right on Shopify is boring in the best way: configure Markets, set per-market rounding, make every price reference — visible and machine-readable — follow the buyer, and test as a real overseas shopper. No app graveyard required.