CurrencyCraft

Setup guide

Six steps, two of which only you can do

Start by confirming your mode. Mode B needs two merchant-controlled steps: wrap the existing money formats, then enable the app embed and place the switcher. Mode A uses your theme's native country selector instead. This page explains the setup and how to preview it safely before publishing theme changes.

Which steps apply to you

If your store runs Shopify Payments with a Market that has local currencies switched on (Mode A), Shopify Markets already prices and charges in the shopper’s currency. CurrencyCraft does not convert anything, so skip converter steps 2 through 5. If your store has no Shopify Payments account (Mode B), CurrencyCraft converts displayed prices and step 2 is mandatory. Step 1 tells you which one you are.

Step 1. Install, and confirm your mode

Install the app from the Shopify App Store. On first load CurrencyCraft reads two things from your store: whether an activated Shopify Payments account exists, and whether any Market has local currencies enabled. It classifies from that.

Overriding the detection

Open the setup guide inside the app. The mode step has two buttons, “Shoppers pay in their own currency” for Mode A and “Checkout is always in your base currency” for Mode B. If detection already picked one, the button reads “Use Mode B instead” (or A). A manual choice always beats detection and is marked as set manually. “Clear and re-detect” drops the override and re-reads the store.

Step 2. Wrap your money formats (Mode B only)

Currency formats are store-wide

These Shopify settings apply across the store. A draft theme does not isolate currency-format changes from your published theme. Test this step on a dedicated development store, or agree a controlled test window before changing an existing store.

Record the exact existing values of both HTML fields before editing. Keep that copy until testing is complete. If the preview is wrong or you stop using Mode B, restore those exact original values and save, then check the published storefront again. Do not guess or replace the store's original formatting with an example from this guide.

This is the most missed step, by a distance. In Mode B the storefront script only rewrites prices that carry the cc-money wrapper. If no price on the page has it, there is nothing for the app to convert, and the storefront looks completely unchanged no matter how many currencies and rules you set up.

Shopify has no Admin API mutation that writes currency formats, so the app cannot do this for you. Skip it if you are in Mode A: Markets handles those prices and the wrapper does nothing there.

Where the fields are

In Shopify admin go to Settings, then General, then Store currency, then Change formatting. You will see four fields. Edit both HTML ones:

Do both. Themes render prices through both fields, so wrapping only one leaves half your prices frozen. The two email fields do not matter.

What to paste

Paste this in front of whatever the field already contains:

<span class="cc-money" data-cc-base="{{amount}}">

and this after it:

</span>

You are wrapping the existing value, not replacing it. Replacing it drops your currency symbol and your separator style from every price on the store.

A worked example

A field that currently reads:

${{amount}} USD

becomes:

<span class="cc-money" data-cc-base="{{amount}}">${{amount}} USD</span>

The same applies to any format. A store using a euro symbol and comma separators keeps both:

&euro;{{amount_with_comma_separator}}

becomes:

<span class="cc-money" data-cc-base="{{amount}}">&euro;{{amount_with_comma_separator}}</span>

Notice that data-cc-base always uses the plain {{amount}} token even when the visible part of your format uses a different one. That attribute is what the script parses, and the plain token gives it the canonical form (period decimals, comma thousands) regardless of how you display numbers. The visible half keeps your symbol, your token and your separators untouched.

The in-app version of this step reads your live formats and reports each field as done or not done, so you are not guessing. It also hands you the exact new value for each field with a copy button.

Step 3. Turn on the app embed, then place the switcher (Mode B only)

Duplicate your theme and open the draft copy in the theme editor for this step. Preview that copy while configuring the embed and block. In-app editor links target the current theme, so open the chosen draft manually if needed and confirm its name before saving. Saving the draft does not publish it. Publish only after you have checked prices, variants, cart and the checkout-currency notice and decide the result is ready. The store-wide money-format warning in step 2 still applies.

These are two different things needed for Mode B. Installing the app does neither. In Mode A use the theme's native country selector; CurrencyCraft's picker remains hidden. While the mode is unknown, settle detection before setting up conversion.

The app embed loads the runtime

In the theme editor open App embeds, switch CurrencyCraft on, and save. This loads the price script and its stylesheet on every storefront page. Until it is on, nothing the app does reaches your store.

On its own the embed puts no switcher anywhere. It is the engine, not the control.

The switcher block is what shoppers click

Still in the theme editor, add the CurrencyCraft Switcher app block to a section, usually the header. That is the visible dropdown. It only renders once at least two currencies are enabled in the app, because a switcher with one option is not a switcher.

CurrencyCraft does not request the read_themes scope, so it cannot read your theme to check either of these. Both can be confirmed manually. If optional analytics are deliberately enabled and the shopper consents, a recent storefront event can also confirm activation. No event is expected when analytics are off or consent is denied; enabling analytics is not required for conversion.

Step 4. Display currencies, markup and rounding (Mode B only)

Open Currencies and enable the ones you sell in. You need at least one besides your base currency for the switcher to appear. The Free plan allows up to 5 currencies; paid plans remove the cap.

Where rates come from

Fiat rates come from OpenExchangeRates or Frankfurter. Crypto comes from Coinbase. Precious metals (XAU, XAG, XPT, XPD) come from gold-api.com, with a CC0 CDN as the last fallback. The providers are chained: if one fails the next is tried, a circuit breaker stops hammering a provider that is down, responses are cached, and a recent but stale rate is served rather than showing a broken price. Crypto and metals are available on Pro.

Markup and manual rates

Per currency you can add a markup percentage, or pin a manual rate. The precedence is: a rateOverride rule beats a manual rate, a manual rate beats a markup percentage, and a markup percentage beats the live provider rate.

Rounding

Rounding is per currency, with six strategies: nearest, up, down, charm99 (23.41 becomes 23.99), charm95 (23.41 becomes 23.95) and charm00 (23.41 becomes 24.00). Zero decimal currencies such as JPY and three decimal currencies such as KWD are handled correctly. On a zero decimal currency there is no .99 or .95 to land on, so charm99 and charm95 fall back to the nearest whole number. charm00 always rounds up to the next whole number, in any currency.

Rounding is applied inside the conversion path. Mode A never enters that path, so in Mode A your rounding settings are stored but never used.

Step 5. Mode B conversion rules (optional, Pro)

Pro rules affect Mode B display conversion only and let you target a subset of shoppers instead of the whole store. They do not change Shopify Markets prices or checkout currency. They are available on Pro. Every rule has a level and a type.

Rule typeWhat it does
forceCurrencySets the display currency, overriding the shopper’s own earlier choice.
enableCurrencyMakes a currency selectable. It does not set the display currency.
rateOverridePins the rate used for a currency in that context.
roundingApplies a rounding strategy in that context.
switcherVisibilityShows or hides the switcher.

How conflicts resolve

Levels are global, currency, country and market. When two rules touch the same field the more specific level wins: market beats country, country beats currency, currency beats global. If two rules are at the same level, the higher priority number wins. If those tie too, the lowest rule id wins, so the outcome is always deterministic.

A worked example

You sell in USD and want Japanese visitors to land on JPY with whole number prices, while everyone else keeps the default.

Add a global switcherVisibility rule later and the country rules still win in Japan, because country outranks global.

Before you rely on a rule, use the simulator in the admin. You pick a sample visitor, Japan, the United States or your APAC market, and it resolves the same way the storefront does: which currency that shopper sees, the sample price and the rate behind it, the rounding, whether the switcher shows, and which rule won each of those.

Step 6. Check it actually worked

For Mode B, open your storefront in a fresh tab and do these in order. For Mode A, use the theme's built-in country selector and verify Shopify's native product, cart and checkout currency instead.

What usually went wrong

Still stuck?

The same guide lives inside the app, where it reads your live money formats and tells you which field is still blocking your storefront.