Documentation
Amounts and currencies
Why every amount is an integer, and how to convert it correctly for display.
Minor units
Every amount in the API is an integer in the currency's minor unit, paired with an ISO 4217 currency code. €12.30 is { "amount": 1230, "currency": "EUR" }. Floating-point numbers are never accepted: 12.3 returns 400 invalid_request.
Why not decimals?
0.1 + 0.2 is 0.30000000000000004 in binary floating point. Money that is stored or summed as floats drifts. Integers do not.Currency exponents
| Currency | Exponent | Example | Meaning |
|---|---|---|---|
| EUR | 2 | 1230 | €12.30 |
| RON | 2 | 4999 | 49.99 lei |
| GBP | 2 | 500 | £5.00 |
| JPY | 0 | 1500 | ¥1,500 |
| TND | 3 | 12500 | 12.500 TND |
| BHD | 3 | 1000 | 1.000 BHD |
Displaying amounts
Convert to a decimal string without floating point, then let the platform format it for the user's locale:
TypeScript
function toDecimalString(minor: bigint, exponent: number): string {
const neg = minor < 0n;
const s = (neg ? -minor : minor).toString().padStart(exponent + 1, "0");
const out = exponent === 0 ? s : `${s.slice(0, -exponent)}.${s.slice(-exponent)}`;
return neg ? `-${out}` : out;
}
// Intl accepts numeric strings exactly:
new Intl.NumberFormat("it-IT", { style: "currency", currency: "EUR" })
.format(toDecimalString(1230n, 2) as unknown as number); // "12,30 €"
