Since version 2.0, this module is called Multi-Currency Checkout. It treats currency as checkout state, not as a label attached to an individual variation. A cart, order, transaction, and subscription always use one settlement currency, and customers can switch that currency before payment.
The old Multi-Currency Variations behavior, where a variation carried a display currency without a converted amount, is gone. In its place you get real multi-currency: enabled currencies, exchange rates, exact per-variation price books, and currency-aware payment gateway routing.
What Changed in 2.0
The 1.x module swapped the currency symbol on a variation’s price. It never converted amounts, and payment still settled in the store currency. Version 2.0 replaced that with a full checkout system:
- One authoritative currency per cart, order, transaction, and subscription
- A per-variation currency price book stored in its own table (
wp_gtfc_currency_prices) - Manual or automatic exchange rates with markup and rounding rules
- A currency-to-gateway routing matrix validated on the server
- A storefront currency selector and automatic local currency detection
Legacy other_info['currency'] values from 1.x are deliberately not imported. The old field identified a currency but never stored an unambiguous converted amount, so importing it as a price would be unsafe. Configure enabled currencies and add fixed prices where needed instead.
Enabling the Module
- Go to Fluent Cart > GT Extensions.
- Toggle on Multi-Currency Checkout.
- Work through the numbered settings sections: currencies, exchange rates, gateway routing, and the storefront selector.
- Click Save Settings.
- Run a sandbox payment for every currency and gateway combination before going live.
Settings
- Enabled Currencies: The currencies customers may select. Your store base currency is always included. Defaults add INR, USD, EUR, and GBP.
- Default Storefront Currency: The fallback currency when nothing else applies.
- Automatic Local Currency: Resolve the visitor’s currency from their location at checkout. Default: on.
- Rate Provider:
Manualrates you type in, orFrankfurterdaily reference rates fetched fromapi.frankfurter.dev. - Rate Markup: A percentage added on top of the rate, useful for covering conversion fees.
- Rounding: None, nearest .99, nearest .50, or nearest whole number.
- Missing-Price Behavior:
Convertusing the configured rate, orblockthe product from being purchased in that currency. - Selector Placement: Show the selector above checkout payment methods, enable the
[gtfc_currency_selector]shortcode, or both. - Remember Selection: How many days the currency cookie persists (1 to 365, default 30).
With the Frankfurter provider, rates refresh once a day via the gtfc_refresh_exchange_rates cron job. The settings page also has a Refresh rates now button for an immediate update.
How Prices Are Resolved

For every variation and selected currency, the module resolves the price in this order:
- The native Fluent Cart amount, when the selected currency is the store base currency.
- An exact price saved for that variation and currency in the price book.
- A converted amount using the current rate, markup, and rounding rule.
- An unavailable-product error, when missing-price behavior is set to block.
Amounts are stored as integer minor units (cents, paise). The module is designed for two-decimal currencies; test zero-decimal currencies separately before enabling them.
The Currency Price Book
Automatic conversion is a fallback. For deliberate regional pricing, save exact amounts per variation and currency. Open a product in the Fluent Cart editor and the Currency price book widget appears with the pricing section. For each enabled non-base currency you can save:
- Item price: The exact selling price in that currency
- Compare-at price: The strikethrough price, if you use one
- Signup fee: For subscription variations with a signup fee
Exact price-book entries always beat converted prices. Choosing Use automatic price removes the entry and returns that currency to rate-based conversion. Entries live in the wp_gtfc_currency_prices table, keyed by variation and currency.
Gateway Routing
Every enabled currency maps to one or more payment gateways in a routing matrix, plus one preferred gateway that is shown first. On checkout, the module:
- Resolves the authoritative currency from cart data, a validated request, the currency cookie, or the default.
- Filters Fluent Cart’s active gateways down to the ones assigned to that currency.
- Moves the preferred eligible gateway to the first position.
- Validates the submitted gateway again before the order is processed, so a stale or manipulated checkout submission is rejected.
- Writes the currency and conversion snapshot to the order, transactions, and subscription configuration.
Razorpay defaults to an INR-only route. That conservative default prevents an accidental USD route, but your saved matrix is authoritative, so you can override it if your gateway account supports other settlement currencies. Capability hints in the settings are warnings, not enforcement.
Storefront Selector and Local Currency

The selector renders above Fluent Cart’s payment methods on checkout, and anywhere else via [gtfc_currency_selector]. Switching currency reprices the server-side cart, revalidates coupons, and clears prior shipping, tax, and fee calculations before the page reloads. Both block-based and shortcode checkouts are supported.
When automatic local currency is enabled, checkout resolves the first usable country in this order: billing country, then shipping country, then Cloudflare’s visitor-country header. Fluent Cart’s locale data maps that country to its currency. The automatic currency is used only when every cart item can be priced in it; otherwise checkout falls back to the default storefront currency. A currency the customer picked manually always wins.
REST API
The module registers these endpoints under gt-extensions-fluentcart/v1:
GET /currency, Public. Returns the current currency context for the storefront selector. Sent withno-storecache headers so cached pages never become the source of truth. Accepts an optionalcart_hash.POST /currency, Public. Switches the cart currency. Takescurrencyand an optionalcart_hash, reprices the cart, and returns{"success": true, "currency": "...", "reload": true}.GET/POST/DELETE /variation/{id}/prices, Requiresmanage_options. Reads, saves, or removes price-book entries. POST takescurrency,item_price,compare_price, andsignup_feeas decimal amounts.POST /rates/refresh, Requiresmanage_options. Forces an exchange-rate refresh.
Extension Filters
gtfc/multi_currency/gateway_capabilities, Changes the capability hints shown to merchants in the routing matrixgtfc/multi_currency/location_country, Changes the detected two-letter country codegtfc/multi_currency/location_currency, Changes the country-to-currency result
Quick answers to common questions:
What happened to the per-variation currency dropdown from 1.x?
It was removed in 2.0. The old field only swapped the currency symbol without converting the amount, which could misstate prices. The replacement is the currency price book: exact per-variation amounts per currency, with rate-based conversion as the fallback. Old values are intentionally not migrated.
Do I have to enter a price for every currency?
No. Prices convert automatically from your configured rates, markup, and rounding. Enter exact price-book amounts only where you want deliberate regional pricing; those entries always take priority over converted values. Set missing-price behavior to block if a product should never sell in an unpriced currency.