Hacker News new | past | comments | ask | show | jobs | submit login

The amount option is leaving a slightly bitter taste in my mouth.

• It allows commas, which will just be stripped on execution. This feels like it’s just inviting errors unnecessarily, especially given that some parts of the world use comma (,) as their decimal separator and full stop (.) for grouping, rather than the other way round. I see no compelling reason for allowing grouping at all.

• “The 'unit' value MUST be smaller than 2^53. If present, the 'fraction' MUST consist of no more than 8 decimal digits.” Both of these feel a mite surprising, and the combination of them far more surprising. The 2⁵³ limit is doubtless to allow it to be safely stored in a 64-bit floating point number, specifically for JavaScript’s sake; but (dealing with this part first) do you know how small 2⁵³ is? 9 quadrillion. That’s honestly not that large. I’ve handled a 100 trillion dollar note, and that’s hardly the highest any currency has ever gone. (Admittedly, the sorts of currencies where this is happening probably have limited use for a payto: URI scheme at the time.) But anyway, skipping onto the second part, a fraction of up to eight digits. Skipping over the apparent arbitrariness of the number (which happens to match Bitcoin’s division), if you’ve made concession to treat the unit as a Number, what about the fraction? If you wanted to retain eight decimal places of significance, you’d be limiting your unit to 2⁵³ ÷ 10⁸, about 90 million, which is obviously too low, so you clearly can’t be meant to be representing the whole thing as a Number, so why that restriction on the unit? So yeah, both of these limits simply feel weird to me.

But other than these quibbles, I say: finally! I’m really glad about this and hope it gets adopted by banking apps and the likes quickly, and added to the HTML spec’s safelisted schemes (https://html.spec.whatwg.org/#safelisted-scheme) so that banks’ web apps can also navigator.registerProtocolHandler("payto", "https://bank.example/payto-handler/%s") soon. And also that Australian banks either register some way of addressing their accounts as a payto payment target type, or adopt IBAN.




Wow, I had not spotted this yet.

Omitting a comma turns an amount with Euro Cents to 100 times the amount here in Germany. I can both see this comma/dot problem be missed in development and can also imagine such a payment go through, as a few digit amount times one hundred still gives an amount that people can have in their bank accounts. Users clicking through confirmation dialogs and dismissing wrong information as 'computer problems' is not an unheard-of problem either.

This is really inviting trouble - without good reason? - as a payment 'API' having to deal with how a number was displayed to a user seems out of scope for it.


Seriously, not to get too down on the author, but whoever wrote this was way out of touch with what a decent standard should look and act like. So many blatant flaws like this.


Try to be constructive in your critique.


Do or do not, there is no try :)


practically speaking this kind of bugs gets detected immediately and is corrected immediately. so in reality, it's not that dangerous.


They do not.

This reminds me of a bug I happened to come across with a cheap offshore company I had to deal with a while back (well, a very expensive consulting company that used a very cheap offshore company for development). We were dealing solely with Pound Sterling (100 pence make a pound). As part of the API requirements, they were asked to solely deal with pence in integers. They ignored the requirements and used pounds in floats.

This caused rounding errors here and there. We spotted the problem as soon as we heard about the rounding errors, and asked them to correct it. Later on, our customer asked us why the items that cost £1.85 were being charged correctly, but the items that cost £1.90 were being charged at 19p.

Turns out that rather than doing anything sensible, they took the float, converted it to a string, stripped out the period, then converted the string to an integer. So £1.85 became "1.85", then "185", then 185p, but £1.90 became "1.9", then "19", then 19p.

They managed to put this into production before we had a chance to see it. Yes, it was a dysfunctional project. But there’s lots of them out there. If you leave a footgun like this lying around, there’s no end of companies that will not only shoot themselves in the foot but happily reload while you are scrambling to stop them.


> they took the float, converted it to a string, stripped out the period, then converted the string to an integer.

This simultaneously made my day much better, and much worse.


I've worked on an enterprise application serving hundreds of millions of users and this exact error went out the door.

So no, practically speaking, this absolutely does not get caught right away. And if the specification is this sloppy, it should be thrown out and redone.


The specification is not sloppy, it specifies precisely the wire format, and does expressly cover this problem of how the values MUST be interpreted. The specification does not cover how the application should render the amount when showing it to the user, so when applications show the amount to the user they can of course still render it in a culturally appropriate way.


It specifies the wire format and how it must be interpreted, but deliberately leaves a big footgun in place where there was no need to do so.


Woah, this is beyond just "bitter taste." If these values are potentially stored in JS Numbers, this scheme is completely dead on arrival. It is not acceptable for currency to be stored in a floating-point data type, full stop. This proposal needs to at a minimum define a datatype for how these values should be stored, not just leave it up to implementations to throw it at `var currency = x;`

This RFC is woefully underspecified, and the fact that there's an amount of its already-small specification devoted to "7.5. Bitcoin Address" makes me question their priorities and destroys a lot of confidence in the proposal.


I think you’re exaggerating the severity of the issues. “Such-and-such an integer must be less than 2⁵³” is normally a reasonable constraint to make life easier for people across all environments, and to make some such constraint is typically a good thing, rather than leaving it unspecified. I just think that the limit is on the low side here and probably unjustified due to what else is going on—and that perhaps this should be one of the rare cases where you deliberately don’t specify any limit (to the magnitude of unit or the length of fraction), and leave it to the client to decide what makes sense.

On the Bitcoin part: that’s just putting an entry in the registry, a perfectly reasonable and normal thing to do in such a specification. They’ve included entries for four of the main traditional banking systems, and two of the main new-generation systems that people are sure to want to combine this with.


2^53 isn't enough in hyper inflation situation.


If you deal with money, you do have to store the fraction separately anyway and clearly should not use floating point. But that's beyond the point. The upper bound is there to ensure that you do not have to use BigNum in languages like JavaScript, not to tempt you to simply represent the amount in a double.


> The upper bound is there to ensure that you do not have to use BigNum in languages like JavaScript,

I think that is a far too generous read of the document. I think it's because they wanted you to be able to use a JS Number to store the value, which is the Wrong Thing To Do. In fact, using two BigInts to separately represent the fractional and whole pieces of the currency would be far better.

This is the kind of ambiguity that I refer to when I say this is underspecified.


Eh, it’s not underspecified. It’s just… strangely specified, in a way that people will ignore and misparse. But then, if it had been specified in any other way people would have ignored and misparsed it too.


People going to put money in floats unless you make it impossible. Then they send it via json and round and probably over or under flow and all sorts of amusing bugs result.


If JavaScript numbers work up to 2^52 that could precisely represent $45 trillion in cents.

IMHO if they had a choice between dropping Javascript support in preference of languages with BigInt support, or dropping support for payments larger than $45 trillion, they probably made the right decision.



It's an early request for comments, so I guess you should find out how to respond to the RFC properly, if you don't know already.


The name is request for comments, but the meaning is technical internet standard. This RFC has already been published, so it's no longer just a draft.


I know. That was meant as a joke somehow. But nevertheless, you can email the authors and tell them about your concerns. I think there's a process of improving RFCs via errata.


This one is an informational RFC though. No internet standard.


It's an informational RFC which is already published. So there's no review process anymore, it's done already. And as it's informational, it's not a "real" standard (no going through implementations etc)


Would it be better to store the integer and fractional parts separately, or mantissa and exponent?


I’m just going to say “no”.

If you don’t need to work with the value, store it in a string. If you do, use a proper decimal type. (Your question may then apply to the internals of the decimal type, but the point is that that should be transparent to the developer accessing the decimal value.)


Most developers don't know the difference between a float and a decimal. I've had to fix this at least five times in my career.


My favorite is when someone tries to treat either a Zipcode or a CVV as a number.


I think that makes sense, given the room for confusion

Just curious does any country use fractions of a bill other then 1/100 (ie cents)


This was posted here regarding some similar discussion a while ago.

"Falsehoods programmers believe about prices"

https://gist.github.com/rgs/6509585


The USA does, for example. There are ten mill in a cent. Apparently Tunisia even has five-mill coins in circulation.

https://en.wikipedia.org/wiki/Mill_(currency)


Going to add to the other comments that the "1" is not a bill in many currencies. For example the smallest Euro bill is 5€.

Other currencies do not have a fractional part at all and use just one integer.


FWIW Japan doesn’t use fractions - 1 yen is approx 1 US penny. Lunch is 300-500 yen.


IIRC correctly one country uses three digits in the less than one realm. This site https://www.localeplanet.com/icu/currency.html has one three and even a four.


US gas stations frequently give prices in fractions of a cent.

https://www.marketplace.org/2018/10/11/why-do-gas-prices-end...


Meh, from what I've seen so far, it's just so people see, e.g. 2.55 $/gal with the tiny nine in the corner, stop by and get charged 2.559 $/gal (essentially squeezing that last cent out of customers.)

I'd be interested to hear if anyone else has seen any digit other than nine in the tenth-of-a-cent column though.


I believe it's because gas prices are quoted with tax (which is unusual in the US), and there is a federal tax ending in 9 tenths of a cent. Probably lobbied by the small 9 marquee digit manufacturers of america.


Australian fuel prices are listed in cents to one decimal place. >80% of the time the last digit is a nine, the rest of the time it’s most commonly a 5. I’ve seen other odd digits rarely, with even numbers just about unheard of. But what you actually pay will be rounded to the cent, or to the nearest 5¢ if you pay in cash.

The whole concept involved here is called psychological pricing (https://en.wikipedia.org/wiki/Psychological_pricing). I wish it was illegal.


Yes 1/1000 is very commom in the Arab world.


How does iOS handle custom schemes when you’ve got two banking apps?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: