Found this after a partner integration went live in Japan. Our internal ledger stored every amount as an integer in the smallest unit, same as we did for USD and EUR — cents. Except JPY doesn't have cents. Neither does KRW, VND, or a dozen others ISO 4217 lists with zero decimal places.
A charge for 1000 yen came through the gateway as "1000" in the amount field. Our code, built around the assumption that every amount field is minor units of a two-decimal currency, divided by 100 before writing to the ledger. Customer got charged 1000 yen, our records showed 10. Refund requests then tried to refund 10 yen against a 1000 yen charge and the processor rejected the mismatch, which is the only reason we caught it in days instead of a full billing cycle.
The fix was a currency-to-decimal-places lookup table, but the real fix was admitting the assumption existed at all. It had been sitting in three different services: the charge creator, the refund handler, and the reconciliation job. Each one had copied the /100 logic from the other.
How many of you have a canonical currency-decimals table somewhere, versus this logic just being reimplemented per service?
Top comments (0)