How7o
  • Home
  • Tools
  • Prank Screens
  • Contact
  • Blog
Reading: How to Dynamically Change Currency in WooCommerce
Share
Subscribe Now
How7oHow7o
Font ResizerAa
  • Marketing
  • OS
  • Features
  • Guide
  • Complaint
  • Advertise
Search
  • Home
  • Tools
  • Prank Screens
  • Contact
  • Blog
Follow US
Copyright © 2014-2023 Ruby Theme Ltd. All Rights Reserved.
How7o > Blog > Web Development > How to Dynamically Change Currency in WooCommerce
Web Development

How to Dynamically Change Currency in WooCommerce

how7o
By how7o
Last updated: May 10, 2026
7 Min Read
WooCommerce dynamic currency switcher — cookie-stored currency applied via woocommerce_currency filter
SHARE

A woocommerce currency switcher is three pieces: a form or query parameter that lets the visitor pick a currency, a cookie that remembers the choice across requests, and a filter on woocommerce_currency that changes which currency WooCommerce reports everywhere. The filter handles the display side (symbol, code, formatting); it doesn’t convert prices — for that you need a multi-currency pricing layer.

Contents
  • TL;DR
  • The HTML switcher
  • Allow-list validation
  • The cookie
  • The filter
  • The conversion caveat
  • Frequently asked questions
  • Related guides
  • References

Last verified: 2026-04-23 on WooCommerce 9.x with WordPress 6.5. Originally published 2023-02-10, rewritten and updated 2026-04-23.

TL;DR

// functions.php
$allowed = array( 'USD', 'EUR', 'GBP' );

// Resolve requested or stored currency
global $how7o_dynamic_currency;
if ( isset( $_GET['currency'] ) && in_array( $_GET['currency'], $allowed, true ) ) {
    $how7o_dynamic_currency = $_GET['currency'];
    setcookie( 'currency', $how7o_dynamic_currency, time() + ( 30 * DAY_IN_SECONDS ), '/' );
} elseif ( isset( $_COOKIE['currency'] ) && in_array( $_COOKIE['currency'], $allowed, true ) ) {
    $how7o_dynamic_currency = $_COOKIE['currency'];
} else {
    $how7o_dynamic_currency = 'USD';
}

// Apply it
add_filter( 'woocommerce_currency', function ( $currency ) {
    global $how7o_dynamic_currency;
    return $how7o_dynamic_currency ?: $currency;
} );

The HTML switcher

<form method="get">
    <label for="currency">Currency:</label>
    <select id="currency" name="currency">
        <option value="USD">USD</option>
        <option value="EUR">EUR</option>
        <option value="GBP">GBP</option>
    </select>
    <button type="submit">Switch</button>
</form>

A plain GET form — submits to the same URL with ?currency=XXX. The PHP snippet picks up the parameter on the next request.

Allow-list validation

$allowed = array( 'USD', 'EUR', 'GBP' );

if ( isset( $_GET['currency'] ) && in_array( $_GET['currency'], $allowed, true ) ) {
    // safe — $_GET['currency'] is one of the three
}

Never trust $_GET directly. The allow-list makes sure only known currency codes reach the cookie and the filter — preventing tampering that would plant garbage into user sessions or trigger downstream errors when WooCommerce looks up a bogus currency’s symbol.

woocommerce currency switcher — $_GET allow-list stores a cookie, woocommerce_currency filter applies it

The cookie

setcookie(
    'currency',
    $chosen,
    time() + ( 30 * DAY_IN_SECONDS ),
    '/',                // path — must be / for site-wide
    '',                 // domain — leave empty for current host
    is_ssl(),           // secure — only over HTTPS
    false               // httponly — keep false if JS reads it
);

WordPress’s DAY_IN_SECONDS constant keeps the math readable. Path '/' is critical — subpath cookies won’t reach /cart/ and /checkout/. is_ssl() flags the cookie as secure when the request came in over HTTPS.

The filter

add_filter( 'woocommerce_currency', function ( $currency ) {
    global $how7o_dynamic_currency;
    return $how7o_dynamic_currency ?: $currency;
} );

woocommerce_currency is the master filter — WooCommerce calls it whenever it needs the current currency code (for prices, cart totals, PayPal requests, etc.). Returning our stored value overrides the admin-configured default for this request only.

The conversion caveat

This filter only changes which currency is displayed. If your base currency is USD and a $10 product is shown with the EUR symbol, it’s shown as €10 — not converted. Three options for real pricing:

  • Informational only — the switcher shows the currency label for staff reference, prices stay in base currency (fine for B2B where invoices are always in the base currency).
  • Filter prices manually — pair woocommerce_currency with woocommerce_product_get_price and multiply by an FX rate from a config table. Doable for 3–5 currencies; brittle as the list grows.
  • Use a multi-currency plugin — WooCommerce Multi-Currency, WPML WCML, WooCommerce Payments built-in multi-currency. Handles per-currency pricing, rate updates, tax calculations. Right answer for production.

Frequently asked questions

What’s the quickest woocommerce currency switcher?

Read $_GET['currency'] against an allow-list, store it in a cookie, and filter woocommerce_currency to return the stored value on subsequent requests. ~20 lines in functions.php. Changes which currency symbol and code WooCommerce emits throughout the storefront — but note this doesn’t convert the prices themselves; you still need a conversion layer or multi-currency pricing plugin for that.

Does the woocommerce_currency filter convert prices too?

No — it only changes which currency is displayed (symbol, code, ISO). Prices stay in the store’s base currency numerically unless something else converts them. For real multi-currency (EUR prices actually charged in EUR), reach for WooCommerce Multi-Currency or similar. The filter is only appropriate when prices happen to match across currencies or when you’re showing informational currency labels.

Is the cookie-based approach safe against CSRF?

The currency switch itself isn’t a destructive action, so CSRF isn’t the main concern — but always validate the $_GET value against an allow-list (in_array($_GET['currency'], ['USD', 'EUR', 'GBP'])) so an attacker can’t force an arbitrary string into the cookie. Skipping the allow-list lets someone plant junk values that cause downstream errors.

Can I use the customer’s IP to auto-detect currency?

Yes — Cloudflare sets CF_IPCountry, MaxMind GeoIP2 lookups give you a country code. Map country to currency server-side (default EUR for EU countries, GBP for UK, USD for others) and set the cookie on first visit. This works as a first-visit default but still let users override via the switcher — some UK customers browse with US pricing intentionally.

Where should the cookie path be set?

'/' — the cookie should apply site-wide, so every page honors the switch. Setting it on a sub-path (/shop/) means the cart and checkout (on /cart/ and /checkout/) wouldn’t see the cookie and would show the default currency. Always '/' unless you have a very specific reason.

Related guides

  • How to Add a Custom Fee in WooCommerce — another cart-surface customization.
  • How to Remove Checkout Fields in WooCommerce — simplifying what the customer sees.
  • How to Display Orders Instead of Dashboard on the WooCommerce My Account Page — My Account tweak.
  • Fix ERR_TOO_MANY_REDIRECTS in WordPress After Switching to HTTPS — cookie/domain configuration gotchas.

References

WooCommerce woocommerce_currency filter docs: woocommerce.com/document/add-new-currency-to-woocommerce.

TAGGED:phpWooCommercewordpress

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Previous Article WooCommerce product view counter — meta-based counter with increment and display hooks How to Display a Product View Counter in WooCommerce Without a Plugin
Next Article WooCommerce get customer ID from order — WC_Order::get_user_id How to Get the Customer ID from an Order ID in WooCommerce
Leave a Comment

Leave a Reply Cancel reply

You must be logged in to post a comment.

FacebookLike
XFollow
PinterestPin
InstagramFollow

Subscribe Now

Subscribe to our newsletter to get our newest articles instantly!
Most Popular
Display PHP errors — ini_set + php.ini configuration
How to Display PHP Errors
May 10, 2026
PHP convert string to uppercase — strtoupper and mb_strtoupper
How to Convert a String to Uppercase in PHP
May 10, 2026
PHP string to float conversion with cast, regex cleanup, NumberFormatter
How to Convert a String to Float in PHP
May 10, 2026
PHP merge arrays without duplicates — union operator and array_unique
How to Combine Two Arrays Without Duplicates in PHP
May 10, 2026
PHP delete array element — unset, array_splice, array_filter, array_search
How to Delete an Element from a PHP Array
May 10, 2026

You Might Also Like

Capitalize all words in JavaScript with a ucwords-style function
Web Development

Capitalize All Words in JavaScript (ucwords Equivalent) + First Letter Uppercase

6 Min Read
Laravel user password being updated via artisan tinker with Hash::make
Web Development

How to Change a User Password in Laravel

6 Min Read
WooCommerce remove checkout fields — woocommerce_checkout_fields filter unsetting fields
Web Development

How to Remove Checkout Fields in WooCommerce

6 Min Read
Send a simple email in Laravel using Mail::raw and SMTP
Web Development

How to Send a Simple Email in Laravel (Fast SMTP + Mail::raw)

4 Min Read
How7o

We provide tips, tricks, and advice for improving websites and doing better search.

Latest News

  • SEO Audit Tool
  • Client ReferralsNew
  • Execution of SEO
  • Reporting Tool

Resouce

  • Google Search Console
  • Google Keyword Planner
  • Google OptimiseHot
  • SEO Spider

Get the Top 10 in Search!

Looking for a trustworthy service to optimize the company website?
Request a Quote
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?