XOF has no cents — the bug that cost me 3 hours
When you work with European or American payment APIs, amounts get sent in cents.
€5 → you send 500.
A €1.50 coffee → you send 150.
It's a convention to avoid floats in financial calculations.
The problem: I'd picked up that habit. And the first time I integrated Moneroo, I did the same thing.
5,000 FCFA → I sent 500000.
Result: the payment link displayed 500,000 FCFA. Not 5,000.
XOF — and several African currencies — have no subdivision into cents. 5,000 FCFA is 5,000. Not 50 FCFA. Not 500,000 FCFA. 5,000.
The currencies affected: XOF, XAF, GNF, CDF.
Since then, every Moneroo project of mine has this function:
const NO_SUBUNIT = ["XOF", "XAF", "GNF", "CDF"];
function toMonerooAmount(amount: number, currency: string): number {
return NO_SUBUNIT.includes(currency) ? amount : Math.round(amount / 100);
}
function formatPrice(amount: number, currency = "XOF"): string {
return new Intl.NumberFormat("fr-FR", {
style: "currency",
currency,
minimumFractionDigits: 0,
}).format(amount);
}
// formatPrice(5000, "XOF") → "5 000 FCFA"If the currency is in NO_SUBUNIT, the amount you have stored is already correct. Nothing to divide.
Rule of thumb: XOF never divides.