for any APIs related to money, should the currency be in strings as opposed to in floats? This will prevent accidental float arithmetic in the code. I always find it tricky to work with currency in javascript.
From their docs [1] it looks like they do everything using integers: the amounts are integers in the "minor unit" of currency, for example cents if the currency is dollars. So 1000 means $10.00. In languages like JavaScript where everything is a float64, you can still accurately represent integers up to 2^53, which would be $90 trillion.
This isn't sufficient to represent prices which often include fractional amounts of cents in non-retail scenarios. Think of AWS server prices per hour.
Yes, never use floats for currency. I typically use integers and for USD for example, measure in "cents" rather than dollar. I try to avoid the fallacy of appeal to authority, but this is what Stripe does. You can also use the Decimal type in javascript and convert to/from strings to cross API boundaries.
Google's money proto [1] has units and nanos. Any competent ad-tech system will use something similar: integer number of micro-dollars, nano-dollars, etc. You want a fair amount of precision, so just tracking whole cents isn't enough, but you want that precision to be (linearly) equally distributed across the value space so that you can make intuitive guarantees about how much error can accumulate.
I will be the contrarian: JSON numbers are not floating point values, they are strings of characters matching the format "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?". You can choose to parse them however you want, and parsing libraries should provide a mechanism to decode to an arbitrary-precision value.
By way of example: when I worked on payment code in Java, we accepted numeric JSON values in request payloads but they were deserialized into "BigDecimal" fields in our payload classes, not "float" or "double".
Luckily, there are not many broken JSON parsers out there, as this is a well-known issue. Just about the only parser that remains broken is Javascript's JSON.parse(), because it doesn't allow for any options to control the parser, which is why we keep having this discussion.
Yes, because JSON.parse() treats the input as if it were a JS object literal; that is, JSON.parse(JSON.stringify(someObject)) will be idempotent. Usually parser libraries let you construct a parser with options, so you'd make a "let json = JSON({parseNumbersAsBignums: true})" and use that everywhere, but JS doesn't have that built in.
Some currencies use more than 2 decimal places. For instance, the currencies of Algeria, Bahrain, Iraq, Jordan, Kuwait, Libya, and Tunisia are subdivided into 3 decimals.
I'm not sure what you mean by "arbitrary place values" with Bitcoin; if you are implying it's infinitely divisible, it isn't. You'd do the same trick with Bitcoin: represent it as an integer¹. The value 1 is 1 sat, or 0.00000001 BTC.
¹(where you need to; otherwise, I'd use some fixed point type if my language supports it)
Don't use floats if you're trying to represent an exact value, i.e. someones bank account. But in financial modelling you're generally dealing in probabilistic "expected values", it's common and fine to use floats.
Having said that, half the world seems to run on Excel spreadsheets, which are full of money values, and Excel is basically all floats (with some funky precision logic to make it deterministic - would be curious to know more).