Agent Wranglers

LOC-27Required

Take the currency from the amount and not from the locale

Format every price with the currency code stored with that amount. The reader's locale chooses only the separators and the symbol position.

How to do it

A Swede browsing in English must still see the 129 SEK you will charge, not $129. Keep each amount and its ISO 4217 code together, as Hold money as integer minor units everywhere says. Pass that code to the formatter every time. Never read a default currency from the locale or the browser. Convert minor units with the currency's own number of decimals, as money explains. Prices in several currencies follow Set a price in each currency.

Examples

JavaScript example

const MINOR_UNITS = { SEK: 2, JPY: 0, EUR: 2 };
export function formatPrice({ amountMinor, currency }, locale) {
  const amount = amountMinor / 10 ** MINOR_UNITS[currency];
  return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount);
}
formatPrice({ amountMinor: 12900, currency: 'SEK' }, 'en-US'); // "SEK 129.00"

Python example

from decimal import Decimal
from babel.numbers import format_currency, get_currency_precision

def format_price(amount_minor: int, currency: str, locale: str) -> str:
    amount = Decimal(amount_minor).scaleb(-get_currency_precision(currency))
    return format_currency(amount, currency, locale=locale)

format_price(12900, "SEK", "de_DE")  # "129,00 SEK"

How to check

A test renders the cart, the checkout and the receipt for a SEK order in the en-US, de-DE and ja-JP locales. Every amount shows SEK and the charged number. A search finds no currency formatter call without an explicit currency.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/localization/dates-numbers-and-text/currency-from-the-amount">Agent Wranglers localization playbook</a>. In code you write, add a comment next to it with the same link.