Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why URLs? #9

Closed
annevk opened this issue Aug 11, 2016 · 47 comments
Closed

Why URLs? #9

annevk opened this issue Aug 11, 2016 · 47 comments

Comments

@annevk
Copy link
Member

annevk commented Aug 11, 2016

We have learned a couple times that using URLs for identifiers is not the best. What's the justification?

@adrianhopebailie
Copy link
Contributor

The intention is to use URIs (not URLs) but this of course means URLs are also allowed.

The group will use URNs for identifiers of payment methods that are specified by the WG as these are "generic" and there may be multiple payment apps that could implement these methods.

However we want to leave the door open for other to develop their own payment methods that are not generic and may be specific to a single payment app. In this case the publishers may wish to use URL identifier that points to a resource like their homepage, the registration page for the app or a manifest for the app.

We haven't explicitly defined what this URL should point to (if it's a URL) until we get some indication from the market of what it may be used for.

@annevk
Copy link
Member Author

annevk commented Aug 12, 2016

o_O

@adrianhopebailie
Copy link
Contributor

o_O

Is that technical term? Not sure what it means?

@msporny
Copy link
Member

msporny commented Aug 12, 2016

Is that technical term? Not sure what it means?

@annevk is probably surprised that we're saying that organizations may use URLs to identify payment methods, but are not defining what should be at the end of those URLs, if anything, and we're punting that decision to "the markets". Waiting for the market to sort it out will almost certainly result in strange backwards-compatible hacks that implementations will have to do in the future to prevent breakage.

Thus, this - http://www.urbandictionary.com/define.php?term=o_O

Welcome to the Web Payments WG, @annevk, where architecture and fully defining things are an anti-pattern. :P

PS: That was a joke... mostly.

@tabatkins
Copy link
Member

tabatkins commented Aug 12, 2016

More fully expanding on @annevk's and @msporny's comments:

URLs are a terrible anti-pattern for identifiers, as has been proven over and over and over again every single time someone tries to use them as such. The canonical anti-example is XML namespaces, but every use suffers from the exact same problem, which is that identifiers want to be opaque strings, but URLs are not opaque strings to humans. URLs come with meaning, and with forgiveness in how precisely one can write it. In particular, most humans would consider all of the following to be "the same URL":

Using URLs also encourages people to make those URLs resolvable. Most of the time the people suggesting this seem to think this is a good idea (as you seem to, with your comment that "the publishers may wish to use URL identifier that points to a resource like their homepage, the registration page for the app or a manifest for the app."). Again, many experiences over the years shows that this is a very bad idea, for multiple reasons:

  • Sometimes URLs become extremely popular, and tools end up effectively DDOSing the endpoint (the W3C has had to spend significant effort/expense making their servers capable of handling all the requests coming in for namespace URLs).
  • Business URLs change. They switch to https, or the company name changes and they change their domain to match, or the company dies and someone else uses the URL, but the service the previous business started is still used. (There's been pushback from important/respected parts of the Semantic Web community against the "use HTTPS everywhere!" mandate, because it changes urls and the namespace & identifier URLs they were using in their ontologies are no longer "correct".)
  • More specific urls (to particular endpoints within a server) change commonly, especially if they don't actually do anything but maybe serve some explanatory text.
  • Even dedicated "live-forever namespace URLs" services die. There are a few that have stood up for years, but plenty of others that have died and been forgotten.

The only reason to use URLs is that it's a globally unique name registry that someone else is already spending the effort to maintain. But that's seriously not a big deal; for all but the most prolific services, running a name registry is trivial and cheap. You can get vastly better ergonomics just by doing it yourself (or having the W3C do it).

@adrianhopebailie
Copy link
Contributor

@annevk , @tabatkins thanks for joining this conversation, we're at a key point in figuring out this aspect of the payment API design so getting some fresh eyes is valuable.

We made the decision a while ago that we didn't want to use linked-data to express the data models used by the API and I think using URLs as identifiers is left over as a compromise from that debate.

The group is currently considering the following proposal [1] from @zkoch which changes a lot of what we had decided before and introduced the use of URNs as an alternative.

That said, there are some bootstrapping use cases that I believe @zkoch has in mind where using a URL is useful. In some instances there is only one payment app that can be used for the payment method and the URL can be used to "get" the payment app .

What's not yet clear is what "get" means because we are still defining the payment apps API. It could mean download, it could mean register, it could be a manifest etc.

@zkoch and @adrianba have pushed for the payment request API [2], payment apps API[3] and payment method identifiers spec[4] to be defined separately so in some cases we need to leave things "undefined" in one place while we figure out the details in another.

The group is not planning to progress any one of these specs to CR until they have all stabilized so our expectation is to get feedback from "the market" (i.e. people that may publish payment apps) before then and not leave this entirely open to interpretation (and therefor fragmentation).

[1] https://github.com/w3c/webpayments/blob/gh-pages/proposals/zach-pmi.md
[2] https://w3c.github.io/browser-payment-api/
[3] https://w3c.github.io/webpayments-payment-apps-api/
[4] https://w3c.github.io/webpayments-method-identifiers/

@zkoch
Copy link

zkoch commented Aug 15, 2016

Thanks for bringing this up again. We're looking at this spec again right now, so it's the ideal time to have the discussion.

I agree that there are numerous downsides to URLs. We went through all of the various possibilities before settling on them as the mechanism for identifying payment methods.

It probably is worth reading the proposal we're currently considering. When we think about payment methods and how we identify them, we lump them into two categories: "open" and "proprietary".

Open payment methods are ones that can be standardized by the W3C, and for those we are relying on URNs, so many of the issues outlined above by Tab go away for these types of methods. The WG will most likely contain a registry of these different payment methods (e.g. urn::w3c-payments::basic-card).

The second type, however, are proprietary payment systems. These are oftentimes closed-loop systems where only a single player can return back valid credentials (e.g. PayPal, Visa Checkout, etc). For these players, we rely on URLs. There are a few reasons for that:

  • There are many different proprietary payment methods out there, and it's not reasonable to ask those payment method providers to have to go through some W3C process (even if we make it light weight) to get an identifier into our registry that makes their method available inside of PaymentRequest. The more difficult we make this, the fewer payment apps we see on the market. The fewer payment apps available, the less adoption we see of PaymentRequest. To put this another way, payment method innovation should not be limited by W3C processes.
  • URLs allow us to make assertions about identity and ownership. If I say I support "https://bobpay.xyz", there's no ambiguity about ownership of that payment method. It also allows us to link method identifiers with apps installed on a user's device. So if user has BobPay installed on the device, we can open up the BobPay application instead of using a website. There are already systems in place to make this assertion. This also affects things like Risk and Assurance in the world of interchange.
  • Something can (and should) live at the end of the that URL (e.g. a manifest file) containing information about that payment method. That information can be updated over time if things change. It also allows for additional assertions to be made (e.g. In addition to BobPay.xyz being able to return back BobPay.xyz credentials, we also authorize AlicePay.xyz to return back valid BobPay.xyz credentials). This is another critical use case in the world of payments. But by default, unless this assertion exists, no one else can claim to return back BobPay.xyz credentials.
  • When something lives at the URL, it also allows us to kill the proverbial birds with a single stone. From a UX perspective, if the users doesn't yet have a payment app installed but would like to use it (e.g. PayPal.com), the user can choose PayPal from a list and we can fetch information on-demand about PayPal if it's a URL. But more importantly, there are numerous financial agreements that require certain payment methods to be listed irrespective of a user's preference. So quite literally these payment methods pay money to the merchant to list their method. This means we have to have a system that allows users to pay with those options even if they don't have them installed if we want the merchant to be able to fully use PaymentRequest.

Given the above, URLs seemed to be the best path forward (even if I agree with all your points). There are just certain use cases that seem to necessitate the use of URLs. That said, if you think we can meet those needs without that, great! More than happy to revise my proposal for an alternate method.

Also, FWIW, I don't agree with this assessment:

...but are not defining what should be at the end of those URLs, if anything, and we're punting that decision to "the markets".

Up to this point, I have not been terribly active in the payments app world (though that should change this week), as I'm focused on getting PR out the door. But I do not see any value in leaving this to the markets. We can and should define what lives at the end of these identifiers and make it a part of the process. If we don't, then I agree that URLs as identifiers become less valuable.

@msporny
Copy link
Member

msporny commented Aug 15, 2016

Also, FWIW, I don't agree with this assessment

To be clear, I was summarizing what I've heard @adrianhopebailie say a few times, namely:

We haven't explicitly defined what this URL should point to (if it's a URL) until we get some indication from the market of what it may be used for.

Like @zkoch, I also agree that NOT defining what should be at the end of the URL and letting the markets decide would be a mistake.

@ianbjacobs
Copy link
Contributor

@zkoch wrote:
"We can and should define what lives at the end of these identifiers and make it a part of the process."

Several ideas have been floated for what dereferencing a PMI returns:

1 Payment method spec
2 Metadata about the payment method (e.g., for registration)
3 Information about a payment app

It sounds from this thread like the second one is what you are currently thinking. Is that correct? (We can take this to another issue, no problem.)

Ian

@zkoch
Copy link

zkoch commented Aug 15, 2016

It sounds from this thread like the second one is what you are currently thinking. Is that correct? (We can take this to another issue, no problem.)

I want to be brief as not to detract from the key point of this conversation, but the answer (to me) is both (2) and (3).

But let's discuss elsewhere and focus this conversation on whether or not to use URLs.

@tabatkins
Copy link
Member

Open payment methods are ones that can be standardized by the W3C, and for those we are relying on URNs, so many of the issues outlined above by Tab go away for these types of methods. The WG will most likely contain a registry of these different payment methods (e.g. urn::w3c-payments::basic-card).

Using URNs is overengineering for no benefit. They're intended for global identifiers that can appear in many contexts, so the extra information is useful in identifying them. Here, tho, it's merely an enum used in an API. You can drop literally all of that but the last identifier (basic-card) and get exactly the same benefits with vastly improved usability. URNs are not used in this way anywhere else in the entire web platform, for precisely this reason - they add nothing but line-noise for these types of cases.

There are many different proprietary payment methods out there, and it's not reasonable to ask those payment method providers to have to go through some W3C process (even if we make it light weight) to get an identifier into our registry that makes their method available inside of PaymentRequest.

Looking over PaymentRequest, I'm not clear what 3rd-party payment methods even do. The browser is supposed to "supply a UI" for the payment method, but I can't tell how it's supposed to do so for an arbitrary unknown payment method. Is there some sort of interpolation based on the fields in the PaymentMethodData? Are we assuming that browsers will just know about a bunch of 3rd-party methods and know what sort of UI to generate for them? (If so, then this is ripe for at least light standardization. A simple registry of what kind of information to collect is a very low-friction way to promote interoperability.)

URLs allow us to make assertions about identity and ownership.

URLs don't, origins do. Apps can have origins associated with them. If this is a goal (and it sounds reasonable at first blush), requiring that the URL not include any path data or fragment, and then just looking at the origin for identification, is a reasonable approach that is closer to matching with how people think of URLs. (It still doesn't help the http://example.com vs http://www.example.com problem, but eh.)

Something can (and should) live at the end of the that URL (e.g. a manifest file) containing information about that payment method.

If this is desired, then we must define exactly what it is that lives there, and require something there. If it's optional, it will be left out (or website reorgs will accidentally kill it), and things will continue to silently work.

But more importantly, there are numerous financial agreements that require certain payment methods to be listed irrespective of a user's preference.

This is a reason to allow arbitrary payment types, but it has nothing to do with how those payment types are identified.

@ianbjacobs
Copy link
Contributor

@tabatkins wrote:

"Looking over PaymentRequest, I'm not clear what 3rd-party payment methods even do. The browser is supposed to "supply a UI" for the payment method, but I can't tell how it's supposed to do so for an arbitrary unknown payment method."

We're working on third-party payment apps separately. We have a draft in progress, not yet taken up as a FPWD:
https://w3c.github.io/webpayments-payment-apps-api/

Ian

@tabatkins
Copy link
Member

Okay, so this suggests that 3rd-party methods are always indirected thru apps, and thus origin information is what you need. (Or theoretically thru a Service Worker, where again origin-level is the correct way to go; sub-origin scoping is not a security boundary for SWs, and is considered to be a legacy mistake.) Right?

@zkoch
Copy link

zkoch commented Aug 16, 2016

Using URNs is overengineering for no benefit.

This is a fair point. We settled on URNs so we could make the statement that all payment method identifiers are URIs. The extra boilerplate seems minimal and low cost to me, but curious what others think. I could be persuaded to go with a simple string.

URLs don't, origins do. Apps can have origins associated with them. If this is a goal (and it sounds reasonable at first blush), requiring that the URL not include any path data or fragment, and then just looking at the origin for identification, is a reasonable approach that is closer to matching with how people think of URLs.

Yes, agreed on origin. There are a few additional values to using URLs over origins:

  1. It allows for multiple payment methods to exist at a single origin. There are a few uses cases where this is relevant, but I'd be okay saying that they need to get a unique origin for each payment method (easy enough with method1.domain.com and method2.domain.com).
  2. It seems more semantic at times to have path support. Take Android Pay for example. A payment method of "android.com" doesn't make sense. But a payment method of android.com/pay does make sense. It does seem a bit excessive to demand a subdomain to get the same semantic benefit that paths offer.
  3. Easy versioning support (e.g. bobpay.xyz/payment-method/v1/). Again, subdomains could work here, but same potential issue.

If this is desired, then we must define exactly what it is that lives there, and require something there. If it's optional, it will be left out (or website reorgs will accidentally kill it), and things will continue to silently work.

Yes.

This is a reason to allow arbitrary payment types, but it has nothing to do with how those payment types are identified.

No, there's a relationship. If we're going to show it, we have to be able to support it. If all we have is an identifier, we can't support it. This goes back to the above point where something has to exist at the end of that URL that can be de-referenced. But I agree that if we use origins or URLs, we really need to specify what must exist at the end of that URL.

@tabatkins
Copy link
Member

This is a fair point. We settled on URNs so we could make the statement that all payment method identifiers are URIs. The extra boilerplate seems minimal and low cost to me, but curious what others think. I could be persuaded to go with a simple string.

This is an argument based on spec simplicity, which is very wrong. Per the Priority of Constituencies (user > author > implementor > spec), spec simplicity is one of the lowest things to value. You should be optimizing for author usability here.

Yes, agreed on origin. There are a few additional values to using URLs over origins:

None of these reasons seem to be compatible with communicating with apps, which have an associated origin. Multiple payment methods should indeed be suborigins (a trivial cost compared to actually running a second payment method server), and versioning can either be suborigins or communicated in the PaymentMethodData.

No, there's a relationship. If we're going to show it, we have to be able to support it.

Right, but whether or not it's a URL has nothing to do with that. There are many ways to potentially support open-ended payment methods. In particular, it looks like y'all are supporting them via apps, which can be identified by an associated origin, rather than a full URL. That's what I'm trying to say.

@dlongley
Copy link

If these identifiers aren't intended to be used on the Web, but rather they are only ever going to appear in a JavaScript browser API as a simple enumeration, then I agree that they should just be simple strings. If the intent is for payment methods to fit into a larger Web Payments Architecture where they may be referenced in various payment-related messages on the Web, then a Web-based identifier is more appropriate.

@adamroach
Copy link

I think what is getting lost in this conversation -- especially for those who haven't been following the discussion for the past several months -- is that these URLs are just identifiers. They don't have security properties associated with their origins.

Backing up: what we want is a delegation model that allows third parties to mint new, guaranteed unique identifiers for their payment methods (NOTE: PAYMENT METHODS, NOT PAYMENT APPS -- there is an n-to-m mapping of methods to apps) without having to interact with the W3C in order to do so. URLs are an easy way to go about doing so, although other things would work as well. If the WG is willing to take the assertion that URLs are an anti-pattern due to their historical baggage (e.g., ability to resolve, incorrect assumptions around equality), then we can consider other approaches to achieve the same goal. Some approaches might include:

  • URNs, with a subdelgation model underneath the top level. E.g., W3C-issued URNs would be something like urn:payment:w3c:basic-card, while any third party could use an issued, fully-qualified domain under payment: urn:payment:bobpay.com:bobpay1
  • Basic strings for W3C-issued values (e.g., basic-card), and some other format for third parties; e.g.:
    • UUIDs for third-party values (e.g., {f3653ce8-048e-4a17-81b9-73ecdc03daf5} for "bobpay v1"
    • Strings qualified by domain name for third-party values (e.g., bobpay.com|bobpay1)
    • To avoid the concerns of domains being re-issued, we could use strings qualified by some other unique, per-organization value for third-party values (e.g., if we used enterprise numbers : 24829|bobpay1)

Now, I'm also hearing that the ability to resolve these identifiers is a desired feature, although opinions seem to vary on what exactly that feature is. I think we need to have a much better view about exactly what the goals of resolution are before we take that on as a requirement that constrains our choice.

@tabatkins
Copy link
Member

If these identifiers aren't intended to be used on the Web, but rather they are only ever going to appear in a JavaScript browser API as a simple enumeration, then I agree that they should just be simple strings. If the intent is for payment methods to fit into a larger Web Payments Architecture where they may be referenced in various payment-related messages on the Web, then a Web-based identifier is more appropriate.

URNs aren't web-based, they're an opaque string that (purposely) happens to vaguely resemble URL syntax. They don't resolve to anything and have no intrinsic meaning. Their only benefit over a simple enumeration is that they carry around a namespace label that helps identify what they're for when you see them out of context; this is particularly true for URNs where the payload is just a number or other meaningless identifier. That's not the case here - the keywords have human-readable names, and aren't expected to be shared widely in any sense or be seen out-of-context of a particular API (unlike, say, ISBN numbers). URNs are thus purely downside due to increased verbosity.

I think what is getting lost in this conversation -- especially for those who haven't been following the discussion for the past several months -- is that these URLs are just identifiers. They don't have security properties associated with their origins.

That's not what's being lost, that is literally what we're saying is a bad idea. If you're not using a URL as a URL, you're doing something that has been proven many times in practice to be a mistake.

Now, I'm also hearing that the ability to resolve these identifiers is a desired feature, although opinions seem to vary on what exactly that feature is. I think we need to have a much better view about exactly what the goals of resolution are before we take that on as a requirement that constrains our choice.

Yes. "Maybe they'll resolve to something useful" is, again, an anti-pattern we've seen many times that causes nothing but pain for no benefit. If you don't define precisely what's on the other end (and make that thing do something useful, such that screwing it up or killing it will hurt), the endpoint will devolve to utter trash very quickly, and make it very difficult or impossible to ever use for anything in the future. Use precisely what you need, and no more, of the URL stack: plain identifiers from a registry if all you need is a way to uniquely identify things; plain origins if you just need it for a reasonable security/identity boundary that's shared across web and apps (and is obviously not meant to be resolved, since it's just pointing at a homepage); or URLs if and only if you're actually using what's at the end of the URL for something worthwhile, such that people will notice if they screw it up.

Backing up: what we want is a delegation model that allows third parties to mint new, guaranteed unique identifiers for their payment methods (NOTE: PAYMENT METHODS, NOT PAYMENT APPS -- there is an n-to-m mapping of methods to apps) without having to interact with the W3C in order to do so.

By "without having to interact with the W3C", I presume you're trying to say something like "without having to go through an annoying/arduous beaurocratic process that takes a nontrivial amount of time". There's no reason it has to be like that! A registry can literally just be a text file in a well-known location that your group updates on request - it's a 5-minute email/edit/commit process. You don't have to publish a new spec version every time you update a registry.

Something that I'm still somewhat missing, tho (I thought I had it, but you're implying something different) is what does this unique identifier do? @ianbjacobs suggested that its purpose (as an origin) was to tell the browser what app/SW to boot up to handle some custom payment method. I can understand that, tho it could really do with some better explanation in this spec. In that case it's not really a "unique identifier" at all; that is, it couldn't be replaced by a GUID. It's a very specific and meaningful message that gives the browser directions on how to act.

Is this true? If not, what part is wrong, and how? Arbitrary extensibility is hard to get right; there's a lot of terrible dead-ends in existence that work quite badly, but little indication of what the right ways to do it are.

@adamroach
Copy link

@tabatkins:

Something that I'm still somewhat missing, tho (I thought I had it, but you're implying something different) is what does this unique identifier do? @ianbjacobs suggested that its purpose (as an origin) was to tell the browser what app/SW to boot up to handle some custom payment method. I can understand that, tho it could really do with some better explanation in this spec. In that case it's not really a "unique identifier" at all; that is, it couldn't be replaced by a GUID. It's a very specific and meaningful message that gives the browser directions on how to act.

It's a point of rendezvous between a payment requester and a payment app. The general lifecycle looks like this (although I'm eliding some details, like the difference between "installed" and "enabled" apps):

  1. User visits a website that hosts a payment app (e.g., bankofphobos.com, bobpay.com, big-online-store.com)
  2. The payment app registers with the browser, saying "I can support the payment methods x, y, and z" (where x, y, and z are the payment method identifiers we're currently discussing).
  3. Steps 1 and 2 can be repeated an arbitrary number of times with different payment apps, each supporting different sets of payment methods.
  4. At some later time, the user goes to a merchant site. It says something like "I need $78, and can accept payment methods a, b, and z".
  5. The browser looks at all the registered apps, finds the ones that can provide payment via any of the methods a and/or b and/or z, and displays them to the user. This includes the app we talk about above, since it supports z.
  6. After the user selects a matching app, the browser passes the merchant's payment request along to the payment app so that it can be processed. The payment app's response is sent back to the payment requester.

So, payment method identifiers are literally just unique identifiers that identify a means of payment (schema, behavior) between a payment requester and a payment app. Quite literally anything that is globally unique will work. GUIDs would be technically fine, although they are pretty developer-unfriendly.

@zkoch
Copy link

zkoch commented Aug 16, 2016

So, payment method identifiers are literally just unique identifiers that identify a means of payment (schema, behavior) between a payment requester and a payment app. Quite literally anything that is globally unique will work. GUIDs would be technically fine, although they are pretty developer-unfriendly.

I'm not sure I necessarily agree with this. There are situations where this is true (e.g. basic_card), but it does not necessarily hold true for proprietary payment schemes. BobWallet.com can not arbitrarily say it supports AlicePay.com if AlicePay.com is a proprietary payment system. It just can't work. So there has to be some mechanism by which the payment mediator can validate this statement. This is why payment method identifiers are identifiers, but they can't just be identifiers. Something has to live at the end of that.

We've just tried to solve this problem in steps. We pushed for URLs because we were pretty sure we would need something machine readable to live at the end of that URL that we could get. I realize Tab is trying to say that we shouldn't agree to use URLs until we agree what should be at the end of them, but I'm not sure that is necessarily true. But we probably should get consensus in the group that something should live at the end of that URL before agreeing to use URLs.

@dlongley
Copy link

BobWallet.com can not arbitrarily say it supports AlicePay.com if AlicePay.com is a proprietary payment system. It just can't work.

Playing devil's advocate -- that doesn't mean we necessarily have to do anything about it. The user will just have a bad experience with that Payment App when it doesn't work ... and probably uninstall it.

@adamroach
Copy link

@dlongley beat me to it. If an app claims to support a payment method but cannot satisfy the needed behaviors, then the users will quickly learn to distrust it, and probably uninstall it. this seems like a problem that will work itself out.

@adamroach
Copy link

To be clearer: an app that says it can service AlicePay.com but cannot has no substantially different property than an app that says it can service basic-card but cannot. Right?

@dlongley
Copy link

To be clearer: an app that says it can service AlicePay.com but cannot has no substantially different property than an app that says it can service basic-card but cannot. Right?

Yup, was going to say the same thing. An app could have any number of problems actually fulfilling its promise to support a particular payment method, this is just one of them.

@zkoch
Copy link

zkoch commented Aug 16, 2016

Playing devil's advocate -- that doesn't mean we necessarily have to do anything about it. The user will just have a bad experience with that Payment App when it doesn't work ... and probably uninstall it

True, but there are two issues here:

1.) It's going to be very difficult to get certain payment method/app providers to play along if there isn't any way to protect their brand.

2.) This is not the kind of UX I would feel comfortable shipping.

To be clearer: an app that says it can service AlicePay.com but cannot has no substantially different property than an app that says it can service basic-card but cannot. Right?

You've just incentivized "Wallet providers" to claim they support many different payment methods, even if it isn't true, to ensure they show up in the list of supported apps.

@adamroach
Copy link

@zkoch

To be clearer: an app that says it can service AlicePay.com but cannot has no substantially different property than an app that says it can service basic-card but cannot. Right?

You've just incentivized "Wallet providers" to claim they support many different payment methods, even if it isn't true, to ensure they show up in the list of supported apps.

It's really more of a "yes" or "no" question, and I can't tell which answer you're giving.

@adamroach
Copy link

I also don't understand the incentive you're claiming. If an application perpetually shows up but usually fails, I'm never going to use it. I'll probably rip it out of my browser.

I might even expect something like "The payment app 'slimeballz.com' could not process your payment. Would you like to uninstall it?"

@dlongley
Copy link

You've just incentivized "Wallet providers" to claim they support many different payment methods, even if it isn't true, to ensure they show up in the list of supported apps.

If a Payment App I develop keeps showing up as a choice for users and they can't actually use it to fulfill their payment requests, I'd be strongly incentivized to make sure I fixed that right away, lest those users uninstall it and spread the word that my app is terrible.

@zkoch
Copy link

zkoch commented Aug 16, 2016

I would argue that both of you are probably not the typical user. We've seen nefarious software do all kinds of things to browsers that users don't understand that creates a worse and/or confusing experience. We then spend lots of time and money trying to correct it.

There are all kinds of incentive structures that exist out there, and doing the right thing that is good for users is not necessarily the one that always wins.

Let's discuss this more on the next call, as we are drifting a bit from the topic at hand.

@dlongley
Copy link

dlongley commented Aug 16, 2016

I would argue that both of you are probably not the typical user. We've seen nefarious software do all kinds of things to browsers that users don't understand that creates a worse and/or confusing experience. We then spend lots of time and money trying to correct it.

I concede that some users may not understand what's going on and may not be able to easily uninstall the app (or may feel too uncomfortable to do so).

Edit: But will add that I don't know if solving the problem in this particular case will make a significant impact in those users' experiences (given that there are many other cases we may have more difficulty helping out with). If I'm trying to cause trouble as an app developer ... I'll just pick another method. Also consider that we don't want to incentivize proprietary payment methods by saying those are the only ones that will be policed and will provide a "nice experience".

@adamroach
Copy link

@tabatkins

By "without having to interact with the W3C", I presume you're trying to say something like "without having to go through an annoying/arduous beaurocratic process that takes a nontrivial amount of time". There's no reason it has to be like that! A registry can literally just be a text file in a well-known location that your group updates on request - it's a 5-minute email/edit/commit process. You don't have to publish a new spec version every time you update a registry.

That may work as well -- can you give an example of somewhere else the W3C has done this? I got the impression from conversations with @dontcallmedom (in the context of getUserMedia() constraints) that the mode of operation you describe was disfavored by the W3C staff; but the objections may have been specific to the facts of that case. Precedent would probably go a long way to assuaging any such concerns.

@tabatkins
Copy link
Member

tabatkins commented Aug 16, 2016

The payment app registers with the browser, saying "I can support the payment methods x, y, and z" (where x, y, and z are the payment method identifiers we're currently discussing).

Ah, I see. It looks like y'all are indirecting thru the "request_url" - an app somehow informs the OS that it will POST payment information to a particular url, and then a website comes along and says "hey, the app that can post to this request_url should be associated with this payment_app_id", and then another website comes along and says "hey, boot up the app that's been connected to this payment_app_id, then hand it this payment request info and let me know when it's finished".

Is this right? If so, is there a reason it's so... roundabout? Is the request_url information somehow already being collected/advertised by apps, such that it's "free" to learn about? If so, why not just use that directly as the identifier?

Or is the request_url also something that an app needs to explicitly tell the OS about via some new communication channel? If so, why not just instead let the app provide an identification token? Or use some other quality of the app that's unique, like the origin it claims to be associated with? It seems like that would allow skipping the "visit webpage so it can register a payment method" step entirely (unless the webpage is registering a SW as a payment method, of course, rather than an app providing that functionality).

Apologies if these questions seem basic, but I'm puzzling my way thru several layers of indirection here, and I get the (possibly unfounded) feeling that much of it is unnecessary, and just accidentally accreted as people stumbled towards distributed extensibility.

(in the context of getUserMedia() constraints)

I'm not seeing anything like that in gUM; was it thrown out entirely because of such problems?

In any case, there's not a ton of precedent here. If it ends up being useful to produce a centralized registry of payment methods, it's easy enough to explore the option, rather than assume that it won't work.

@adamroach
Copy link

@tabatkins

Ah, I see. It looks like y'all are indirecting thru the "request_url" - an app somehow informs the OS that it will POST payment information to a particular url, and then a website comes along and says "hey, the app that can post to this request_url should be associated with this payment_app_id", and then another website comes along and says "hey, boot up the app that's been connected to this payment_app_id, then hand it this payment request info and let me know when it's finished".

No, you've got both the ordinality wrong and the thing that the website asks for wrong.

The website says "boot up one of the potentially many apps that are associated with this payment_method_id (not payment_app_id)" -- and then the browser gives the user an opportunity to select from among the many apps that can handle payment_method_id.

As a minor detail that doesn't really change this conversation, the POST thing is going away. The actual app API is (if people generally agree with the proposal) likely to look something like this

Unless the webpage is registering a SW as a payment method, of course, rather than an app providing that functionality...

I think you're running into a terminology impedance mismatch. In the vocabulary defined by the web payments documents, "payment app" would include a thing that's basically a service worker. Read the proposal I cite above, which might clarify things a bit.

@tabatkins
Copy link
Member

I got the payment_app_id from where you pointed me to - I don't see anything at that destination that talks about registering a payment_method_id.

I think you're running into a terminology impedance mismatch. In the vocabulary defined by the web payments documents, "payment app" would include a thing that's basically a service worker.

Ah! That clears up some parts of this a ton, but confuses me further on other bits. Was I misinterpreting every use of "app" by people earlier in the thread? Or are we actually talking about mobile apps at least some times?

If everyone really was using "app" in this way, to refer to a SW-y thing, then I'll have to go back and rethink this a bit. Something for tomorrow!

@adamroach
Copy link

adamroach commented Aug 17, 2016

@tabatkins

I got the payment_app_id from where you pointed me to - I don't see anything at that destination that talks about registering a payment_method_id.

It's:

    static Promise<void> register(URLString payment_app_id,
                                  URLString request_url,
                                  sequence<PaymentOption> payment_options);

Where:

  • payment_app_id is a unique identifier for the payment app (n.b., if URL isn't okay for an identifier, we may need to re-think this as well)
  • request_url is the place the identified app is retrieved from (posted to in the current document; but, as I say, that's changing)
  • payment_options (maybe not the best name) is a list of these:
dictionary PaymentOption {
    DOMString           label;
    DOMString           icon;
    sequence<DOMString> enabled_methods;
};

...and enabled_methods is a list of payment method identifiers that the payment app can support. (I forgot that these aren't called payment_method_ids in the spec; they probably should be).

Was I misinterpreting every use of "app" by people earlier in the thread?

Probably. There's a as-of-yet undefined notion of having "native apps" registered for some payment methods as well, but that's a complication that we don't need to bring into this issue. For the purpose of this conversation, it really does not make any difference whether it's a SW-like thing or a native app. For the purpose of this conversation, what we need is some system for creating guaranteed unique payment method identifiers in a decentralized, zero-friction manner.

@annevk
Copy link
Member Author

annevk commented Aug 17, 2016

@adamroach one thing you definitely want to change there is the naming convention, see https://w3ctag.github.io/design-principles/#casing-rules, although it seems dictionary members (which should be lower camelcase) are not covered there.

@adrianhopebailie
Copy link
Contributor

It may be useful for anyone new to this work to read both:

  1. This overview and
  2. This early architecture proposal which is now somewhat outdated but provides useful context to some of the design considerations.

What these APIs are attempting to facilitate is a conversation between a merchant (website) and user that looks something like this:

  • User: I want to checkout (click checkout button)
  • Merchant: The total is $10 and you can pay by card, Bitcoin or Paypal (website calls PaymentRequest API, browser prompts user with choice of payment apps that support one or more of the payment methods the merchant accepts)
  • User: I will pay via my ABC Bitcoin Wallet. (User selects a Payment App that supports the Bitcoin payment method, browser invokes ABC Bitcoin Wallet and user interacts with wallet to authorize payment, wallet return response to browser which passes this back to the website)

This may seem like indirection via the browser (the mediator) but it is necessary for protection of the user's privacy.

In terms of "what is a payment app"; it could be many things. It could be a piece of Javascript that runs (ServiceWorker-like) in a non-UI context but it may also be a mobile app installed from the app store. Also bare in mind that the group is attempting to solve for use cases where there is no browser or even user interaction (example: a parking meter prompts a vehicle to pay for it's parking by passing it the URL for a payment request - see the HTTP API for some thoughts on this) and the ability to identify payment methods will benefit from the name-spacing and context gained by using URIs. (I am also aware that not everyone in the group considers this an important design goal but that doesn't mean we should ignore it, put differently the browser APIs are not being designed in a vacuum)

Note also that at W3C we can only define how a browser might invoke a payment app via web technology (where @adamroach 's proposal is the latest thinking in this regard) but nothing prevents browsers from offering an integration via browser extensions or some other platform specific mechanism (example: an app installed from the app store calls a platform API that makes all installed browsers aware of the payment methods it supports), especially for invoking "native" apps. Therefor we're limiting our scope to invocation via @adamroach 's proposal but we need to consider if the use case of a "native" app, registered via the browser APIs is still important.

So, the payment method identifier is exactly as @adamroach describes, purely an identifier. In fact, user's will likely never need to understand the concept of payment methods. They will be prompted through a variety of channels to install payment apps (in many forms) and these apps will support one or more payment methods.

When the user needs to make a payment they will be prompted with a choice of payment apps (not methods). The intersection of methods accepted by the merchant and supported by the users many apps is used by the browser to decide what choices to offer the user.

The complication in this is @zkoch 's assertion that there will be payment methods that are proprietary and for which there is a limited set (likely 1) of apps that will support this method.

I believe the problem here is that we are conflating identifying the payment method with identifying the payment app to try and solve for concerns around bootstrapping the ecosystem.

The scenario is this:

  • A user visits a merchant that says they accept PayPal (as an example)
  • The PayPal payment method is only supported by the PayPal payment app
  • If the only information provided by the merchant to the browser is "urn:payment"paypal" then the browser has no way to assist the user in getting the right app for this payment method whereas if the identifier was "https://paypal.com/app/v1" and that URL pointed to some kind of manifest then the browser could fetch that and use the information in that manifest to prompt the user to install the Paypal app before continuing with their checkout.

What I am hearing from @zkoch is a proposal to use URLs when the browser is expected to fetch and process (i.e. it will be machine readable) the resource at the end of this URL AND for the format of this resource to be well defined by this group.

There is a counter-proposal from @ianbjacobs for the payment request to allow the merchant to provide "recommended apps" for any of the methods they support and thereby provide the browser with additional information about the apps that are available that support a specific payment method directly in the payment request.

I believe that the editors of the Payment Request API spec don't like @ianbjacobs proposal because, up to now, they have been able to to avoid any mention of payment apps in that specification and kept the two very loosely coupled. Adding "recommended payment apps" to the payment request API would change that.

@annevk
Copy link
Member Author

annevk commented Aug 17, 2016

Is there any kind of interest from browsers to implement that "fetch the metadata manifest and figure out what's next" approach? It seems the website would likely have lost the user at that point.

@adrianhopebailie
Copy link
Contributor

Is there any kind of interest from browsers to implement that "fetch the metadata manifest and figure out what's next" approach?

That is not clear. The proposal to use URL's and also define what is at the end of them comes from Chrome (@zkoch) :

We pushed for URLs because we were pretty sure we would need something machine readable to live at the end of that URL that we could get. I realize Tab is trying to say that we shouldn't agree to use URLs until we agree what should be at the end of them, but I'm not sure that is necessarily true.

But Chrome have not really engaged in the design of the payment apps API to date so it's hard to know what they are thinking with regard to WHAT will be at the end of that URL (especially if not a manifest) because that is mostly relevant to payment app registration and we don't know if they support the current proposals around how that would work.

It seems the website would likely have lost the user at that point.

If you are referring to the user's focus, then yes. Once the website initiates the payment request flow the browser takes over and renders a new dialogue that prompts the user to select a payment app.

I believe the proposal is for that dialogue to also offer the user apps that they have not yet registered but could register as part of the checkout flow.

@zkoch
Copy link

zkoch commented Sep 12, 2016

The group has resolved to use URLs, so marking this as closed.

@zkoch zkoch closed this as completed Sep 12, 2016
@tabatkins
Copy link
Member

More detail, assuming the group resolved in a way similar to what Zach described to me in person: the spec is going to use URLs with a defined type of document at the endpoint which is necessary for the feature to function.

Within this, tho, I recommend the spec require that the URL be normalized (using terms from the URL standard) to be just origin + path (and dictate whether there's a trailing slash or not). That way there's no confusion about query parameters or fragments.

@adrianhopebailie
Copy link
Contributor

@tabatkins said:

Within this, tho, I recommend the spec require that the URL be normalized (using terms from the URL standard) to be just origin + path (and dictate whether there's a trailing slash or not). That way there's no confusion about query parameters or fragments.

This is complicated by the fact that there is a desire for this document to potentially contain an embedded object which is necessarily represented by a different URL (it is an identifier for a payment app, not a payment method). The only way to do this would be to have a fragment that points to the embedded object and therefor the URLs only differ based on that fragment.

See: w3c/payment-handler#35

@annevk
Copy link
Member Author

annevk commented Sep 13, 2016

The group has resolved to use URLs, so marking this as closed.

The group hasn't really explained their rationale to OP though (and the various others that chimed in).

@adrianhopebailie
Copy link
Contributor

The rationale is that the URL will point to a manifest that document that defines details about the payment method, most importantly a white list of payment app identifiers and/or origins for publishers of payment apps that are authorized to handle this payment method.

@annevk
Copy link
Member Author

annevk commented Sep 13, 2016

So it's no longer used as identifier, but as a resource?

@halindrome
Copy link
Contributor

My take on this is that it is both. It is an identifier in that it identifies a payment method, and it is a resource in that it dereferences to data that informs implementations about the characteristics of that identifier.

@annevk
Copy link
Member Author

annevk commented Sep 13, 2016

You need to treat it as one or the other. Anything else will lead to problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants