How to Handle Multi-Currency and International Payments in Bubble.io
Selling globally means charging in local currencies, handling VAT, paying out in local currencies, and reporting revenue across currency boundaries. This guide covers every layer of multi-currency implementation in Bubble with Stripe.
Why Multi-Currency Is More Than Changing a Currency Symbol
Displaying “$49” vs “€49” is trivial. Real multi-currency support means: charging customers in their local currency, remitting to sellers or service providers in their local currency, handling exchange rate fluctuations in reporting, complying with VAT and tax requirements per country, and ensuring Stripe is configured to accept and payout in the right currencies. Each of these is a distinct challenge with a distinct solution in Bubble.
Store All Amounts in the Smallest Currency Unit
Stripe requires amounts in the smallest unit of a currency — cents for USD, pence for GBP, fils for AED. Always store your prices in Bubble as the major unit (49.00) and multiply by 100 before sending to Stripe (price * 100). Never store cents in Bubble — it makes your UI math incorrect and your data confusing.
Five Layers of Multi-Currency Implementation
Workspace:
currency → text (ISO code: “USD”, “EUR”, “GBP”)
currency_symbol → text (“$”, “€”, “£”)
stripe_customer_id → text (one Customer per workspace)
// Set during workspace creation based on IP geolocation
// or let user select from a currency dropdown
amount = price * 100 (in smallest unit)
currency = Workspace’s currency (“usd”, “eur”, “gbp”)
// Stripe uses lowercase ISO codes
// Stripe will decline if your account doesn’t support the currency
// Enable currencies in Stripe Dashboard > Settings > Payouts
In Stripe, a subscription Price is currency-specific. A $49/mo plan and a €49/mo plan are two separate Price objects with two separate IDs. Store both IDs on your Plan data type: stripe_price_usd, stripe_price_eur, stripe_price_gbp. On checkout, select the Price ID matching the workspace’s currency.
Price display:
Workspace’s currency_symbol + Plan’s price_monthly
// Result: “$49” or “€49” or “£49”
// For formatting with decimals and thousands separator
Formatted price:
price:formatted as $#,###.## → then replace “$” with currency_symbol
For EU customers, VAT must be collected and remitted per country. Enable Stripe Tax (automatic tax calculation) on your checkout sessions — Stripe handles the calculation, collection, and reporting. Store the customer’s country on the Workspace record and pass it to Stripe on Customer creation.
Multi-Currency Revenue Reporting in Bubble
Reporting revenue across currencies requires a common unit. The two options: report in each currency separately (show $MRR, €MRR, £MRR as separate figures) or convert everything to a base currency using a stored exchange rate. Store a daily exchange rate on a CurrencyRate data type updated by a Scheduled Workflow via an exchange rate API. Multiply each workspace’s MRR by its exchange rate to the base currency for the total.
Ready to Build on Bubble?
Architecture, data model design, Stripe billing, and full SaaS builds — done right from day one.