w3c / payment-handler

Payment Handler API
https://w3c.github.io/payment-handler/
Other
72 stars 42 forks source link

Multiple payment apps per origin #98

Closed adamroach closed 7 years ago

adamroach commented 7 years ago

Currently, the Payment App spec allows an origin to host as many payment apps as they want to (e.g., to allow for different versions, different account types, etc.). In @marcoscaceres' Payment Request Handler document, he proposes that origins be limited to hosting a single payment app.

I think this proposal is problematic. I'm opening this issue to allow discussion of support for and opposition of such a constraint.

tommythorsen commented 7 years ago

This sounds like a very artificial limitation to me. What is the advantage?

Our Payment Apps are pretty much just Service Workers. Service Workers are limited to one per scope (not one per origin), why should Payment Apps be different?

marcoscaceres commented 7 years ago

Sorry, there was clearly some bad wording on my part: I was not proposing 1 per origin. What I was trying to say is, you can register as many service workers as you like, but the "feature" is controlled per origin (like any other power feature).

Like all other browser features:

screenshot_2017-01-24_19_43_00

marcoscaceres commented 7 years ago

I want to be clear, my reaction is to the misnomer that there is a "payment app".

There is no "Payment app", just like there is no "Geolocation app", and no "Push Notification App" - supporting "payment handling" is just another (permission gated) powerful feature - there is nothing special about these kinds of web applications.

marcoscaceres commented 7 years ago

And even going further, one could even display the number of registered payment methods like this:

screenshot 2017-01-24 19 55 28

... but now I'm going off the rails. Anyway, I hope that clarifies things further.

jakearchibald commented 7 years ago

@marcoscaceres

There is no "Payment app", just like there is no "Geolocation app", and no "Push Notification App" - supporting "payment handling" is just another (permission gated) powerful feature - there is nothing special about these kinds of web applications.

There's one "push notification" permission per origin, but there's up to one "push subscription" per service worker, meaning there can be many per origin.

I've taken "payment app" to be akin to "push subscription". I agree that the permission part is per-origin.

marcoscaceres commented 7 years ago

On 24 Jan 2017, at 11:13 pm, Jake Archibald notifications@github.com wrote:

@marcoscaceres

There is no "Payment app", just like there is no "Geolocation app", and no "Push Notification App" - supporting "payment handling" is just another (permission gated) powerful feature - there is nothing special about these kinds of web applications.

There's one "push notification" permission per origin, but there's up to one "push subscription" per service worker, meaning there can be many per origin.

I'm trying to say exactly what you just said. Language is hard :(

I've taken "payment app" to be akin to "push subscription". I agree that the permission part is per-origin.

That's also exactly how I'm viewing it. Why I don't like the whole "payments app" thing (and I think saying "app" is leading to problems and poor design choices) - it's a subscription of sorts... just another "powerful feature", as per Permission API parlance.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ianbjacobs commented 7 years ago

We had lonnnnnnnng discussions about how to talk about this work with people. We did not like the term "digital wallet" as it is overloaded. We chose "payment app" to say "The software that you pay with". We have invested a lot in the phrase "payment app" for communications purposes and I would not throw it out lightly.

Ian

marcoscaceres commented 7 years ago

On 25 Jan 2017, at 1:12 am, ianbjacobs notifications@github.com wrote:

We had lonnnnnnnng discussions about how to talk about this work with people. We did not like the term "digital wallet" as it is overloaded. We chose "payment app" to say "The software that you pay with". We have invested a lot in the phrase "payment app" for communications purposes and I would not throw it out lightly.

You don't need to. No spec talks about "progressive web apps", for instance; yet we have a good understanding of the tech that comes together to form them.

So please don't mix marketing and communication with normative prose - that just makes for really bad times - and it's clear to see how it's already led to poor design choices in this spec (the manifest duplication).

Ian

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ianbjacobs commented 7 years ago

@marcoscaceres,

We were not planning to duplicate the manifest. We had an open issue to discuss with you how to manage this since we recognized the overlap. This conversation is part of clearing all that up. I would not call it a bad design choice because our goal has always been to avoid duplication...we just haven't had all the answers until these recent threads.

I am convinced we need a term to refer to what we are currently calling payment apps, and that term should be part of the specification. I support cleaning up the normative text to stay closer to Web primitives.

Ian

adamroach commented 7 years ago

@marcoscaceres --

Sorry, there was clearly some bad wording on my part: I was not proposing 1 per origin. What I was trying to say is, you can register as many service workers as you like, but the "feature" is controlled per origin (like any other power feature).

If that's the case, then this seems to be a matter of simple confusion. I agree that payment permissions need to be managed in the same way we manage other permissions. But this doesn't for the basis for "identification" of an app.

If you agree, then it would appear that this is a simple matter of confusion, and we can close the issue.

[@ianbjacobs: I'd like to hear positive confirmation from @marcoscaceres before we close the issue]

adrianhopebailie commented 7 years ago

there is nothing special about these kinds of web applications.

This is an oversimplification. A browser does not have many geo-location handlers or push-notification handlers.

There are two sides to payments: does an origin have permisson to request payments and does it have permission to handlepayments?

But there is also more granularity. Can a specific ServiceWorker handle payments for a specific payment method and is it permitted to do so.

I am hearing @marcoscaceres say that, per the web security model, we cannot assign different permissions to two Service Workers from the same origin (i.e. app1 has permission to handle basic-card payments and app2 has permission to handle bobpay). I don't think this is a problem as the notion of 'supporting" a payment method is different to the notion of having permission to handle a payment method.

WRT terminology, since these components are able to spin up a new UI and therefor present a fully featured application to the user I think the terminology app is appropriate. Any software architecture literature I have read refers to handlers as simple functions that process events or messages. These are usually a component of larger application or (as they are often called on the Web platform, an app).

Nothing in the current design prevents the Service Worker that handles the payment request from also performing a plethora of other functions that are part of a larger application.

On the topic of "manifest duplication", I personally attempted, on more than one occasion, to engage the editors of the app manifest specification to provide input into this work or review our use case. Specifically I wanted to find ways to re-use parts of app-manifest without duplicating it but those attempts, to put it politely, didn't end well, so let's leave that there.

adamroach commented 7 years ago

@adrianhopebailie --

I am hearing @marcoscaceres say that, per the web security model, we cannot assign different permissions to two Service Workers from the same origin (i.e. app1 has permission to handle basic-card payments and app2 has permission to handle bobpay). I don't think this is a problem as the notion of 'supporting" a payment method is different to the notion of having permission to handle a payment method.

We're not talking about those kinds of permissions. We're talking about "do you give example.com permission to install a payment app in your browser?" This is going to be a "yes/no/always/never" kind of thing set on the origin, just like all other browser permissions.

marcoscaceres commented 7 years ago

Tl;dr: @adamroach, indicating in the affirmative. Please close this issue.

@adrianhopebailie, wrote:

On the topic of "manifest duplication", I personally attempted, on more than one occasion, to engage the editors of the app manifest specification to provide input into this work or review our use case. Specifically I wanted to find ways to re-use parts of app-manifest without duplicating it but those attempts, to put it politely, didn't end well, so let's leave that there.

I'm really sorry that we the Editors let you down - but the reality is that what you were asking for didn't make any sense to us, which is why we were doing so much head scratching when you reached out to us. We were all like, "...but... we already provide all that stuff, why do you want it again?".

Anyway, just trust the page to include: <link rel=icon> OR <link rel=manifest> OR even a favicon OR <meta name="application-name">. If it doesn't, that's also ok! It's just a crap app and the browser can provide a fallback icon.

adamroach commented 7 years ago

@marcoscaceres --

Tl;dr: @adamroach, indicating in the affirmative. Please close this issue.

Based on your recent comment "...the "multi-paypal" example is totally bogus. If there are two totally different things, then they would be in totally different origins (hence different apps).", it sounds very much like you still think that there can be only one payment app per origin -- so I don't think this is ready to close until you've explained more completely what you mean.

marcoscaceres commented 7 years ago

Wish we could stop calling them "apps"... it's making this really confusing (because these things are inside web apps).

Anyway, In the other bug I said:

screenshot_2017-01-25_15_43_57

why we should not allow multiple payment handlers.

adrianhopebailie commented 7 years ago

I am +1 to only having one payment app per origin.

adrianhopebailie commented 7 years ago

We must differentiate between the permission a user grants to an origin to "handle payment requests" and the ability of a payment app (a Service Worker with a scope under that origin) to handle payment requests for a specific payment methods.

Therefor there are two things that happen:

  1. An origin requests and is granted/denied permission to handle payment requests
  2. A payment app notifies the browser that it can handle payments for a specific payment method

I think we must still decide if 2. requires user consent, this feels like a separate issue.

Concrete proposal to close THIS issue:

  1. Update the registration process to explicitly ask the user if they grant permission for the calling origin to handle payment requests (similar to existing permission requests like location etc)
  2. Resolve whether or not a user must consent to a payment app altering the set of payment methods it supports.
ianbjacobs commented 7 years ago

@adrianhopebailie, you wrote:

"I am +1 to only having one payment app per origin."

Please say more about versioning in this case.

Ian

jakearchibald commented 7 years ago

Given that an origin can have multiple service workers, I can't see how "one per origin" works, nor what it achieves.

marcoscaceres commented 7 years ago

On 25 Jan 2017, at 11:18 pm, Jake Archibald notifications@github.com wrote:

Given that an origin can have multiple service workers, I can't see how "one per origin" works, nor what it achieves.

Wait, no - maybe the terminology has also confused you?: one can have as many Service Workers as one likes using the API (each having N registered payment methods). Just that only one "web app" shows up in the "Select how you want to pay" dialog on the merchant's site.

Works exactly the same as any other SW using feature. Should be the same as Push Notifications.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

jakearchibald commented 7 years ago

@marcoscaceres Are you saying the browser merges all the payment methods across an origin's service workers?

An origin can have many active push notification subscriptions.

marcoscaceres commented 7 years ago

On 26 Jan 2017, at 3:09 am, Jake Archibald notifications@github.com wrote:

@marcoscaceres Are you saying the browser merges all the payment methods across an origin's service workers?

I'm unsure if they are merged at this point. I don't think they should merge (depends also what merge means in this context). An origin can have many active push notification subscriptions.

The same here: you could have many active payment handlers.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

adamroach commented 7 years ago

@marcoscaceres -- Wait, what? You seem to be all over the map on this. You previously said:

And this is what is "totally bogus" (apologies if I misread and you were not proposing the below):


const reg1 = await serviceWorker.register("app1.sw");
const reg2 = await serviceWorker.register("app2.sw");

reg1.paymentManager.setName("SUPER COOL CARD MANAGER"); reg1.paymentManager.setIcon("super-app1.png");

reg2.paymentManager.setName("I'M A TOTALLY DIFFERENT CARD MANAGER"); reg2.paymentManager.setIcon("TOTALY_DIFFERENT_APP.jpeg");

await Promise.all([reg1.paymentManager.register(), reg2.paymentManager.register()];



But now you seem to be saying it's... okay? Or maybe okay? I'm getting whiplash trying to follow your can-or-can't have multiple payment apps[1] per origin.

[1] _Which, for avoidance of doubt, is the term we have been using as shorthand for "service worker that is registered to handle one or more payment methods."_
adamroach commented 7 years ago

@jakearchibald --

@marcoscaceres Are you saying the browser merges all the payment methods across an origin's service workers?

I think that would be the height of confusion. @adrianhopebailie's example using business and personal apps from the same bank seems highly realistic, and mashing together the personal and business payment options to make them look like one thing is exactly wrong.

chackett commented 7 years ago

Hi all, another perspective:

It is highly likely that a PSP may want to host many payment apps on a single origin. For example many whitelabelled apps on behalf of various merchants. I would not consider this an edge case.

marcoscaceres commented 7 years ago

@adamroach wrote:

But now you seem to be saying it's... okay? Or maybe okay? I'm getting whiplash trying to follow your can-or-can't have multiple payment apps[1] per origin.

I've not changed my position, AFAICT - but I clearly didn't articulate my position well and kept getting confused by the existing terminology (which is why I provided code and images, which are subject to less ambiguity). From my very first proposal, I held that I view "payment web apps" as single origin progressive web apps - meaning you could have as many service workers registered to handle requests per payment as needed. I.e., they were exactly the same as any web application today. Sorry if I was not clear.

Also, should I, or anyone, change their position by coming to a new understanding in light of new information, that's a good thing - not something to be mocked. I'm not here because I like s***posting or making an ass of myself. If I am wrong, or proved wrong, I will be totally happy with that. But I will continue to question as to assure that this is the best solution for users, developers, merchants, payment processors, implementers and the Web as a whole.

I still think we can do better - and we are a long way from anything I would support publishing as a FPWD or would feel comfortable taking back to Mozilla to allow us to consider implementation.

[1] Which, for avoidance of doubt, is the term we have been using as shorthand for "service worker that is registered to handle one or more payment methods."

That's not the definition I was using - and that definition is the source of all confusion (which is why I removed it from my counter proposal - and continue to argue to drop it from this spec too). The definition I was using was from a user's and developer's perspective (and basically what everyone else in the web community would call these things, and how user's would understand them): "web apps that can handle payments".

This image (the actual web application) represents what is meant (wallet.com is a payment app):

screenshot 2017-01-27 13 57 21

A end-user would see when making a purchase:

screenshot 2017-01-27 13 50 17

(one web application: multiple payment methods)

Thus, "a payment app is a web application that is registered to handle requests for payment via one or more payment methods. Payment methods are processed via one or more service workers". If we can get behind a logical definition, that is consistent with the rest of the web platform, then we can stop all the confusion.

Now, with regards to permissions we could even refine the proposal as follows:

// Register once on static PaymentManager method. 
PaymentManager.requestPermission().then(async result => {
  // can do  both Visa and Amex
  const multiHandler = await serviceWorker.register("visa_and_amex.js");
  // can do only MasterCard
  const masterCard = await serviceWorker.register("mastercard.js");

  // Add payment methods
  await multiHandler.paymentManager.methods.set("visa-4756", {
      name: "Visa",
      methods: ["basic-card"],
      icons: [...visaIcons],
   });
  await multiHandler.paymentManager.methods.set("amex-5361", {
      name: "Amex",
      methods: ["basic-card"],
      icons: [...amexIcons],
   });
  await masterCard.paymentManager.methods.set("mastercard-1234", {
      name: "MasterCard",
      methods: ["basic-card"],
      icons: [...mastercardIcons],
   });
});

@adrianhopebailie wrote:

Resolve whether or not a user must consent to a payment app altering the set of payment methods it supports.

I'm of the opinion that the web application need not ask a user for consent to manage payment methods. It should be a goal of this spec to enable developers to build apps like "wallet.com" above - which include saving payment hander details, handling the payment processing (in coordination with payment processors), and being able to store shipping/billing information, and whatever else will help to make for a speedy checkout experience.

I can't build "wallet.com" if I have to annoy the user every time they want to add or modify a payment method.

Lastly, as an implementer, I want developers to have exactly the same API that we would use to build a card management interface in Firefox - this includes Firefox also having to ask for permission to handle credit cards on behalf of the user, etc. I don't want the browser to have any special things that are not available to developers unless there is some demonstrable privacy or security restriction that can't be handled in any other way (e.g., in fetch API, developers can't override certain headers for security reasons - I want the same here, where it makes sense).

Again, in pictures, to reduce ambiguity: Firefox settings to manage credit cards and wallet.com are the same thing, and must use the same APIs:

screenshot 2017-01-27 14 14 43

In fact, I should be able to host Firefox's credit card manager at "mozilla.com/manage-payments" or whatever, without requiring any browser-only APIs. If this spec doesn't let me do that, then it's not meeting the use cases.

ianbjacobs commented 7 years ago

@marcoscaceres,

You wrote: "A payment app is a web application that is registered to handle requests for payment via one or more payment methods. Payment methods are processed via one or more service workers".

Here are my annotations:

What about this, merging your text with some of the text in the task force's spec, something like:

"A payment app is software that enables the user to fulfill a payment request for one or more payment methods. A payment app that conforms to this specification is a Web application where one or more service workers handle the payment request and response."

Regarding consent from the user:

Ian

marcoscaceres commented 7 years ago

(There may be other payment app implementations that do things differently.

Sure, but they are not our concern.

"A <dfn>payment app</dfn> is software" ... "A <dfn>payment app</dfn> ... is a Web application".

The above is confusing, because you are defining the same thing twice. I think we should drop the "is software", because, as you state, they are outside the scope of this specification.

ianbjacobs commented 7 years ago

What I like about the first sentence is that it is user-friendly and implementation independent. Even though I think my sentences make sense next to each other because the second one is a subset of the first, here's another attempt:

"A payment app enables the user to fulfill a payment request for one or more payment methods. A payment app that conforms to this specification is a Web application where one or more service workers handle the payment request and response."

marcoscaceres commented 7 years ago

"A payment app enables the user to fulfill a payment request for one or more payment methods. A payment app that conforms to this specification is a Web application where one or more service workers handle the payment request and response."

I would want it to be more clear about the payment apps role as mediator: a payment app doesn't itself necessarily fulfill the payment request. I'd also be inclined to drop any mention of service workers.

For the purpose of the specification, in normative terms:

"A payment app is a web application that manages an end-user's payment methods (e.g., credit cards) and mediates a request for payment between a merchant and the end-user using those payment methods."

For general communication outside the spec, the other definition is fine (as it covers proprietary payment apps).

ianbjacobs commented 7 years ago

@marcoscaceres wrote:

"a payment app doesn't itself necessarily fulfill the payment request."

(Agreed, which is why we have been saying "handling". )

We should not use the word "mediate" as you have done here because we have used the word "mediator" to describe the browser's role.

How about:

"A payment app is a web application that manages payment requests on behalf of the user by supporting one or more payment methods."

Ian

marcoscaceres commented 7 years ago

"A payment app is a web application that manages payment requests on behalf of the user by supporting one or more payment methods."

Like it! ❤️

dlongley commented 7 years ago

@marcoscaceres,

In your mock up, if a user selected "master card" to pay, would only the service worker that registered it receive the payment request event?

Now, regarding "multiple payment apps per origin", I think what @chackett and @adamroach are looking for is another level of classification that can be surfaced on the UI. In other words, I believe they would like to be able to create different groupings, each with their own icon/title, of N of what you are calling payment methods.

Side note: I think what you're calling payment methods are really what have been understood by the group to be payment instruments. These are instances of payment credentials that can be used by a particular payment method. In other words, "visa-debit-legacy-v2" is a payment method identifier which uniquely identifies a payment method, which is set of rules (and a network) for processing payment. A payment instrument like "the visa card with number 4111 1111 1111 1111" may be used by such a payment method to perform payment. The terminology in this space -- as previously noted -- can be confusing and significant conflation occurs between popular understanding and various industry terms of art. So you should be aware that even the language you are using to talk about how a payment app exposes "which payment methods it supports" may take on a somewhat different meaning from others in this group. We must all make a best effort to understand these nuances.

Anyway, getting back to what I think may be desired here: Could the same origin, after getting permission (just once) to handle/manage payment for the user, register two different "groups" of payment options? I'm intentionally not using methods/instruments or mentioning service workers, because it doesn't matter for this particular point.

Each group could be surfaced on the UI using a title and icon, e.g. one for "Merchant X" and one for "Merchant Y" where both of these merchants have signed up to use a white label service provided by the origin. Similarly, another origin could surface two different groups "MyBank for Business" and "MyBank Personal". The origin would be the same for both of these cases but, from the end user's perspective, there would be multiple "apps". The assumption here is that the end user's only concept of "an app" is an icon they click on to do things -- and that icon is merely a "grouping" indicator. Each of these groups may have N "payment methods/payment instruments".

Under this scenario, there would be no user consent required to "install" these groups. Any service worker on the origin could add or remove them at will. They could, of course, ask the user (on their own) at the origin if they want to add/remove these groups (and may use the language "app" on their site). I believe this would give @adamroach and @chackett what they are looking for and it would fit into the architecture you've described. The only possible hiccup may be with how origin/manifest icon meta data is used (or not used) here.

Sorry for rambling on. TL; DR: Would it meet the use cases and fit the existing browser architecture to allow origins to create their own "groups" (terminology pending) of payment methods/instruments that could be surfaced using titles and icons on the UI? Control over the addition/removal of these groups would not require user permission. Note: getting user consent for permission to handle payment and any site's division of its own code into N many service workers is totally orthogonal to this.

dlongley commented 7 years ago

I think much of the confusion in this thread has to do with how a particular origin decides to divide its own code (into N many Service Workers) and whether or not the concept of a "Payment App" is bound to a Service Worker.

For those who are using the Working Group's original understanding of a "Payment App":

The argument here is that there is no 1:1 relationship between a Payment App and a Service Worker. A Service Worker is simply a division of labor mechanism for an origin. When we have said, in the past, that a "Payment App is just a Service Worker", that was a mistake. It is true that we will use Service Worker(s) to implement Payment Apps. But that's just because it's the browser's mechanism for writing code that gets registered to run in the background, without the user necessarily having to revisit the origin from whence it came.

A Payment App, due to the existing browser architecture, may cross the boundary of a single Service Worker. So we should not equate these two things. We should not be telling developers how to divide their origin's Payment App code. They can use as many Service Workers as they would like.

All we need is a way to execute code without requiring the user to visit a web page. We need a way to ask the user for their consent to handle payments. That's what Service Workers provide.

I recommend we should stop talking about a "Payment App" registering itself. That will never happen -- it mixes our conceptual model and it confuses everyone. Those unfamiliar with our architecture and terminology are only thinking of an "app" as "the code from an origin". There is no other division. Only an origin can register what we've been calling a "Payment App".

Furthermore, there would be no user consent required (from the browser) when this registration happens. The user consent is required when an origin asks the user if it can be allowed to "handle payment". The browser architecture and security model currently only understands one boundary: the origin. That means that any user consent that is required from the browser must be origin-bound. In other words, an origin may ask the user to grant permission to an origin. Nothing else.

So, when a user provides consent to handling payment through the browser, it means that they consent to allowing the entire origin to install Payment Apps (that will handle payment requests) at will. It has no ability to manage user consent at a more granular level (i.e., within an origin).

Now, this does not mean that we can't surface more information from an origin for the user to see in some UI. But, as far as the browser is concerned, we have already been given permission to do this. If we're going to ask for user consent to show these items, it's up to the origin to surface a UI to ask the user. Otherwise we'd be trying to invent something new that deviates from the browser's existing architecture and security model.

Moving on -- I'll leave whether or not we should maintain the terminology "Payment App" aside. What we should not do is talk about them as registering themselves. We should separate how we talk about the code an origin is running from what is effectively our "grouping" of an end user experience that a particular origin provides. That's what a Payment App really is, IMO.

While we came up with "Payment Apps" by thinking about the various roles that exist in a Web Payments ecosystem, I think what the Working Group has understood to be a "Payment App" in these implementation discussions has largely been driven from the end user's perspective:

It should be an icon + title that the end user uses to identify a particular experience. They expect that by selecting it or by selecting an item that is associated with it (through some kind of encapsulating indicator on the UI) that they will be choosing to have the same experience they had the last time they made that choice.

I believe that how a particular origin manages this experience (or experiences) is totally orthogonal to how it is surfaced for the end user, e.g. the origin may use as many Service Workers as its developers desire. We need to accept that reality and move on to talking about what will be surfaced, whether or not it can be done securely, and how it enables multiple "Payment Apps" from the same origin given that it appears to be a requirement.

delapuente commented 7 years ago

I could not agree more with @dlongley. For me, the capability of handling a payment request is no more than that: a capability. I could have it in my web property regardless if someone considers it a web app or not. So, a website can have the ability to handle payment requests. Since registering new payment methods is adding user preferences, I see the need of asking for permission.

Once permission is granted, a website needs to link specific payment methods with code to handle the payment request, it makes sense for me that an origin could register as many handlers as it considers convenient.

adrianhopebailie commented 7 years ago

@dlongley asked:

Would it meet the use cases and fit the existing browser architecture to allow origins to create their own "groups" (terminology pending) of payment methods/instruments that could be surfaced using titles and icons on the UI?

Yes, and this already exists in the spec as "options". The intention is for a single payment app to register multiple options each of which handles requests for a specific combination of payment methods.

@dlongley said:

The argument here is that there is no 1:1 relationship between a Payment App and a Service Worker. A Service Worker is simply a division of labor mechanism for an origin. When we have said, in the past, that a "Payment App is just a Service Worker", that was a mistake.

Yes, I think that's at the heart of the issue.

And also:

What we should not do is talk about them as registering themselves. We should separate how we talk about the code an origin is running from what is effectively our "grouping" of an end user experience that a particular origin provides. That's what a Payment App really is, IMO.

Agreed. I still think we should be writing a "Payment Apps Specification" but that this should define the various features that we are introducing for web apps to use that would qualify them as payment apps.

dlongley commented 7 years ago

@adrianhopebailie,

Yes, and this already exists in the spec as "options". The intention is for a single payment app to register multiple options each of which handles requests for a specific combination of payment methods.

I think these "options" are really what we should be referring to as "payment apps" in the sense that they are merely logical groupings for some set of payment methods. "Payment apps" shouldn't register these "options", rather, origins should register these "payment apps".

Agreed. I still think we should be writing a "Payment Apps Specification" but that this should define the various features that we are introducing for web apps to use that would qualify them as payment apps.

I don't think "web apps" should qualify as "payment apps". I think origins may be granted permission to handle payments. They may register "payment apps" that are just logical groups of payment methods that will be surfaced to the user for selection during payment. Maybe "payment options" is better and the term "payment apps" should go away entirely.

adrianhopebailie commented 7 years ago

@dlongley,

This came up on the apps TF call today. I agree that we need more clarity on how this would be supported but I don't think we should call these "apps". Many of these option could technically be supported by a single web app.

I like your other comment that payment apps are effectively web apps that use some specific platform features that we are defining.

Personally I still like the idea of sticking with origin boundaries (and then using sub-domains if required) and providing options per origin (where each option has a label and icon).

@adamroach had some other ideas but I don't want to speak for him so will leave it with him to comment.

Consensus was that a payment app is identified by its origin (just like any other app on the Web platform), but that as a separate issue we need to ensure our "option" semantics support all the use cases we expect payment app developers to have.

Step 1 is gathering those use cases.

dlongley commented 7 years ago

@adrianhopebailie,

Personally I still like the idea of sticking with origin boundaries (and then using sub-domains if required) and providing options per origin (where each option has a label and icon).

If you're suggesting that an origin can provide multiple "options", then I think we're on the same page. I'm advocating for origin boundaries where origins may register as many logical groups ("options") as they want -- and these are surfaced to the end user for selection. These groups may have subgroups for surfacing more granular options that allow end users to select individual payment instruments directly for a more efficient flow (if the browser supports this in its selection UI).

tommythorsen commented 7 years ago

I really like the direction we're heading where payment apps are just web apps that can handle payments.

However, the single-app-per-origin thing still confuses me. I understand that permissions are handled on a per-origin basis, but web apps (as described here for instance) are not normally origin-bound. Web apps the way I know them, are just collections of web pages that share a common manifest file.

To demonstrate this, please have a look at the following two web apps, that I just made:

Open them in a modern mobile browser, and add them both to the home screen to see that they are indeed independent of each other. These two web apps are hosted on the same server (which also hosts a myriad of other web apps and random pages), but they have separate manifest files.

It seems to me to be a misunderstanding that "because permissions are per-origin, payment apps must also be limited to one per origin". I think the boundaries of the permission model and the boundaries of the payment apps can absolutely be independent.

marcoscaceres commented 7 years ago

So, that's to do with the "scope" of a web app: scope is the URL space to which a manifest is applied (e.g., /blue). That's independent from its origin.

More info at: https://w3c.github.io/manifest/#navigation-scope

marcoscaceres commented 7 years ago

Think of manifest as similar to a CSS style sheet - in that they are applied to web page so long as the page "is in scope" (URL space). If you leave the scope (/red) the manifest is no longer applied. However, origin policy still applies- we can't change the web's security model.

tommythorsen commented 7 years ago

@marcoscaceres

So, that's to do with the "scope" of a web app: scope is the URL space to which a manifest is applied (e.g., /blue). That's independent from its origin.

More info at: https://w3c.github.io/manifest/#navigation-scope

Thanks Marcos! This is useful and relevant information. I should really try to find the time to sit down and read the whole Web App Manifest specification today.

@marcoscaceres

However, origin policy still applies- we can't change the web's security model.

Not sure if you are implying that I proposed to change the web's security model in my previous comment, but I want to make it clear that I propose no such thing. I am however suggesting that perhaps there is no conflict between the security model of the web, and having multiple payment apps per origin. Even if my bank has multiple payment apps, it is fine that they share permissions, as my trust lies with the bank itself, not with the specific apps.

For those that are arguing the one-app-per-origin side, I would ask that you consider the following simple logical statements:

  1. "Payment Apps are Web Apps." (This is by our own definition.)
  2. "There may exist multiple Web Apps per origin." (I demonstrated this above.)
  3. The above two statements imply that: "There may exist multiple Payment Apps per origin."

Which one(s) of these do you disagree with?

adrianhopebailie commented 7 years ago

I think we are all clear on the permission model so let's leave that to the side now.

What we're trying to establish is whether it is possible/desirable for a user to be presented with two "things" that it can choose between when the browser prompts him/her to make a choice between payment apps.

Example

Assuming the two "apps" that @tommythorsen has created each install a service worker (https://people.opera.com/tommyt/blue/sw.js and https://people.opera.com/tommyt/red/sw.js are the script files).

Both SWs have registered event listeners for the paymentRequest event and also registered their ability to handle payments for the basic-card payment method.

So, from the perspective of the browser there are two apps (from the same origin but that's okay) with non-overlapping scopes that can both handle basic card payments.

When @tommythorsen visits a website that calls payment request and lists basic-card as a supported method, what is the desired/expected behavior? Does @tommythorsen get presented with 1 or 2 options?

Assuming he's presented with 2 options, how does the browser decide which event handler to invoke when he picks the blue app?

Do we require that the two service workers that register the event listeners have non-overlapping scopes and scopes that fit within the scope of the manifest (from which the browser gets the icon and label to display), or must the URL of the service worker install scripts be under that same scope?

What happens if a third service worker is installed from that origin (https://people.opera.com/tommyt/sw.js) with an overlapping scope (https://people.opera.com/tommyt/) and also registers itself as a handler for basic card payments?

What if it has no manifest?

How does the browser figure out what options to present and, when the user has selected one, what event listener to invoke?

My understanding of navigation scope is that it is simply a way to tell the browser whether to apply the context changes defined in the manifest or not, based on the location the browser has navigated to. I would like to hear from @marcoscaceres but I don't think the intention of the navigation scope is to define app boundaries?

So, I don't think we can prevent anyone having a hundred SWs under the same origin, all listening for payment request events.

But, we must define how the browser separates these from one another into logical "apps" for the sake of presenting a user with choices and also, how the browser determines which "app" to invoke when the user has made their choice.

If we want to use scope, then that's fine, but we need to put something in the spec that makes this easy to understand, implement and develop against so that the outcome is predictable.

tommythorsen commented 7 years ago

@adrianhopebailie

When @tommythorsen visits a website that calls payment request and lists basic-card as a supported method, what is the desired/expected behavior? Does @tommythorsen get presented with 1 or 2 options?

2 options, assuming both service workers have registered a single option each.

Assuming he's presented with 2 options, how does the browser decide which event handler to invoke when he picks the blue app?

Each of the two options presented to the user, is connected to a specific service worker instance, by means of an ID (in our current implementation in Chromium, this is not the scope url, but a unique numeric identifier).

Do we require that the two service workers that register the event listeners have non-overlapping scopes and scopes that fit within the scope of the manifest (from which the browser gets the icon and label to display), or must the URL of the service worker install scripts be under that same scope?

Our current implementation does not care about the scopes of the web apps nor the scopes of the service workers when it comes to directing events to the right listener. Each option presented to the user is linked directly to a specific service worker instance. Even if we move from being service-worker-centric to being web-app-centric, I don't think this implementation detail needs to change.

What happens if a third service worker is installed from that origin (https://people.opera.com/tommyt/sw.js) with an overlapping scope (https://people.opera.com/tommyt/) and also registers itself as a handler for basic card payments?

That's fine. It will be presented as a third payment option in the UI, and an eventual payment request event will be routed to it without any problem.

What if it has no manifest?

This depends. As per the current specification, the web app manifest doesn't really matter, but it could be that we want to rely on it a bit more, now that we've changed our definition of "Payment App".

How does the browser figure out what options to present

This is easy. We go through all the registered service workers, and check which ones can handle the merchant's supported payment methods, and do optional extra filtering. I don't think we need to confuse things any more by dragging origins and scopes into this equation.

... and, when the user has selected one, what event listener to invoke?

Again, as an implementer, I don't see that there is any problem with knowing exactly which option belongs to which service worker instance. Once the user has selected an option, we can pass the event to the correct service worker.

Even though we have moved from focusing on service workers to focusing on web apps, the service workers are still the ones that register the payment options and the payment request event listener. I don't see any reason to change this. Do you?

adrianhopebailie commented 7 years ago

Even though we have moved from focusing on service workers to focusing on web apps, the service workers are still the ones that register the payment options and the payment request event listener. I don't see any reason to change this. Do you?

My only concern here is we're back to tying a Service Worker, 1:1, to a user choice. That feels wrong to me at an architectural level. It's an implicit binding between a background process and a UI element that is not really how SW's are intended to be used.

As @dlongley pointed out previously SWs are just a way of having a background process, a division of labour, for a web app. As @marcoscaceres has also pointed out, you could have multiple SWs per payment app (example one that knows how to handle card payments and one that can handle some other proprietary payment method). The developer intends these to be presented to the user as a single "app".

I like the idea of the "user choice" being analogous to the "app icon on a user's home screen". i.e. My browser finds an app manifest and "installs" that app (assuming I give the app all the permissions it requires). This is no different to the app manifest flow today.

In this flow the browser will fetch the SW script defined in the manifest and register the SW at which point the app can register its intention to be a payment app. (i.e. the app asks for the "handle payments" permission and registers event listeners for payment events).

I believe that the SW would necessarily have to be within the defined scope of the app as defined in the manifest or it will not be installed.

The thing presented to the user at payment time is the app in the form of its icon and label (as defined in the app manifest).

If a user selects an app, all SWs within the scope of that app and which have registered listeners for one of the merchant supported methods receive the paymentRequest event. (i.e. it could be more than one).

It is up to the app developer to co-ordinate this if they use multiple SWs (as it would be today if you had mutiple SW(s) listening for fetch events). The first SW that calls respondWith on the event wins and that is the response passed back to the website.

This only leaves SWs that attempt to register handlers independent of the app manifest install flow (which is completely possible). We need to define a way for them to make themselves available for user selection or decide that we always ignore them...

tommythorsen commented 7 years ago

@adrianhopebailie

My only concern here is we're back to tying a Service Worker, 1:1, to a user choice.

I'm not sure what this refers to. Neither the existing setManifest() specification text, nor the proposal in https://github.com/w3c/webpayments-payment-apps-api/issues/95 ties Payment Option 1:1 to a Service Worker. Each Service Worker can register 0, 1 or many Payment Options.

I like the idea of the "user choice" being analogous to the "app icon on a user's home screen". i.e. My browser finds an app manifest and "installs" that app (assuming I give the app all the permissions it requires). This is no different to the app manifest flow today.

That does actually sound pretty nice, but then we are not doing Payment Options anymore. You're now describing a single entry per Payment App. Nothing wrong with that approach, although there might be advantages to having multiple Payment Options per Payment App too.

Implementation-wise, this does probably require us to keep track of all Service Workers that belong to a Payment App. "Belong to" meaning either registered through the App Manifest, or from a page that is associated with the App Manifest. Not sure how easy this is. It might be feasible.

It is up to the app developer to co-ordinate this if they use multiple SWs (as it would be today if you had mutiple SW(s) listening for fetch events). The first SW that calls respondWith on the event wins and that is the response passed back to the website.

This only leaves SWs that attempt to register handlers independent of the app manifest install flow (which is completely possible). We need to define a way for them to make themselves available for user selection or decide that we always ignore them...

This does not sound that great, though. Our current specification, where Payment Options are registered by the individual Service Worker, and Payment Request events are passed directly to the correct Service Worker feels much more precise and elegant. It solves the last problem you describe, too, by allowing any Service Worker to register and handle payments, regardless of whether has a relation to a Web App Manifest.

adrianhopebailie commented 7 years ago

I'm not sure what this refers to. Neither the existing setManifest() specification text, nor the proposal in #95 ties Payment Option 1:1 to a Service Worker. Each Service Worker can register 0, 1 or many Payment Options.

You are talking about the options and I am talking about apps. The choices presented to a user exist at two levels. The user is presented with a bunch of "apps" and under each app is a bunch of "options". The most common use of options will be to present different instruments that the app has stored.

The images from @marcoscaceres in https://github.com/w3c/webpayments-payment-apps-api/issues/98#issuecomment-275581133 are good illustrative examples.

My suggestion is that if we want to allow multiple "apps" per origin then the only way to do that is using scopes and these are defined by either a manifest or by a SW itself during registration. (Note that the scope of a SW is it's unique identifier so if there is no manifest defining the scope then only one SW can be installed per scope)

That does actually sound pretty nice, but then we are not doing Payment Options anymore. You're now describing a single entry per Payment App. Nothing wrong with that approach, although there might be advantages to having multiple Payment Options per Payment App too.

You can still do payment options. Any SW that registers an "option" will do so under the "app" under whose scope it is currently executing. If we go back to the example of your two apps from the same origin, if a SW with the scope https://people.opera.com/tommyt/blue/ registers an option, that option will appear under the Blue "app" in the user choices.

Implementation-wise, this does probably require us to keep track of all Service Workers that belong to a Payment App. "Belong to" meaning either registered through the App Manifest, or from a page that is associated with the App Manifest. Not sure how easy this is. It might be feasible.

No, I think you'd track which SW's are within which scopes. i.e. A scope delimits the app boundary.

This does not sound that great, though. Our current specification, where Payment Options are registered by the individual Service Worker, and Payment Request events are passed directly to the correct Service Worker feels much more precise and elegant. It solves the last problem you describe, too, by allowing any Service Worker to register and handle payments, regardless of whether has a relation to a Web App Manifest.

My proposal is modeled on how fetch events work. There is no context binding a single Serviceworker to an event.

An alternative is to take some inspiration from the Push API: https://www.w3.org/TR/push-api

The Push API defines a concept of a push subscription: "A push subscription is a message delivery context established between the user agent and the push service on behalf of a webapp. Each push subscription is associated with a service worker registration and a service worker registration has at most one push subscription."

If we followed this model, then perhaps we would allow one SW per "option"?

Stealing from the push spec I'd imagine a SW registration (assuming the handle payments permission has been granted already) to look like:

// https://example.com/serviceworker.js
this.onpaymentrequest = function(event) {
  // This handler will only be invoked if the user selects the "Acard ***1234" option
}

// https://example.com/webapp.js
const methods = ['basic-card'];
const label = "Acard ***1234"
navigator.serviceWorker.register('serviceworker.js').then(
  function(serviceWorkerRegistration) {
    serviceWorkerRegistration.paymentAppManager.addOption(methods, label).then(
      function(paymentOption) {     
      }, function(error) {
      }
    );
  });

Imagine the following registered in a user's browser:

Origin 1: https://wallet.com
      |- App 1:  Wallet.com App (scope: "./" )
                          |-  Option 1: Acard ****1234
                          |-  Option 2: Bcard ****3456
                          |-  Option 3: Bitcoin
Origin 2: https://banka.com
      |- App 1:  Bank A Business (scope: "./business")
                          |-  Option 1: Credit Transfer
                          |-  Option 2: Bank Cheque
                          |-  Option 3: Corp Card ****4567
      |- App 2:  Bank A Personal  (scope: "./business")
                          |-  Option 1: Acard ****1234
                          |-  Option 2: Loyalty Points

Ignoring manifests and icons for now, to get to this, I'd imagine the following needs to happen:

  1. A webapp at wallet.com is granted permission to handle payments.
  2. A SW at wallet.com is registered and adds Option 1: Acard ****1234
  3. Another SW at wallet.com is registered and adds Option 2: Bcard ****3456
  4. Another SW at wallet.com is registered and adds Option 3: Bitcoin

Note: There is no manifest so there is no icon for wallet.com and all options registered by SWs under this origin are assumed to be under the same "app".

Next...

  1. A webapp at banka.com is granted permission to handle payments.
  2. The browser processes an app manifest for an app called Bank A Business which defines it's scope as https://banka.com/business.
  3. The app manifest points to a SW which, when it is registered registers three additional SWs:
    1. A SW that adds Option 1: Credit Transfer
    2. Another SW that adds Option 2: Bank Cheque
    3. Another SW that adds Option 3: Corp Card ****4567

Note: Without the manifest there is no way to know that these three options are expected to be part of a single "app" as the scope is defined by the manifest and all three SWs are located within the scope of the app.

Also Note: SWs also have a scope and this has to be unique so we must assume each of these SWs will register itself with a unique scope.

Next...

  1. The webapp at banka.com already has permission to handle payments.
  2. The browser processes another app manifest for an app called Bank A Personal which defines it's scope as https://banka.com/personal.
  3. The app manifest points to a SW which, when it is registered registers three additional SWs:
    1. A SW that adds Option 1: Acard ****1234
    2. Another SW that adds Option 2: Loyalty Points

Note: This is a second "app" under the same origin, partitioned from the first using it's scope. This is not a security boundary as the apps are under the same origin but it is a logical boundary which the browser can use when deciding how to present the options to the user (group them under "apps").

marcoscaceres commented 7 years ago

I honestly don't think we need this. Look at how elegantly you can already do profiles in Uber, for instance:

screenshot 2017-02-08 22 33 59

You can just do it in the same app, and the app remembers... that's the whole point of having these be PWAs. Exposing multiple app and profiles doesn't make sense (to me)... it probably doesn't even make much sense to show the payment methods: only the icon for the PWA that handles the payment (again, see above... just pretend Uber is a PWA).

tommythorsen commented 7 years ago

@adrianhopebailie

You are talking about the options and I am talking about apps. The choices presented to a user exist at two levels. The user is presented with a bunch of "apps" and under each app is a bunch of "options". The most common use of options will be to present different instruments that the app has stored.

While the exact presentation should be left up to the implementor of the mediator to decide on, I do agree that providing the mediator with the means to display "app" elements with underlying "option" elements is a good thing.

The challenge then is how do we decide which Service Workers belong to which Web App? Is there any existing method/algorithm we can use for this? Comparing scopes could work, but there are a fair amount of corner cases that can make problems for us. For instance, a Web App can be unbounded. How do we handle this case? A service worker that is registered by a page that belongs to the Web App, can probably also set a scope that is wider than the scope of the Web App. Does the service worker belong in this case, or not?

@marcoscaceres

I honestly don't think we need [Payment Options].

Keeping things simple for V1 of the spec is a good thing. I could probably be convinced to agree to leave the options for a future version. Especially if doing so would simplify things significantly. Unfortunately, omitting Payment Options does not let us sidestep the problem I describe above. We'd still need to figure out which Service Workers belong to which Web App.