26

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:

  1. send amounts as a string like so: "5.85" (a string with base units)
  2. 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?

alvi
  • 2,622
  • 1
  • 22
  • 34
  • 4
    Wow, this is an amazing summary of how various APIs do that! – Georgii Oleinikov Jul 29 '17 at 07:27
  • 1
    +1 for the research effort ! Similar questions are also debated on SO : https://stackoverflow.com/questions/45222706/what-are-the-best-practices-passing-dollar-amounts-in-json https://stackoverflow.com/questions/30249406/what-is-the-standard-for-formatting-currency-values-in-json – Jean-Rémy Revy Aug 08 '17 at 15:58

2 Answers2

1

Integers will eat the dot, that's one less byte :D Integers will have a max_int, do you have anyone rich enough that may overflow?

People that will parse a currency string as float will turn the int to float anyway.

If you send binary data, integer will be much smaller than a string and the way to go. If you send xml anyway, you might as well define it a string (the file is probably compressed before sending right?), try to make it "currency" type as opposed to listing it as a full string though.

gia
  • 757
  • 5
  • 19
0

Which datatype is the best depends on your usage. For calculations integers or doubles are going to be faster, skipping the parsing step. If sending the data through networks is your goal you're better off with strings.

That said, any functionality should be realizable using either method.

Maarten
  • 7
  • 1