I'm going to create an API which contains money amounts. I was wondering what the best practices are, or whether someone has some good or bad experiences with certain formats.
- should we transmit base units or minor units? (amount vs amount_cents)
- should we represent the numbers as integers / decimals or as strings?
I've seen the following two possibilities:
- send amounts as a string like so: "5.85" (a string with base units)
- send amounts in their minor unit: 585 (an integer which expresses the amount in the minor unit)
I'm going back and forth between those two. So I went out to check what other APIs use and came up with the following list:
- Stripe: integer with minor units
- Braintree: string with base units
- Google Wallet: string with base units
- Paypal: string with base units
- Amazon Payments: string with base units
- The Currency Cloud: string with base units
- 2checkout: string with base units
- Adyen: integer with minor units
- Dwolla: decimal with base units
- GotoBilling: weird heuristics! "Amount may be formatted with or without a decimal. If no decimal is given two (2) decimal places are assumed (1.00 = 100)"
- GoCardless: string with base units
- Intuit: decimal with base units in requests, string with base units in responses
- Klarna: integer with minor units
- MasterCard: integer with minor units
- Paynova: string with base units
- Rogers Catalyst: string with base units
- WePay: string with base units
- Venmo: decimal with base units
So, out of 18 sampled APIs, 4 are using minor units, 13 are using base units and 1 is using a hard-to-comprehend mixture. And within the 13 who use base units, 10 are transmitting them as quoted strings, 3 as unquoted decimals (actually 2 and a half if you look at Intuit).
I personally feel uncomfortable having to parse a string like "8.20", because if you parse this it becomes "8.19999999..." if you make the mistake to use floats. So I'm leaning towards sending integers only. But I don't think this is a great argument, and I see that generally APIs tend to go with base units as strings.
Do you have any good arguments for/against each format?