📖 Documentation

Multi Currency Switcher for
WooCommerce — by WebTend

Lightweight multi-currency switcher with Auto exchange rates, GeoIP detection, Gutenberg block, currency coupons, role-based currency access, WPML/Polylang integration, smart rounding, and vanilla JS frontend — zero bloat, zero telemetry.

● WooCommerce 7.0+ ● WordPress 6.3+ ● PHP 8.0+ ● v1.1.5 ● PHPCS / WPCS Clean ● GPL-2.0+
01 — Introduction

What is Currency Switcher for WooCommerce?

Currency Switcher lets your international customers browse and purchase in their local currency. It automatically fetches live exchange rates, detects the visitor's country via GeoIP, and can optionally convert the full WooCommerce checkout — cart, order totals, and payment — into the selected currency. Everything runs from a single clean admin panel with zero external dependencies.

🔄
Auto Exchange Rates
Pulls live rates from the European Central Bank (free, no API key), ExchangeRate-API, or Open Exchange Rates. Configurable refresh interval from 1–48 hours.
🌍
GeoIP Auto-Detection
Detects the visitor's country from their IP address and automatically selects the matching currency. The country code is kept in a 30-day cookie, so the lookup runs once — nothing is stored per IP.
🛒
Full Checkout Mode
Converts cart totals, order amounts, and payment currency — not just display prices. Visitors pay in their actual currency.
🎯
Smart Rounding
Four rounding modes: none, round, charm (.95 endings), and .99 pricing. Each mode previews a live example in the admin.
💰
Per-Product Price Override Pro
Set exact fixed prices per currency per product — bypasses auto-conversion for products with region-specific pricing.
⚡
Lightweight & Fast
No bloated libraries. Rates cached via WP transients. Vanilla JS frontend — zero jQuery. Assets only enqueued when the switcher is active.
🧱
Gutenberg Block
Native block for the WordPress Block Editor and Full Site Editor. Drag, drop, and configure style & flag display from Inspector Controls.
🔗
REST API
Two endpoints under storzen-cs/v1 for headless & decoupled WooCommerce setups — switch currency and list enabled currencies.
🏷️
Currency-Specific Coupons
Restrict any WooCommerce coupon to one or more currencies. A checkbox field on the coupon edit screen. Safe default — unchecked coupons work for all currencies.
🌐
WPML / Polylang Auto-Map
Automatically switch currency when a visitor changes language. Map each language to a currency from the Language Map tab. Works with both WPML and Polylang — zero code needed.
👥
Role-Based Currency Access v1.1.5
Choose which currencies each user role, and logged-out guests, can use. Ideal for wholesale and B2B stores. Roles with no rule keep every currency.
02 — Requirements

Requirements

RequirementMinimumRecommended
WordPress6.37.1+
WooCommerce7.011.0+
PHP8.08.2+
MySQL5.68.0+
HTTPSRequired for GeoIP API requests
✅
The free version uses the European Central Bank rate feed — no API key, no account, and no rate limits. ExchangeRate-API (no key) and Open Exchange Rates (free account) are optional alternatives.
03 — Getting Started

Installation

1
Upload the plugin
Go to WordPress Admin → Plugins → Add New → Upload Plugin. Choose the storzen-multi-currency-switcher-for-woocommerce.zip file and click Install Now.
2
Activate
Click Activate Plugin. The plugin creates its database table and registers a background cron job to fetch exchange rates on first activation.
3
Open the settings page
Navigate to WooCommerce → Currency Switcher in your admin menu.
WooCommerce → Currency Switcher
4
Enable currencies & save
On the General tab, tick the currencies you want to offer, choose a conversion mode, and click Save Settings. The switcher is live instantly — no cache flush needed.
5
Add the switcher to your theme
Use the WordPress widget, the shortcode, or the PHP function to place the currency picker anywhere on your storefront.
[storzen_currency_switcher]
05 — Admin UI

General Settings

The General tab controls the conversion mode, base currency, and which currencies are available to visitors. This is the primary configuration screen.

yourstore.com/wp-admin/admin.php?page=storzen-currency-switcher
💱
Currency Switcher
by WebTend
Active v1.1.5
⚙️General
📺Display
🔄Exchange Rates
📋Usage
⚙️
General Settings
🛒
Conversion Mode
Full Checkout Cart & payment converted
Visual Only Display only, WC charges base
🌍
Enabled Currencies
🇺🇸USD
🇪🇺EUR
🇬🇧GBP
🇯🇵JPY
🇧🇩BDT
GeoIP Auto-Detection
Set currency from visitor's country
Show Currency Flag
Display country flag in the switcher

Conversion Mode

Full Checkout — the selected currency applies to the cart, order total, and the amount charged by the payment gateway. Your payment gateway must support multiple currencies (Stripe, PayPal, etc.).

Visual Only — prices are displayed in the chosen currency, but WooCommerce charges the base store currency at checkout. Useful when your gateway only supports one currency.

⚠️
In Full Checkout mode, verify your payment gateway supports the currencies you enable. Stripe and PayPal multi-currency are both supported. Some gateways may reject orders placed in unsupported currencies.
06 — Admin UI

Display Settings

The Display tab controls how the currency switcher looks on the frontend — the label format, rounding, decimals, and a live preview of the actual switcher widget.

…?page=storzen-currency-switcher&tab=display
💱
Currency Switcher
by WebTend
Activev1.1.5
⚙️General
📺Display
🔄Exchange Rates
📋Usage
📺
Display Settings
🎨
Switcher Style
Style
Label Format
Live Preview
🇺🇸 USD
🇪🇺 EUR
🇬🇧 GBP
🎯
Smart Rounding
$25.43None
$24.99Charm
$25.00Nearest
$26.00Ceiling
07 — Admin UI

Exchange Rates

The Exchange Rates tab selects the rate source, sets the refresh schedule, and shows the last fetch time. A Manual Refresh button lets you force an immediate rate update.

…?page=storzen-currency-switcher&tab=rates
💱
Currency Switcher
by WebTend
Activev1.1.5
⚙️General
📺Display
🔄Exchange Rates
📋Usage
🔄
Exchange Rates
📡
Rate Source
🏦 ECB Free, no key needed
🔑 OXR OpenExchangeRates
✏️ Manual Set rates yourself
Refresh Interval
How often to auto-fetch rates
Last Updated
Last successful fetch
3 hours ago
Manual Refresh
08 — Features

Conversion Modes

Visual Only mode

In this mode, prices are converted and displayed in the visitor's selected currency everywhere on the frontend — product pages, shop archives, cart, and checkout. However, WooCommerce internally processes the order and charges the payment gateway in the base store currency. The converted price is for display only.

Use this mode if your payment gateway does not support multi-currency, or if you only want to give customers a price indication without actually charging in local currency.

Full Checkout mode

In Full Checkout mode, the conversion goes all the way through: cart totals, tax calculations, shipping, and the final charge sent to the payment gateway are all in the selected currency. Orders are stored in WooCommerce with the currency code the customer used.

ℹ️
Payment gateway compatibility: Stripe, PayPal, and most modern gateways support multi-currency natively. Always test a transaction in a staging environment before going live.
09 — Features

GeoIP Auto-Detection

When GeoIP is enabled, the plugin sends a lightweight request to api.country.is (free, no API key, no account required) to detect the visitor's country on their first page load. The visitor's IP address is sent in that request. The country code is matched against a built-in country→currency map and the result is stored in a first-party cookie (storzen_cs_country) for 30 days — no per-IP data is ever written to the database.

If GeoIP detects a country that maps to a currency not in your enabled list, the plugin falls back to the base store currency. Role Access rules still apply: a detected currency that is not allowed for the visitor is ignored.

💡
The GeoIP API is called only once per visitor session. Subsequent page views use the cached result. The cookie expires after 30 days. No repeat API calls are made on subsequent page loads.
10 — Features

Smart Rounding

After converting a price, raw floating-point results (e.g. 24.571...) are rarely attractive to shoppers. The rounding system applies one of four modes to every converted price. The examples below use 2 decimal places:

ModeExample InputOutputBest for
None$24.571$24.57Exact pricing, B2B
Round$24.571$24.57Rounds to the decimal places set in Decimals (use 0 for whole numbers)
Charm (.95)$24.571$24.95Retail — rounds up to the next whole number, then subtracts .05
.99 Pricing$24.571$24.99Retail — rounds up to the next whole number, then subtracts .01
ℹ️
Charm and .99 pricing always end below the next whole number. A converted price that is already whole (for example $25.00) becomes $24.95 or $24.99.
11 — Features

Per-Product Price Override

Sometimes the auto-converted rate is not the right price for a specific market. The per-product override lets you set an exact fixed price for each currency directly on the WooCommerce product edit screen.

Go to Product → Product Data → Storzen Currency Prices. Enter a fixed price for each enabled currency. Leave a field empty to fall back to the auto-converted rate. Per-product fixed prices are a Pro feature. In the free version the tab shows a locked preview.

ℹ️
Fixed prices are stored as product meta and bypass the rate conversion entirely. They are not affected by rate refreshes or rounding settings.
12 — Features

Widget & Shortcode

Shortcode

Place the currency switcher anywhere using the shortcode:

[storzen_currency_switcher] [storzen_currency_switcher style="buttons"] [storzen_currency_switcher style="dropdown" show_flag="false"]
AttributeValuesDefault
styledropdown, buttons, selectdropdown
show_flagtrue, falseplugin setting
classAny CSS class string—

PHP function

// In your theme template: <?php if ( function_exists( 'storzen_cs_render' ) ) { storzen_cs_render( array( 'style' => 'buttons' ) ); } ?>

WordPress Widget

The plugin registers a Currency Switcher widget in Appearance → Widgets. Drag it into any widget area. Configure the style and flag display from the widget settings panel.

12b — Usage

Gutenberg Block v1.1.3

The plugin registers a native WordPress block — storzen-cs/switcher — that works in the Block Editor and Full Site Editor (FSE). No shortcode or PHP needed.

1
Open any page, post, or template
Works in the post editor, the Site Editor (FSE), and in page builder patterns that support blocks.
2
Search "Currency Switcher" in the block inserter
Click the + block inserter and type Currency Switcher. The block appears under the Storzen category.
3
Configure from Inspector Controls
In the right-hand sidebar, choose the switcher style (Dropdown / Buttons / Select) and toggle flag display. Changes preview instantly in the editor.
4
Publish
The block renders a live, functional currency switcher using the same markup as the shortcode and widget.
ℹ️ Block-level style and flag settings override the global Display Settings for that placement only — other switcher placements are unaffected.
13 — Reference

All Settings

All settings are stored in a single WordPress option: storzen_cs_settings (serialised array).

KeyTypeDefaultDescription
modestringfullConversion mode: full or visual
currenciesarray[]Enabled currency codes (ISO 4217)
base_currencystringWC settingStore base currency — mirrors WooCommerce
rate_sourcestringecbRate provider: ecb, erapi, open_exchange_rates, manual
api_keystring""OpenExchangeRates App ID (only if source = oxr)
refresh_intervalint12Hours between automatic rate refreshes
geoip_enabledbooltrueEnable GeoIP auto-detection on first visit
roundingstringnoneRounding mode: none, charm, round, ninety_nine
decimalsint2Decimal places for converted prices
show_flagbooltrueShow country flag emoji in the switcher
switcher_displaystringsymbol_codeLabel format: symbol, code, symbol_code, name
switcher_stylestringdropdownSwitcher UI style: dropdown, buttons, select
manual_ratesarray{}Manual rate overrides: {"EUR": 0.92, "GBP": 0.79}
auto_placement_enabledboolfalseEnable one-click theme header placement (Storefront, Astra, OceanWP, etc.)
storzen_cs_lang_maparray{}Language → currency pairs (separate option key): {"fr": "EUR", "bn": "BDT"} — set from Language Map tab
storzen_cs_role_accessarray{}Allowed currencies per role (separate option key, v1.1.5): {"__guest": ["USD","EUR"], "wholesale_customer": ["USD"]} — set from Role Access tab. __guest is the logged-out visitor. A role with no entry is unrestricted.
14 — Reference

Hooks & Filters

Filters

HookArgumentsDescription
storzen_cs_rate $rate, $base, $currency, $product Override the exchange rate for a specific currency pair. Return a float.
storzen_cs_convert_price $converted, $base, $currency, $product Modify the final converted price after rate & rounding are applied. Return a float.
storzen_cs_enabled_currencies $currencies Programmatically add or remove currencies from the enabled list. Return a string[].
storzen_cs_geoip_country $country Override the detected country code before it is mapped to a currency. Return an ISO 3166-1 alpha-2 string.
storzen_cs_switcher_html $html, $atts Filter the fully-rendered switcher HTML string before output. Used in shortcode and block render.

Filters (v1.1.4)

HookArgumentsDescription
storzen_cs_coupon_currency_error $message, $currency, $allowed Customise the error notice shown when a coupon is rejected due to currency mismatch.

Filters (v1.1.5)

HookArgumentsDescription
storzen_cs_role_access_user_allowed $allowed, $user_id, $roles Filter the currencies a user may use. $allowed is a string[] or null (unrestricted). $user_id is 0 for guests; $roles holds the role slugs, or ["__guest"].
storzen_cs_role_access_exempt $exempt Return true to skip role rules for the current request. Default false. Admin screens, cron, WP-CLI and the plugin's own admin AJAX are always exempt.

Actions

HookDescription
storzen_cs_rates_refreshedFires after exchange rates are successfully fetched and cached.
storzen_cs_currency_switchedFires when a visitor switches their active currency.
storzen_cs_lang_currency_switchedFires after the currency is switched due to a WPML / Polylang language change. Args: $currency, $lang.
storzen_cs_role_access_savedFires after the Role Access rules are saved (v1.1.5). Arg: $rules. Hook here to purge page caches that show the switcher.
storzen_cs_role_access_advanced_panelAdmin only (v1.1.5). Renders at the bottom of the Role Access tab when Pro is active. Pro uses it to show advanced role rules.
14b — Reference

REST API v1.1.3

The plugin registers two REST API endpoints under the storzen-cs/v1 namespace. Both require a valid WP nonce (X-WP-Nonce header or _wpnonce query param).

Switch currency

POST /wp-json/storzen-cs/v1/switch

ParameterTypeDescription
currencystringISO 4217 code to switch to (e.g. EUR)

On success returns 200 with { "currency": "EUR", "rate": 0.93, "symbol": "€", … }. Returns 400 if the currency is not in the enabled list.

List enabled currencies

GET /wp-json/storzen-cs/v1/currencies

Returns an array of enabled currency objects: { "code": "EUR", "symbol": "€", "name": "Euro", "flag": "🇪🇺" }. Public endpoint — no authentication required.

💡 The REST API is useful for headless / decoupled WooCommerce setups. For standard themes, the existing AJAX handler (wp_ajax_storzen_cs_switch) continues to work and requires no changes.
16b — Features

Currency-Specific Coupons v1.1.4

Restrict any WooCommerce coupon so it is only valid when the customer's active currency matches. Create loyalty codes for specific markets — BANGLA20 for BDT shoppers, SUMMER10 for USD, EURO15 for EUR — without any code.

How to set a currency restriction

1
Open a coupon in WooCommerce → Coupons
Go to WooCommerce → Coupons, create or open any existing coupon.
2
Find "Currency restriction" under the General tab
A checkbox group listing all enabled currencies appears in the General options panel. Check one or more currencies to restrict the coupon.
3
Save the coupon
The restriction is active immediately. Customers applying the coupon in a non-allowed currency see a clear error notice. Leave all checkboxes unchecked to allow any currency (safe default — no breaking change for existing coupons).
💡 Coupons with no currency restriction set behave exactly as before — this feature is strictly additive and requires no migration.

Developer hook

HookArgumentsDescription
storzen_cs_coupon_currency_error $message, $currency, $allowed Filter the error notice shown when a coupon is rejected due to currency mismatch. Return a custom string.
16c — Features

WPML / Polylang Language Map v1.1.4

Automatically switch the active currency whenever a visitor changes language. Requires WPML or Polylang to be installed and active. Configure language → currency pairs from the new Language Map admin tab.

Setup

1
Install WPML or Polylang
The Language Map tab detects which multilingual plugin is active and loads its language list automatically. If neither is installed, the tab shows an informational notice.
2
Go to Currency Switcher → Language Map
Each active language appears as a row. Select the currency to assign from the dropdown in that row.
3
Save and test
Switch languages using your theme's language switcher — the currency changes automatically without a manual switch. Mappings saved before the multilingual plugin is installed are activated automatically once the plugin is detected.
ℹ️ Languages with no mapping set leave the currency unchanged. A visitor who manually switched their currency before changing language will have their manual selection overridden by the language map.

How it works

The plugin hooks into:

EventPluginWhat happens
wpml_language_has_switchedWPMLCurrency switches immediately when the user changes language.
init (priority 20)WPML & PolylangCurrency syncs on every page load from the active language cookie/URL.
pll_language_definedPolylangCurrency syncs once Polylang resolves the current language.
pll_set_languagePolylangCurrency switches when visitor uses the Polylang language switcher.

Developer action

HookArgumentsDescription
storzen_cs_lang_currency_switched $currency, $lang Fires after the currency is switched due to a language change. Use this to sync other systems.
16d — Features

Role-Based Currency Access v1.1.5

Control which currencies each customer group can use. For example, show wholesale buyers only USD, let logged-out guests choose between USD and EUR, and keep every currency for retail customers. Rules are set per WordPress user role, plus one row for logged-out visitors.

Setup

1
Enable your currencies
Role Access works with the currencies you enabled on the General tab. Enable at least two, otherwise the tab shows a notice.
2
Go to Currency Switcher → Role Access
Each row is a user role. The first row, Guest (logged out), applies to visitors who are not logged in. Each column is an enabled currency.
3
Tick the currencies each role can use
Use the All and None buttons to fill a row quickly. A row with every box ticked, or none ticked, has no restriction.
4
Save and test
Click Save Settings, then log in as a user with that role (or open the store logged out for the Guest row) and check the switcher. If you use a page cache, purge it after changing the Guest row.

Example

RoleUSDEURGBPResult
Guest (logged out)✓✓Sees USD and EUR
Customer✓✓✓No restriction
Wholesale Customer✓USD only — the switcher is not shown

How the rules work

SituationWhat happens
Role has no ruleThe role can use every enabled currency (safe default for existing stores).
User has several rolesThe user can use the currencies of all their roles. If any one role has no rule, the user is unrestricted.
Current currency is not allowedThe store base currency is used. If the base currency is not allowed either, the first allowed currency is used.
Only one currency allowedThe switcher is not shown and the frontend script is not loaded for that visitor.
Allowed currency was disabled laterIf a rule would leave a visitor with no usable currency, the rule is ignored so checkout never breaks.
GeoIP, language map, cookieAll follow the same rules. A currency chosen by GeoIP or the language map that is not allowed is ignored.
Direct switch requestA request for a hidden currency is rejected with 403 and the message “This currency is not available for your account.”
Admin screens, cron, WP-CLINot restricted. Exchange rates are always fetched for every enabled currency.
ℹ️ Role rules apply on the storefront to every logged-in user, including administrators, if their role has a rule. To preview a rule, log in as a test user with that role. Inside wp-admin, all enabled currencies stay available.
💡 The tab also shows an Advanced Role Rules panel (default currency per role, hide the switcher for a role, per-user override). These options are reserved for Pro.

Developer hooks

HookTypeDescription
storzen_cs_role_access_user_allowedFilterChange the allowed currencies for a user. Args: $allowed, $user_id, $roles.
storzen_cs_role_access_exemptFilterReturn true to skip role rules for the current request.
storzen_cs_role_access_savedActionFires after the rules are saved. Arg: $rules.
// Example: let customers with a "vip" role use every currency. add_filter( 'storzen_cs_role_access_user_allowed', function ( $allowed, $user_id, $roles ) { if ( in_array( 'vip', $roles, true ) ) { return null; // null = unrestricted. } return $allowed; }, 10, 3 );
16 — FAQ

Frequently Asked Questions

Does this work with my payment gateway?
In Full Checkout mode the plugin passes the selected currency to WooCommerce, which then passes it to the gateway. Any gateway that reads get_woocommerce_currency() — including Stripe, PayPal, Square, and Mollie — will work. Test with a small transaction first. In Visual Only mode, the gateway always receives the base store currency so compatibility is guaranteed.
Are exchange rates real-time?
Rates are fetched from your chosen source (ECB, ExchangeRate-API or Open Exchange Rates) on a schedule you set — between 1 and 48 hours. The ECB publishes its reference rates once daily (around 16:00 CET on business days). For most retail stores, a 12–24 hour refresh interval is sufficient. You can always trigger an immediate update using the Manual Refresh button on the Exchange Rates tab.
Is this GDPR compliant?
The plugin is built with privacy in mind, but compliance depends on how your whole site is set up. When GeoIP is enabled, the lookup sends the visitor's IP to api.country.is to determine their country. The detected country code is stored in a first-party cookie for 30 days — the raw IP address is never written to the database. The active currency is also stored in a first-party cookie (storzen_cs_currency) containing only the ISO currency code — no personal data. Exchange-rate requests contain no visitor data.
Can I set different prices per country rather than using the exchange rate?
Yes — use the Per-Product Price Override feature on each product's edit screen. Set a fixed price in each currency and the plugin uses that instead of the auto-converted rate. Fixed prices can be set for all enabled currencies (Pro).
Will it slow down my site?
No. Exchange rates are cached in WordPress transients. GeoIP results are stored in a 30-day cookie — no repeat API calls. The frontend script is lightweight and only loaded when the switcher is active. On shop and product pages, switching currency updates prices via AJAX without a full page reload. Cart and checkout pages reload for accurate WooCommerce totals, which is required for correct tax and shipping calculations.
Where does the currency selection get stored?
The selected currency is stored in a first-party cookie named storzen_cs_currency for 30 days. The selection persists across browser sessions. If GeoIP is enabled, the first-visit detection populates the cookie automatically.
Can I restrict a coupon to a specific currency?
Yes. Open any coupon in WooCommerce → Coupons, scroll to the General tab, and check the currencies the coupon should be valid for under "Currency restriction". Customers applying the coupon in a non-allowed currency see a clear error notice. Coupons with no currencies checked apply to all currencies — zero breaking change for existing coupons.
Does it support WPML and Polylang?
Yes — since v1.1.4. Go to Currency Switcher → Language Map and assign a currency to each language. When a visitor switches language, the currency switches automatically. Works with both WPML and Polylang with no code required. Mappings saved before the multilingual plugin is installed activate automatically once detected.
Can I show different currencies to wholesale customers and guests?
Yes — since v1.1.5. Go to Currency Switcher → Role Access. Each row is a user role, plus a Guest row for logged-out visitors. Tick the currencies each role can use. A role with every box ticked has no restriction. If a user has more than one role, they can use the currencies of all their roles. See Role-Based Currency Access for details.