Build a multi-currency e-commerce platform in Bubble by storing product prices in a base currency, fetching live exchange rates via API, displaying converted prices based on user selection, and processing Stripe payments in the customer's chosen currency. This lets you serve international customers with accurate, localized pricing without writing code.
Overview: Building Multi-Currency E-Commerce in Bubble
This tutorial shows you how to add multi-currency support to a Bubble e-commerce app. You will store all product prices in a single base currency, integrate a live exchange rate API, build a currency selector that dynamically converts displayed prices, and configure Stripe to charge in the customer's preferred currency. This is ideal for any online store serving international customers.
Prerequisites
- A Bubble account with an e-commerce app started
- Stripe plugin installed with test API keys configured
- API Connector plugin installed
- Basic understanding of Bubble data types, workflows, and dynamic expressions
Step-by-step guide
Set up the base currency data structure
Set up the base currency data structure
Go to the Data tab and ensure your Product data type has a price_usd (number) field — this is your base currency (USD). Create an Option Set called Currency with options: USD, EUR, GBP, JPY, CAD, AUD. Add attributes: symbol (text, e.g., $, EUR, GBP), code (text, matching ISO codes). Create a data type called ExchangeRate with fields: currency_code (text), rate_to_usd (number), and last_updated (date). This stores cached exchange rates.
Expected result: Products have a base USD price, a Currency Option Set exists, and an ExchangeRate data type is ready to store rates.
Configure the exchange rate API
Configure the exchange rate API
Go to the Plugins tab and open the API Connector. Add a new API called ExchangeRates. Create a call named GetRates with Use as set to Action, method GET, and URL: https://api.exchangerate-api.com/v4/latest/USD (this free API returns rates for all currencies). Click Initialize call to map the response. The response includes a rates object with currency codes as keys and conversion rates as values. Save the call.
Pro tip: The free exchangerate-api.com plan allows 1,500 requests per month. For production apps, consider a paid plan or cache rates daily.
Expected result: The API Connector is configured to fetch live exchange rates from USD to all supported currencies.
Build a rate caching workflow
Build a rate caching workflow
Create a backend workflow called update_exchange_rates. In it: Call the GetRates API. For each supported currency, search for the existing ExchangeRate record and update its rate_to_usd and last_updated fields. If no record exists, create one. Schedule this backend workflow to run once daily using Schedule API workflow with a recurring schedule. This avoids calling the API on every page load and reduces costs.
Expected result: Exchange rates are cached in the database and updated daily via a scheduled backend workflow.
Add the currency selector to your storefront
Add the currency selector to your storefront
On your product listing page, add a Dropdown in the header linked to the Currency Option Set. When the user selects a currency, set a Custom State on the page called selected_currency (type: Currency Option Set) to the dropdown's value. Default it to USD. In each product card's price display, use a dynamic expression: Product's price_usd * Search for ExchangeRates (currency_code = Page's selected_currency's code):first item's rate_to_usd, formatted as currency with the selected symbol.
Expected result: Users select a currency and all product prices on the page convert to the selected currency in real time.
Configure Stripe for multi-currency checkout
Configure Stripe for multi-currency checkout
When the user clicks Buy, the checkout workflow calculates the converted price: Product's price_usd * ExchangeRate for the selected currency. Pass this amount (multiplied by 100 for cents) to the Stripe Checkout element along with the currency code (e.g., eur, gbp). Stripe supports 135+ currencies natively. Store the Pledge or Order record with both the original USD price and the charged amount in the customer's currency for accounting.
Pro tip: For JPY and other zero-decimal currencies, do not multiply by 100 — pass the amount as-is. Check Stripe's documentation for currency-specific rules.
Expected result: Customers are charged in their selected currency through Stripe, and both amounts are recorded in the database.
Display localized prices throughout the app
Display localized prices throughout the app
Replicate the currency conversion pattern on all pages: cart, checkout, order history, and product detail. On the cart page, convert each line item's price and the cart total using the same exchange rate lookup. Store the user's preferred currency on their User profile so it persists across sessions. When a user logs in, set the page's selected_currency custom state from their saved preference. For complex international e-commerce setups, consider reaching out to RapidDev for expert Bubble development.
Expected result: Prices appear in the user's preferred currency consistently across all pages, with the preference saved to their profile.
Complete working example
1MULTI-CURRENCY E-COMMERCE — WORKFLOW SUMMARY2===============================================34DATA TYPES:5 Product6 - name (text)7 - description (text)8 - price_usd (number) — base price in USD9 - image (image)1011 ExchangeRate12 - currency_code (text) — e.g. EUR, GBP13 - rate_to_usd (number) — e.g. 0.92 for EUR14 - last_updated (date)1516 Order17 - customer (User)18 - product (Product)19 - price_usd (number) — original base price20 - price_charged (number) — converted amount21 - currency_charged (text) — e.g. EUR22 - stripe_charge_id (text)2324OPTION SET: Currency25 USD — symbol: $ — code: USD26 EUR — symbol: EUR — code: EUR27 GBP — symbol: GBP — code: GBP28 JPY — symbol: JPY — code: JPY29 CAD — symbol: CA$ — code: CAD30 AUD — symbol: A$ — code: AUD3132PAGE CUSTOM STATE:33 selected_currency (Currency Option Set, default: USD)3435PRICE DISPLAY FORMULA:36 Product's price_usd37 * Search for ExchangeRates38 (currency_code = selected_currency's code)39 :first item's rate_to_usd40 Formatted as: #,##0.0041 Prefix: selected_currency's symbol4243BACKEND WORKFLOW: update_exchange_rates44 Runs: daily at 00:00 UTC45 Step 1: Call ExchangeRates API - GetRates46 Step 2: For each supported currency:47 Search for ExchangeRate (currency_code = code)48 If exists: Make changes → rate_to_usd = API result49 If not: Create new ExchangeRate record5051WORKFLOW: Checkout52 Event: Button Buy is clicked53 Step 1: Calculate converted price54 price_usd * exchange rate for selected currency55 Step 2: Stripe Checkout56 Amount: converted price * 100 (skip *100 for JPY)57 Currency: selected_currency's code (lowercase)58 Step 3: Create Order59 price_usd = Product's price_usd60 price_charged = converted amount61 currency_charged = selected_currency's code62 stripe_charge_id = Stripe charge IDCommon mistakes when building multi-currency ecommerce in Bubble
Why it's a problem: Calling the exchange rate API on every page load
How to avoid: Cache exchange rates in a data type and update them once daily via a scheduled backend workflow.
Why it's a problem: Storing converted prices instead of base currency prices on products
How to avoid: Always store prices in one base currency (USD) and convert dynamically at display time using cached rates.
Why it's a problem: Multiplying JPY amounts by 100 for Stripe
How to avoid: Check Stripe's zero-decimal currency list and skip the *100 multiplication for those currencies.
Best practices
- Store all product prices in a single base currency and convert dynamically at display time
- Cache exchange rates in the database and update daily via a scheduled backend workflow
- Use an Option Set for supported currencies with symbol and code attributes
- Save the user's preferred currency on their profile for persistent selection across sessions
- Record both the base price and the charged amount on orders for accurate accounting
- Handle zero-decimal currencies (JPY, KRW) differently when passing amounts to Stripe
- Test the checkout flow with multiple currencies using Stripe test mode
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building an e-commerce platform in Bubble.io that needs multi-currency support. Products are priced in USD but I want to display and charge in EUR, GBP, JPY, and other currencies. How do I set up exchange rate fetching, price conversion, and Stripe multi-currency checkout?
Add multi-currency support to my e-commerce app. Fetch exchange rates via API and cache them daily. Add a currency selector that converts all displayed prices. Configure Stripe checkout to charge in the customer's selected currency.
Frequently asked questions
Which exchange rate API should I use?
ExchangeRate-API.com offers a free tier with 1,500 monthly requests. For production, Open Exchange Rates ($12/mo) or Fixer.io ($10/mo) offer more reliable uptime and higher rate limits.
How often should I update exchange rates?
Daily updates are sufficient for most e-commerce apps. If you sell high-value items where rate fluctuations matter, consider updating every few hours.
Does Stripe handle currency conversion automatically?
Stripe charges in whatever currency you specify. It does not convert automatically. You must calculate the converted amount and pass it with the correct currency code.
How do I handle refunds in a different currency?
Stripe refunds in the original charge currency. Store the currency_charged and stripe_charge_id on the Order so you can issue accurate refunds.
Can I show prices without decimal places for some currencies?
Yes. Use a conditional format: When selected_currency is JPY, format the number with zero decimal places. For USD and EUR, use two decimal places.
Can RapidDev help with international e-commerce features?
Yes. RapidDev specializes in Bubble development and can help build complete international e-commerce platforms with multi-currency, tax calculation, shipping zones, and localized checkout flows.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation