If your online store only shows prices in one currency, you are leaving money on the table. International shoppers who cannot see prices in their own currency are far more likely to abandon their cart.
Why Multi-Currency Pricing Matters
- 92% of shoppers prefer to see prices in their local currency before making a purchase.
- 33% of international visitors abandon their cart when prices are displayed only in a foreign currency.
- Stores with multi-currency support see 12-15% higher conversion rates on average.
How Multi-Currency Pricing Works
- Detect the customer's location or preferred currency.
- Fetch current exchange rates from a reliable API.
- Convert your base prices into the target currency.
- Display the converted price with proper formatting.
- Handle checkout in either your base currency or the customer's local currency.
Step 1: Detect the Customer's Location and Currency
GeoIP Detection
Use the customer's IP address to determine their country. Services like MaxMind GeoLite2 or Cloudflare's CF-IPCountry header make this simple.
Manual Currency Selector
Always give customers the option to override automatic detection.
// Map country code to currency
const countryCurrencyMap = {
US: 'USD', GB: 'GBP', DE: 'EUR', FR: 'EUR',
JP: 'JPY', CA: 'CAD', AU: 'AUD', IN: 'INR',
BR: 'BRL', MX: 'MXN', CN: 'CNY', KR: 'KRW'
};
function getCurrencyFromCountry(countryCode) {
return countryCurrencyMap[countryCode] || 'USD';
}
Step 2: Fetch Exchange Rates from an API
Exchange Rate API is an excellent choice for e-commerce. It provides mid-market rates for 160+ currencies, updates every 60 seconds, and offers a free tier.
// Fetch exchange rates from Exchange Rate API
const API_KEY = 'your_api_key_here';
async function getExchangeRates(baseCurrency = 'USD') {
const response = await fetch(
`https://exchange-rateapi.com/api/v1/rates?base=${baseCurrency}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const data = await response.json();
return data.rates; // { EUR: 0.9178, GBP: 0.7892, JPY: 149.53, ... }
}
Here is a simple caching layer:
// Simple in-memory cache for exchange rates
let cachedRates = null;
let cacheTimestamp = 0;
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getRates(baseCurrency = 'USD') {
const now = Date.now();
if (cachedRates && (now - cacheTimestamp) < CACHE_TTL) {
return cachedRates;
}
cachedRates = await getExchangeRates(baseCurrency);
cacheTimestamp = now;
return cachedRates;
}
Step 3: Convert and Display Prices
function convertAndFormat(priceInBase, targetCurrency, rates) {
const converted = priceInBase * rates[targetCurrency];
return new Intl.NumberFormat(undefined, {
style: 'currency',
currency: targetCurrency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(converted);
}
// Usage
const rates = await getRates('USD');
console.log(convertAndFormat(49.99, 'EUR', rates)); // "€45.89"
console.log(convertAndFormat(49.99, 'JPY', rates)); // "¥7,474"
Step 4: Handle Checkout and Payment
Option A: Display in Local Currency, Charge in Base Currency
Show the converted price throughout browsing, but charge in your base currency. Simpler to implement.
Option B: Charge in the Customer's Local Currency
Use your payment processor's multi-currency settlement feature. Stripe, PayPal, and Adyen all support this.
| Factor | Option A (Display Only) | Option B (Charge Local) |
|---|---|---|
| Implementation effort | Low | Medium-High |
| Customer experience | Good | Excellent |
| Currency risk | On customer | On merchant |
| Recommended for | Getting started quickly | Scaling international sales |
Common Pitfalls to Avoid
Rounding Errors
Always round after the final conversion, not during intermediate calculations.
Stale Exchange Rates
If your cache expires and the API is temporarily unreachable, serve the stale rates rather than showing an error.
Price Anchoring Issues
Consider adding a small buffer (1-3% markup on the mid-market rate) to absorb minor fluctuations so prices feel more stable.
Platform-Specific Tips
Shopify
Shopify Markets handles multi-currency natively. For more control over rates, integrate with Exchange Rate API through a custom app.
WooCommerce
Use the WPML WooCommerce Multilingual plugin and customize the rate source to pull from Exchange Rate API.
Custom Stores (Node.js, React, Next.js)
// Next.js API route example
// pages/api/prices.js
import { getRates } from '../../lib/rates';
export default async function handler(req, res) {
const { currency = 'USD' } = req.query;
const rates = await getRates('USD');
const rate = rates[currency] || 1;
const products = getProducts().map(product => ({
...product,
displayPrice: formatPrice(product.basePrice * rate, currency),
rawPrice: Math.round(product.basePrice * rate * 100) / 100
}));
res.json({ products, currency, rate });
}
Frequently Asked Questions
Does showing prices in local currency increase conversions?
Yes. Studies show 92% of shoppers prefer to see prices in their local currency, and multi-currency stores see 12-15% higher conversion rates.
How do I get exchange rates for my e-commerce store?
Use an exchange rate API like Exchange Rate API to fetch real-time mid-market rates. Rates update every 60 seconds for 160+ currencies.
Should I use mid-market or retail exchange rates for pricing?
Use mid-market rates as your baseline, then add a small markup (1-3%) to cover currency fluctuation risk.
Add live rates to your store
npm install @exchangerateapi/sdk
Power Your Store with Real-Time Rates
160+ currencies, 60-second updates, free tier with no credit card. Built for e-commerce.
Get Your Free API Key →
