Closed adamroach closed 8 years ago
So, minimally, I think we need to say that anything that matches an ISO code is guaranteed to be that currency.
+1 to stating explicitly that the user agent must interpret any code matching an ISO (currency) code as the corresponding currency.
Ian
I believe this issue highlights the need for implicit display semantics where they are not easily implied. For valid ISO currency codes it is easy to imply how a number must be displayed however not so for other currencies.
This suggests we need a mechanism for the website to provide these semantics to the browser.
Would an additional, optional, property like displayFormat
solve this? It could use ES6 Template Strings
IMO this feels like it's too much for v1. We are talking about edge cases and I don't think we should focus on those right now.
Ian
To be clear, when I say "some mutually exclusive way to say 'this is not represented with an ISO code, but with a different identifier, which is XXX'", it could be as simple as requiring any non-ISO codes to be prefixed with a "+"; e.g:
{
"currency": "+DGC",
"value" : "87000.00"
}
I think non-ISO currency codes should be represented with a URL -- and that URL may, optionally, in the future, provide machine-readable information such as "displayFormat" to allow displayers to discover this information and properly display the currency. This approach allows us to largely ignore this issue for v1, but have a path forward for v2+.
I think non-ISO currency codes should be represented with a URL
I find this approach very appealing. +1
I think non-ISO currency codes should be represented with a URL
:+1:
To be clear, is the suggestion that currency should be either a 3 letter code or a valid URL with the handling of the URL form to be determined in future?
Can I suggest that we allow 3-letter codes that are not necessarily valid ISO codes as these have become very common (XBT, BTC, ETH, LTC, XRP) and are pretty easy to display as is?
For valid codes that the browser recognises (i.e. doesn't have to be valid ISO) the browser may implement appropriate display logic (i.e. for USD display as $ xxx.xx)
@adrianhopebailie,
To be clear, is the suggestion that currency should be either a 3 letter code or a valid URL with the handling of the URL form to be determined in future?
Yes.
Can I suggest that we allow 3-letter codes that are not necessarily valid ISO codes as these have become very common (XBT, BTC, ETH, LTC, XRP) and are pretty easy to display as is?
I'm not opposed to this idea, I just don't know how you say whether or not a code fits into that grouping. Maybe we could specify them.
For valid codes that the browser recognises (i.e. doesn't have to be valid ISO) the browser may implement appropriate display logic (i.e. for USD display as $ xxx.xx)
In terms of spec text this essentially would be something like: "If the currency does not have an ISO code, it SHOULD be represented by a URL" (not a MUST)?
It seems to me unlikely that browsers would dynamically support display of arbitrary strings or other items.
Therefore, they would likely need to have built in the support, and they would have researched how to provide that support. Thus, I think a URL in this situation is not likely to be superior to any other type of string since I doubt strongly it will be dereferenced by either human or machine.
Thus, it seems to me that we don't need to say more than "Treat ISO codes per spec."
Ian Ian
@ianbjacobs,
It seems to me unlikely that browsers would dynamically support display of arbitrary strings or other items.
Payment Apps will also be displaying currency amounts. This isn't a browser-centric design. Browsers could just as easily treat URLs as opaque strings as 3-letter currency codes. If they recognize an opaque string (identifier) then they can do special display for it. This approach should place no burden on a browser but will also not limit the flexibility of Payment Apps.
To be clear, it would be nice if we modeled currency the same way for both Payment Apps and for the browser. That is why I say it's not a browser-centric design.
@ianbjacobs if the URL dereferenced to a document that provided URL's for icons, regex for formatting etc I'd imagine they'd consider using these display hints.
We already have one browser that has expressed interest in the idea.
Ultimately this is just a display concern for the browser, it's the payment app that must actually make sense of the currency so as @dlongley says we should be careful about only thinking about the display considerations.
Can I suggest that we allow 3-letter codes that are not necessarily valid ISO codes as these have become very common (XBT, BTC, ETH, LTC, XRP) and are pretty easy to display as is?
The issue there is that we're going to have some hard problems to solve if Bhutan ever changes their currency to a name starting with "C", or Ethiopia changes their currency to start with "H". I'll admit that it's pretty unlikely that Lithuania will get off the Euro any time soon, but there's still a matter of dealing with the distant future.
It's not elegant, but we can accommodate this set of cases like:
Etsy recently published a nice article about currency display. It's more involved than a simple displayFormat
field. They leverage CLDR dataset formatting patterns for language + region + currency combinations. It would be good if new currencies published similar CLDR data so existing formatting tools could be used.
https://codeascraft.com/2016/04/19/how-etsy-formats-currency/
It would be good if new currencies published similar CLDR data so existing formatting tools could be used.
- 1 @davidlehn - I think we could get to that in future (where the website provides formatting hints to the browser) but for now I think we can keep it simple and follow the proposal from @adamroach above.
@adamroach I like your proposal but would not limit the list of "+" prefixed currencies to a known list.
If the browser is going to simply use the 3 letter code for display then it should accept any 3 letter code.
@adrianhopebailie,
The issue with "any non-standard 3-letter code" is that it can lead to name collisions on the Web.
If we don't worry about that, then drop the URL part of the proposal because we no longer need it.
If we do worry about that, then keep the URL part of the proposal.
Ian
+1 to @ianbjacobs' point, which I was about to make.
I'm hearing @adrianhopebailie say he doesn't care about uniqueness, which would point to option 2.
I think we're going to run into practical issues if an identical code can mean two different things in two different contexts, so I think we need either option 1 or option 3.
+1 to option 1 or option 3
I think we are conflating two issues.
Issue 1 is the need for browsers to recognize the currency identifier so they can provide an appropriate display. That means they need to know what symbol to use, where to put it and how to format the numbers. A lot of this is actually tied to i18n stuff (not just the currency).
Issue 2 is the need to allow the ecosystem to introduce currencies without needing them to be explicitly supported by the browser. What if a merchant wants to sell something with loyalty points tomorrow? It's a regular payment request but where the currency is unknown to the browser. Are we saying we don't allow that.
Issue 2 forces us to support uniqueness because I don't want Bob's Tyreshop Credits to be confused with Bitcoins. But, if we solve Issue 2 by saying that a currency can be specified as URL then how do we solve issue 1?
I believe we should allow 3 letter ISO codes and URLs but then we need a way for requests where the currency is a URL to provide display hints to the browser.
@adrianhopebailie writes:
I believe we should allow 3 letter ISO codes and URLs but then we need a way for requests where the currency is a URL to provide display hints to the browser.
Sure. And that's what @dlongley suggested up-thread: the URL can resolve to a document that describes these display hints. Because, honestly, I'm not sure "XBT" is going to mean much to most people.
This might mean defining at least a primitive (and extensible) format for that document sooner rather than later, but I think that's okay. Clearly we'll want something more advanced eventually, but I think this gets us at least to the property that you're suggesting:
{
"symbol": "BTC"
}
In terms of backward-compatible extensibility, a future version might expand this to look more like:
{
// Default Values
"symbol": "Ƀ",
"mantissaLength": "5",
"position": "prefix",
"spaceSeparator": false,
// Locale Overrides
"en": {
"symbol": ["Bitcoin", "Bitcoins"], // corresponds 'en' to plural forms in Unicode CLDR
"position": "suffix",
"spaceSeparator": true
},
...
}
(This is off of the top of my head, and not an polished suggestion; I just wanted to demonstrate how the format could potentially be expanded).
The one issue I see is that this gets us back to the question of who hosts format documents for currencies that may potentially be quite popular, such as Bitcoin. And that brings us back to the three-pronged approach, where we define non-URL codes for specific, well-known currencies that lack official ISO codes.
PROPOSED:
Rationale:
Ian
To be even more precise: it would be invalid to use a string of (length == 3) unless it is an assigned ISO code.
-1 to undefined behavior. We've gotten away with specifying URLs for identifiers before without having to say exactly what's at the other end when you dereference. Let people experiment with that.
To be even more precise: it would be invalid to use a string of (length == 3) unless it is an assigned ISO code.
+1 to this -- if we don't, could be a pretty financially costly mistake when ISO defines a code that was in use w/this API as some other non-ISO currency.
I still think we should be using ISO or URLs -- what if ISO adopts four letters in the future? I doubt they will adopt URLs, but if they do, that's not a problem. This is the Web -- we should be using URLs for identifiers.
@adamroach,
To be even more precise: it would be invalid to use a string of (length == 3) unless it is an assigned ISO code.
Agreed.
@dlongley,
We've gotten away with specifying URLs for identifiers before without having to say exactly what's at the other end when you dereference. Let people experiment with that.
Specifying URLs without specifying what happens does not increase likelihood of interop. I don't think this WG should specify what you find at the end of these URLs.
Therefore I want to enable URLs (for experimentation) but not go so far as to require that all "other" strings be URLs.
Ian
@ianbjacobs
Specifying URLs without specifying what happens does not increase likelihood of interop.
Sure, but it eliminates the chance of collisions.
@adamroach,
Sure, but it eliminates the chance of collisions.
Anyone who wants to avoid those collisions can do so by using URLs.
Summary: I think requiring all unknowns to be represented by URLs would be premature at this point. By saying "undefined" now we can do two things:
Ian
We ran out of time discussing this on 19 May.
Summary of discussion is:
For version 1:
I think in v1 we should just have payment mediators (e.g., browsers) innovate with respect to displaying unknown currencies. They can provide a link to click on, they can indicate that the currency may be displayed in their Payment App -- or something more clever. In the future we can define machine-readable properties that can be retrieved from currency URLs to get display information.
@dlongley
I think in v1 we should just have payment mediators (e.g., browsers) innovate with respect to displaying unknown currencies...
If the identifier is potentially a URL and there is no structure or other information to indicate what a human might call the currency, this may not be something that can be done sensibly. I'm trying to imagine our UX folks' response to this "well, just innovate!" suggestion, and... the discussion I envision doesn't go well.
@adamroach,
If the identifier is potentially a URL and there is no structure or other information to indicate what a human might call the currency, this may not be something that can be done sensibly. I'm trying to imagine our UX folks' response to this "well, just innovate!" suggestion, and... the discussion I envision doesn't go well.
What would implementations do if they could not, for whatever reason, retrieve the display information from a currency URL that was never previously retrieved and was not well-known? This case still has to be considered as it may occur even if we are to specify how to model the display information. I don't think the ability to pay should be denied, particularly if as soon as the Payment App is selected, the Payment App may be aware of the currency and be able to render it appropriately.
Ian
I don't think we can leave this with no hints for the browser about how to display non-standard currencies. I am 👎 to what's been proposed so far until we can address that.
I believe that “how to display non-standard currency” is both low priority (since by definition an edge case) and also beyond the remit of this group (notably, according to our charter we should not be defining UI).
I distinguish “how to display something” from “information necessary so that a user agent can make display decisions.” I think there will be some cases where we do the latter, but “how to display” sounds like the former to me.
The proposal to does not prevent anybody from providing hints (e.g., via URI or something else if people want).
I would be fine with some informal text (outside the spec) that we can develop as good practice based on what people do.
Ian
@ianbjacobs said:
distinguish “how to display something” from “information necessary so that a user agent can make display decisions.”
This is splitting hairs. Call it what you will, our API doesn't fully support non-standard currencies unless we provide a way to help implementors displayed them properly to users so I wouldn't consider this low priority.
I don't consider a hard-coded short-list as support when there are hundreds of crypto-currencies in use today and new ones being invented all the time.
There are two ways we can do this:
I don't see the group agreeing to 2 and I don't think we have a good proposal for 1 yet.
@adrianhopebailie ,
Call it what you will, our API doesn't fully support non-standard currencies unless we provide a way to help implementors displayed them properly to users so I wouldn't consider this low priority.
I want to distinguish:
I don't want to prevent people from being able to deal with it. I just don't think we should specify:
I think we should allow for some experimentation here before we say "It MUST be a URL if it's not a three-letter ISO code."
I don't consider a hard-coded short-list as support when there are hundreds of crypto-currencies in use today and new ones being invented all the time.
I can live without the hard-coded list.
Ian
+1 to not specify how to display currencies.
From standpoint of validation, I preferred "[A-Z]{3}" for currency codes. However, I am OK with free-form strings, including URLs, if the community decides that's for the best. I would prefer some length limit, if possible. How about 2048 bytes?
As far as URLs go, it would be nice to present them uniformly across browser vendors. However, presentation is largely out of scope of this specification. A non-normative note would be OK, right? Something like, "If the currency code is a URL, the user agent MAY enable opening the URL for the user to inspect."
+1 to not specify how to display currencies.
My preference would be to keep things simple and go with something like "[A-Z0-9]{3-10}" (similar to @rsolomakhin's preference, but allowing for the often longer symbols in this list).
-0.5 to mandating URLs for non-ISO symbols (although, like @rsolomakhin, I'm ok with free-form strings that might happen to be URLs).
I honestly believe that the problem of currency symbol conflict is not our job to solve. As long as the merchant has a way to pass a currency symbol to the payment app, the burden is upon them to agree what that symbol means, and the burden is upon the mediator to present this in a user-friendly way. At least for v1, I would prefer to not overcomplicate this.
@ianbjacobs said:
How to display non-standard currencies (which I'm sure is a huge topic that I continue to think is out of scope)
This is in scope because the spec defines features that require implementors to display amounts (display items, shipping costs, etc). The ecosystem can't use non-standard currencies as a result of the mediator having a requirement to display amounts.
In an ideal world the only entities that need to understand what a non-standard currency identifier means would be the merchant and payment app but we've made the decision to put pricing UI in front of users as a feature of the flow so we need to define how that UI should handle non-standard currencies. At a minimum we should provide guidance so that we increase the chances of this being done consistently across implementations.
The only reason we don't have to do this for standard currencies is because it's already done so we trust the browsers to simply use the existing guidance.
If we leave this out then the exact same checkout experience on two browsers would be completely different. Imagine a payment request for 1 bitcoin that is rendered to the user in any one of the following ways depending on which browser they use:
From an interoperability perspective the spec has failed.
I think we should allow for some experimentation here before we say "It MUST be a URL if it's not a three-letter ISO code."
I am not saying we need to say the identifier has to be a URL, that is a separate issue. I am saying that whatever we use for identifiers for non-standard currencies needs to be accompanied with a mechanism to help the user agent with display of amounts in that currency so that browser will can be consistent.
Or, as @rsolomakhin said
As far as URLs go, it would be nice to present them uniformly across browser vendors
@tommythorsen said
I honestly believe that the problem of currency symbol conflict is not our job to solve. As long as the merchant has a way to pass a currency symbol to the payment app, the burden is upon them to agree what that symbol means
👍 - although I think you mean currency identifier not symbol?
The problem here is how we decide what is shown to the user before the request gets to the app?
the burden is upon the mediator to present this in a user-friendly way.
👍 - although we should provide a way browsers to do this consistently (per @rsolomakhin above)
@adrianhopebailie,
but we've made the decision to put pricing UI in front of users as a feature of the flow so we need to define how that UI should handle non-standard currencies.
We are not specifying any display behavior for any currency, however that currency is identified (ISO Code or otherwise).
@tommythorsen said:
the burden is upon the mediator to present this in a user-friendly way.
@adrianhopebailie said:
👍 - although we should provide a way browsers to do this consistently (per @rsolomakhin above)
@rsolomakhin's next sentence is "However, presentation is largely out of scope of this specification. "
I believe it would be a major rathole for this group to go down the path of actually specifying "how to display various currencies." If we do not have confidence that people will frequently use these URLs to find useful information about how to display currencies, that REQUIRING a URL for any non-ISO currency is too strong of a requirement.
I think the odds of a currency name conflict are low, because I expect people work hard to avoid such name conflicts. Therefore URLs would likely be overkill as identifiers. Furthermore, if there were name conflicts in the industry, it would certainly not be our job to explain (in some dereferenced information) how to resolve those conflicts. And I agree with @tommythorsen that "...the problem of currency symbol conflict is not our job to solve."
This is why I think (for non-standard currency codes) I am most comfortable with:
Ian
@ianbjacobs,
We are missing each other here. You are quoting only parts of what I am saying and those statements are being interpreted out of context.
We are not specifying any display behavior for any currency, however that currency is identified (ISO Code or otherwise).
Correct. But, as I have already said, user agents already have guidelines about how to display standard currencies so providing display hints is not required for these. If we don't provide a way for developers to pass display guidance to the browser for non-standard currencies then how will browsers ever do this consistently?
In triaging this issue I looked at what has been said to date and my conclusion was:
I don't think we can leave this with no hints for the browser about how to display non-standard currencies. I am 👎 to what's been proposed so far until we can address that.
Nothing anyone has said since, has proposed a way to:
so my conclusion in evaluating this issue is that it still requires further proposals.
@adrianhopebailie wrote:
I AM saying that we need to define a way for someone who mints a new currency identifier (i.e. non-standard) to also be able to provide display guidance to a user agent.
I don't think you are saying that because "leaving the meaning up to the community" fulfills that requirement.
I think you want us to define a STANDARD way to communicate how to find hints. This is also suggested when you wrote: "... how will browsers ever do this consistently?"
I would not prioritize solving that problem in v1. I DO support people being able to communicate via the field and learning what communications patterns emerge, possibly for future standardization.
I believe we have (at this point) understood each other's views. I'm not yet convinced we need to create a standard way to communicate information about where to find display hints (however those happen to be defined, which I believe we agree should not be us).
Ian
I believe we have (at this point) understood each other's views.
Yes, but I don't think we agree 😄
If we leave this to the community then I think we risk a lot of fragmentation in how browsers do this. We have the right forum here to put forward good proposals on solving this problem now because trying to fix it later will be harder.
We have had one proposal to use a file, at the URL of the currency identifier as the mechanism. The group appears to dislike this approach so I am appealing for alternative proposals.
I've been thinking about this over the weekend, and I have the following opinions:
displayFormat
" near the start of this thread, and I think that would be the way to go. Such a property would fit well inside the CurrencyAmount dictionary.An interesting thought experiment is that if we say amounts are defined per payment method then this becomes much easier (potentially) - see #4
Unusual currencies will likely be specific to a payment method so the payment method spec would define what currency identifier to use and we also have far less chance of conflicts (so no need for URLs).
The challenge remains, how to display amounts in that currency. For this I think we need input from the browsers how they would display amounts if there were different amounts per payment method because that could impact this question.
If a payment request has the following data:
Payment Method | Currency | Amount |
---|---|---|
Debit Card | USD | 1 |
Credit Card | USD | 1.10 |
Bitcoin | BTC | 0.00001 |
Store Loyalty | Points | 1000 |
And the user has 3 payment apps installed
Payment App | Supported Methods |
---|---|
App 1 | Debit Card, Credit Card |
App 2 | Bitcoin |
App 3 | Bitcoin, Debit Card |
App 4 | Store Loyalty, Credit Card |
Perhaps the answer is that the request MUST specify a reference amount in a currency that uses a 3-letter code (ISO or not, it doesn't matter). This is used for display in the items list and where there is a different currency/amount per app this is displayed in the app selector BUT if there is more than one possible amount for an app then no amount is shown.
We need input from the browsers how they would display amounts if there were different amounts per payment method/
I would like to give a payment app the ability to provide detailed information about the ways in which the user can pay, a.k.a. instruments. When I say "instrument", I only mean a way to pay with a payment app.
An instrument can be as broad as "App 3" and as narrow as "Bitcoin account X in App3". An instrument includes such information as an id, a label, an icon, the way to invoke the payment app, and a non-empty list of payment methods.
For example, "App 3" instrument can specify ["bitcoin", "visa/debit"]
methods. Given this information, a user agent can present a list or range of prices to the user in the selector UI. (Ranges for same currency, lists for different currencies.)
Payment | Price |
---|---|
App 1 | USD $1.00-1.10 |
App 3 | BTC 0.00001, USD $1.00 |
Alternatively, "App 3" app can provide two instruments: "Bitcoin wallet X in App 3" with ["bitcoin"]
method and "Debit card Y in App 3" with ["visa/debit]
method. Then price can be displayed one-per-row, without ranges or lists.
Payment | Price |
---|---|
Debit card A in App 1 | USD $1.00 |
Credit card B in App 1 | USD $1.10 |
Bitcoin wallet X in App 3 | BTC 0.00001 |
Debit card Y in App 3 | USD $1.00 |
@rsolomakhin - this is an interesting idea and might be a good way of thinking about this because it allows the app to present it's installed "instruments" to the browser during app registration which allows the browser to show these to the user before the app is invoked.
i.e. The user knows before picking the app which payment instrument they will use (less chance of picking an app and then realising you wanted to use your XYZ card but that's stored in another app etc) but doesn't leak any data to the website.
If you look at the PaymentApps proposal there is a proposed format for app data during registration that includes things like the app name, the URL used to invoke the app etc.
I can imagine that we could change the enabled_methods
property to take a sequence of PaymentInstrument objects defined like this:
dictionary PaymentInstrument {
required sequence<DOMString> supported_methods;
required DOMString name;
required URLString icon_url;
};
dictionary PaymentApp {
required URLString start_url;
required sequence<PaymentInstrument> payment_instruments;
}
So registering an app would look something like:
navigator.payments.registerPaymentApp({
start_url: "https://app3.com/payment_app/endpoint",
payment_instruments: [
{
supported_methods: ["bitcoin"],
name: "Bitcoin Wallet in App 3",
icon_url: "https://app3.com/payment_app/bitcoin_icon.svg"
},
{
supported_methods: ["debit-card"],
name: "Debit Card Y in App 3",
icon_url: "https://app3.com/payment_app/debit_icon.svg"
},
]
});
@tommythorsen --
...three-or-more-letter currency codes (USD, NOK, BTC, DOGE, etc.)...
We seem to be drifting away from the premise that three-letter alphabetic codes must be ISO currency codes, which is something I thought we had good agreement around.
I'm not too stuck on any other aspects of this design, but without that constraint, I'm afraid that we're going to run into serious problems down the road (for the reasons mentioned earlier in this thread).
We seem to be drifting away from the premise that three-letter alphabetic codes must be ISO currency codes, which is something I thought we had good agreement around.
I propose that three-letter alphabetic codes that are official currency codes should be treated as such. We can also allow unofficial three-letter alphabetic codes. For example: BTX (bitcoin).
I have some concerns with being able to sensibly render line items, especially with the “currency” field being effectively free-form (the current version says that it may be but does not have to be an ISO currency code).
Simply stated, no one using a US locale checking out from a US store expects to see “58.73 USD,” and this will certainly confuse some people. They’ll want to see “$58.73”. But if there’s no hard-and-fast convention about what “currency” means, then rendering this sensibly will be difficult. So, minimally, I think we need to say that anything that matches an ISO code is guaranteed to be that currency.
Without strictly requiring the currency code to be an ISO-registered value, though, this becomes problematic: any other three-letter code effectively becomes “squatting” in the space, and runs the (admittedly small but nonzero) chance of being later allocated by ISO. Which means that what we really want is some way to say “this is the ISO code for a currency”, and a mutually exclusive way to say “this is not represented with an ISO code, but with a different identifier, which is XXX.”
There's probably more thought to be given to these non-ISO identifiers in terms of renderability, but I'm mostly worried about the conventional currency cases to start with.