Multiple payment apps per origin #98

Open
adamroach opened this Issue Jan 23, 2017 · 79 comments

Comments

Projects
None yet
9 participants
Contributor

adamroach commented Jan 23, 2017

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.

Member

tommythorsen commented Jan 24, 2017

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?

Member

marcoscaceres commented Jan 24, 2017

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

Member

marcoscaceres commented Jan 24, 2017

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.

Member

marcoscaceres commented Jan 24, 2017

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.

@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.

Member

marcoscaceres commented Jan 24, 2017

Contributor

ianbjacobs commented Jan 24, 2017

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

Member

marcoscaceres commented Jan 24, 2017

Contributor

ianbjacobs commented Jan 24, 2017

@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

Contributor

adamroach commented Jan 24, 2017

@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]

Contributor

adrianhopebailie commented Jan 24, 2017

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.

Contributor

adamroach commented Jan 24, 2017

@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.

Member

marcoscaceres commented Jan 25, 2017 edited

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.

Contributor

adamroach commented Jan 25, 2017

@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.

Member

marcoscaceres commented Jan 25, 2017

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.

  • Unnecessary complexity: it's a super edge case, and can be solved using a different origin.
  • Each requires its own name/icon(s): requires differentiating between different type of "apps" - adds more complexity; introduces yet more icons, names, etc. to the platform.
  • Confusing: revoking payment handling permission for "PayPal.com" disables multiple payment handlers.
Contributor

adrianhopebailie commented Jan 25, 2017

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

Contributor

adrianhopebailie commented Jan 25, 2017

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.
Contributor

ianbjacobs commented Jan 25, 2017

@adrianhopebailie, you wrote:

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

Please say more about versioning in this case.

Ian

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

Member

marcoscaceres commented Jan 25, 2017

@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.

Member

marcoscaceres commented Jan 25, 2017

Contributor

adamroach commented Jan 25, 2017

@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."

Contributor

adamroach commented Jan 25, 2017 edited

@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.

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.

Member

marcoscaceres commented Jan 27, 2017 edited

@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.

Contributor

ianbjacobs commented Jan 27, 2017

@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:

  • "A payment app [that conforms to this specification] is a web application..."

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

  • "that is registered to handle requests for payment via one or more payment methods."
    Ok.

  • "Payment methods are processed via one or more service workers".

    I would avoid the word "processed" because "payment processing" may be interpreted
    a particular way in the payments industry.

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:

  • +1 to requiring consent when the payment app is first registered
  • -1 to requiring consent every time the payment app's capabilities change.

Ian

Member

marcoscaceres commented Jan 27, 2017 edited

(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.

Contributor

ianbjacobs commented Jan 27, 2017

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."

Member

marcoscaceres commented Jan 27, 2017

"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).

Contributor

ianbjacobs commented Jan 27, 2017

@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

Member

marcoscaceres commented Jan 27, 2017

"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! ❤️

@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 Jan 27, 2017 edited

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.

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.

Contributor

adrianhopebailie commented Jan 31, 2017

@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 Jan 31, 2017 edited

@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.

Contributor

adrianhopebailie commented Jan 31, 2017

@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 Jan 31, 2017 edited

@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).

Member

tommythorsen commented Feb 6, 2017 edited

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.

Member

marcoscaceres commented Feb 6, 2017

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

Member

marcoscaceres commented Feb 6, 2017

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.

Member

tommythorsen commented Feb 7, 2017

@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?

Contributor

adrianhopebailie commented Feb 7, 2017

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.

Member

tommythorsen commented Feb 7, 2017

@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?

Contributor

adrianhopebailie commented Feb 7, 2017

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...

Member

tommythorsen commented Feb 7, 2017

@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 w3c#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.

Contributor

adrianhopebailie commented Feb 7, 2017

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 w3c#98 (comment) 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").

Member

marcoscaceres commented Feb 8, 2017

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).

Member

tommythorsen commented Feb 8, 2017

@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.

Member

marcoscaceres commented Feb 8, 2017

Sorry, to clarify: I support having payment options. I'm just not sure they will be shown together with the payment app. Anyway, I don't want us to discuss possible browser UI - as it's outside the scope of the standardization effort.

Contributor

adrianhopebailie commented Feb 8, 2017

@marcoscaceres I have created this page for us to do as you suggested and jot down some sample code in one place to help us get clarity: https://github.com/w3c/webpayments-payment-apps-api/blob/gh-pages/proposals/examples.md

To clarify, are you suggesting that the options may not be grouped together at all? I thought your mock-ups above were a good indicator of how things may be rendered. Obviously this is up to browsers but if they want to group options under an origin/app then we need to make sure that is possible.

Contributor

adrianhopebailie commented Feb 8, 2017

@tommythorsen your input on the page above would also be valuable. Let's use PRs to push new changes but feel free to merge your own changes if they don't conflict.

Member

marcoscaceres commented Feb 8, 2017

To clarify, are you suggesting that the options may not be grouped together at all? I thought your mock-ups above were a good indicator of how things may be rendered.

The more I experiment with different apps and ideas, the less appealing I find the idea of showing then all together outside an application (why I showed the Uber example). See also eBay + PayPal together (specially if you have multiple payment and shipping addresses etc. registered). I hear Stripe provides an even nicer experience - but haven't had the opportunity to use it.

Would love for us to collect more screenshots of existing solutions - so to see if this problem is well solved or not.

Obviously this is up to browsers but if they want to group options under an origin/app then we need to make sure that is possible.

Agree - and working with Mozilla's UX/UI team on that... but it might turn out that beyond the details of the payment method (i.e., the credit card number), icons etc. might be best just left to the payment app itself ( I don't have a strong opinion - just a gut feeling).

Consider, management of the payment methods is done in the app itself - not by the browser. The browser can tell the user about the permission to use the API, and how many methods are registered, but managing of those methods (add, update, delete, etc.) would need to happen inside the web app - this is because payment methods differ from one app to another (credit card VS bit coin VS magic token VS whatever).

Contributor

ianbjacobs commented Feb 14, 2017

Some notes:

  • AdamR is going to write a proposal for a payment app to provide the UA with option information. This also relates to #69 and how we provide icon/label information for options.
  • The group has consensus (9 Feb 2017 WPWG call) that we should NOT require UAs to display option information provided by the payment app.
Member

marcoscaceres commented Feb 15, 2017

The group has consensus (9 Feb 2017 WPWG call) that we should NOT require UAs to display option information provided by the payment app.

Can you clarify the above - I don't understand what that means?

Contributor

ianbjacobs commented Feb 15, 2017

Hi @marcoscaceres,

We are still discussing the topic what the browser shows to the user (and how much detailed information the payment app might want to supply) so that the user can choose a payment app to pay. Although that topic is still open, we have consensus that IF we support the payment app providing detailed options to the browser, the browser is NOT REQUIRED to ALWAYS display that
detailed information. For example, the browser might choose to display it on desktop but not on mobile.

AdamR is working on a proposal that enables the payment app to provide information to the browser, which can then choose whether and when to make use of it to improve the user
experience.

Ian

Member

tommythorsen commented Feb 16, 2017

@ianjacobs, @adrianhopebailie, @marcoscaceres and others: I have spent some time reading the specs and thinking about how we can connect Payment Apps and Service Workers / Payment Options, and I've written down a few thoughts and some very rough algorithms here: https://github.com/tommythorsen/webpayments-demo/blob/gh-pages/proposals/Apps%20and%20Workers.md

WDYT?

"Service workers can be identified by scope"
This one has been an accepted truth in the Working Group for some time, but after reading the Service Workers specification, I have come to believe that this is not true.

It is true. See https://w3c.github.io/ServiceWorker/#register-algorithm - at 4 it gets an existing registration of that scope and updates it if it exists. This ensures you can't register two service workers with the same scope.

The Service Worker does however have a unique id field

This isn't useful for payments. You don't want to associate an app with a service worker, you want to associate with a service worker registration, otherwise you'll lose payment apps during a service worker update.

Even though current implementations may only allow for one Service Worker per scope, this issue leads me to think that we should not assume this will always be the case.

If we do something about that issue, we won't be adding multiple registrations for a single scope. APIs already assume that scope to registration is 1:1, eg https://w3c.github.io/ServiceWorker/#navigator-service-worker-getRegistration.

Member

tommythorsen commented Feb 16, 2017

Aha, I had missed that part of the algorithm. Thanks @jakearchibald! I'll update my text. This won't actually make any difference for the algorithms, though, since we can't match this scope against those of the Service Workers.

Hmm, what have I missed? I thought we agreed that payment apps should be identified by their service worker scope, since they're stored against the service worker registration.

Member

tommythorsen commented Feb 16, 2017

That was true a couple of iterations ago. Since then, we've redefined the term "Payment App". It used to mean "a Service Worker that can handle payments", but it now means "a Web App that can handle payments". The service workers are still used to register Payment Options and subscribe to Payment Request events, though.

Is there a summary for this change including reasons?

Contributor

ianbjacobs commented Feb 16, 2017

Here's a running summary of key issues and where I think we have consensus (and don't):
https://github.com/w3c/webpayments-payment-apps-api/wiki/Proposal-20170130

On this topic specifically:

  • We are currently planning to identify payment apps by their origin
  • However, we are still discussing use cases where a given origin may wish to display different "wallets" (for lack of a better word for now) to the user, and whether we need to support those use cases (and how).

Ian

Member

tommythorsen commented Feb 16, 2017 edited

Also @dlongley's comment from earlier in this thread was a pretty good explanation.

@ianbjacobs

We are currently planning to identify payment apps by their origin

I mention this particular statement in the introduction to my proposal document. I have no idea how identifying apps by their origin could ever work, and I strongly suggest we consider some other form of identifier. I propose to use the url to the Web App Manifest file.

Contributor

ianbjacobs commented Feb 16, 2017

Here is my understanding of where we have arrived:

  • We have discussed two use cases where we need to compare identifiers:

    • Payment app recommendations. ("Has the user already registered this payment app?")
    • Payment app permissions from payment method manifest files. ("Hey browser, you are
      authorized to let people register this payment app to support this payment method that
      I own.")

    Both of these use cases ultimately relate to permissions, and for both of these I have understood
    that origin information suffices. Thus, there is no need here for a new kind of "payment app
    identifier"; we can just use origins.

  • We also have discussed "how do people find the code of a Web-based payment app?" One way is
    that they follow a URL, which loads code which does everything that's necessary. In this
    scenario, there is no special new kind of "payment app identifier"; there is just a URL to some
    code. And there might be different code bases on the same origin.

  • We have also discussed this question: "If we refer to a payment app by origin, how can someone
    get from origin information to the code of a Web-based payment app?" One tentative answer
    has been: use script_url in Web App Manifest.

My summary, therefore, is that there is not currently a need for a special "payment app identifier."
For matching, we use origin. For finding code, we use ordinary URLs.

(I welcome comments on whether this is a fair summary, what is missing, etc.)
Ian

Contributor

adrianhopebailie commented Feb 16, 2017

Both of these use cases ultimately relate to permissions, and for both of these I have understood
that origin information suffices. Thus, there is no need here for a new kind of "payment app
identifier"; we can just use origins.

This is the key IMO. Well put.

It seems that what many of us are calling "apps" only ever have to identified explicitly as "user choices". If I re-write my set of choice from before it would look like this:

Origin 1: https://wallet.com
      |- Option 1:  Wallet.com
                          |-  Option 1.1: Acard ****1234
                          |-  Option 1.2: Bcard ****3456
                          |-  Option 1.3: Bitcoin
Origin 2: https://banka.com
      |- Option 1:  Bank A Business
                          |-  Option 1.1: Credit Transfer
                          |-  Option 1.2: Bank Cheque
                          |-  Option 1.3: Corp Card ****4567
      |- Option 2:  Bank A Personal 
                          |-  Option 1.1: Acard ****1234
                          |-  Option 1.2: Loyalty Points

What is not clear to me yet is what combination of Service Worker registration code and calls to PaymentManager.addOption(...) or similar would result in this set of options being presented to a user (assuming the browser wanted to present the full depth of options).

Member

tommythorsen commented Feb 16, 2017

I disagree with the "A Payment App is an origin" definition that you are arguing above. I really liked the "A Payment App is a Web App that can do payments" definition that I thought we had some consensus on. I think most people's idea of the concept "Web App", is that it is the collection of web pages that are related to a particular Web App Manifest. I think most people think of a "Web App" as the thing you can install to the home screen of your phone if you're on a page that links to such a manifest. I think most people do not think that a "Web App" is an origin.

I know the permissions model works on origins but that, I believe, is unrelated to the concept of a "Web App" and to the concept of a "Payment App".

@ianbjacobs

We have also discussed this question: "If we refer to a payment app by origin, how can someone
get from origin information to the code of a Web-based payment app?" One tentative answer
has been: use script_url in Web App Manifest.

  1. How do you plan to get from the origin information to the Web App Manifest? Bear in mind my earlier examples that show that there can be multiple Web App Manifests within a single origin.
  2. How does the script_url relate to a Payment App?

@ianbjacobs

there is not currently a need for a special "payment app identifier."

I agree with this. But in my opinion, the above statement is not compatible with your earlier statement: "We are currently planning to identify payment apps by their origin".

Any disagreements we have here are likely to be caused by us having differing definitions of the term "Payment App" or of the term "Web App". If I seem to be spouting complete gibberish, please take a moment to consider your definitions, and whether or not they match mine, which I have laid out in the initial paragraph of this comment.

Contributor

adamroach commented Feb 17, 2017

@adrianhopebailie -

What is not clear to me yet is what combination of Service Worker registration code and calls to PaymentManager.addOption(...) or similar would result in this set of options being presented to a user (assuming the browser wanted to present the full depth of options).

This is exactly what I hope to address in my PR. I should have a concrete proposal to talk about on our call on Tuesday.

dlongley commented Feb 17, 2017 edited

@adrianhopebailie said:

It seems that what many of us are calling "apps" only ever have to identified explicitly as "user choices".

I agree with this. All we need to do is specify:

  1. How a developer can declare these choices so the browser can surface them in the UI, and
  2. How the developer can write code to receive an event with the user's particular selection information.

I think origins and permissions are orthogonal to this particular problem. We already have a clear model for those: An origin requests permission to "handle payment" -- and, if granted, they may then specify whatever choices they want, whenever they want to (they can change them at will).

We just need to pin down exactly what the API looks like for specifying choices and how the browser will communicate user selections back to the developer in a way that they expect. There is a secondary piece to the "how developers specify choices" which involves the ability to group choices so users can make more fine grained selections if the browser wants to expose this in their UI (but it likely isn't a requirement). @adrianhopebailie's comment shows an example of this.

I don't know that we even care what the identifiers are for the choices. Those could be left entirely up to the developer. All that needs to happen is the browser must effectively communicate them back to the developer once a user has made their selection. What is important is that the developer knows how to write the code to receive the selections.

It may be that a particular Service Worker registration.paymentManager will be used to specify payment options and that same Service Worker will receive user selection events for those options (if the user chose them). That keeps it simple. What the Service Worker does after it receives those events is totally up to the developer, provided that their code, wherever it lives, ends up passing back a payment response via the appropriate API. It may be that for a particular choice, all the logic for specifying that choice, capturing a user selection event, and sending back a payment response will all happen in the same Service Worker. That doesn't mean a "Payment App is a Service Worker", it just means that the part of a Payment App that needs to communicate with the browser's payment UI/mediator appropriately reuses that component of the Web Platform.

Member

tommythorsen commented Feb 17, 2017

@adrianhopebailie

What is not clear to me yet is what combination of Service Worker registration code and calls to PaymentManager.addOption(...) or similar would result in this set of options being presented to a user (assuming the browser wanted to present the full depth of options).

Yes, this is what we need to figure out next. My proposal suggests that the second level of your hierarchy comes from the Web App Manifest, and that the third level is provided (by means of PaymentManager.addOption(...)) by one or more Service Workers that belong to the Web App.

jakearchibald commented Feb 17, 2017 edited

If an origin is an installed payment app, and that origin has 10 service worker registrations, which service worker gets the paymentrequest event? My understanding is that it'd be the active service worker in the service worker registration that was used in the call to setManifest (or whatever the registering call is now).

What happens if that service worker registration is unregistered? Is the payment app still installed? My understanding is the payment app would no longer be installed, as it no longer has somewhere to fire the paymentrequest event.

If my understanding is correct, there's a very definite 1:1 relationship between a payment app and a service worker registration. Given that a service worker registration has a primary key in the form of its scope URL, this is the only straight-forward way to identify an installed payment app.

Don't be distracted by permissions. Just because a permission is origin-level doesn't mean an instance of the feature is. Take notifications - the permission is origin level, but there can be many notifications from an origin at once. Also, although there's one push origin permission, each service worker registration can have its own push registration, and they're tied to the life of the service worker registration.

Don't be distracted with "recommended payment apps". As far as I know, no one has been able to define how this could happen without presenting large security issues w3c#48 (comment).

Don't be distracted by doing work across multiple service workers for a single payment. If the payment app chooses to open a window, it can do so to any page on its origin. That means the page could be controlled by another service worker to the one that owns the payment app registration. Also, one service worker can message the others on the same origin. However, the payment app is still registered against a particular service worker registration.

Don't get hung up on the definition of a "web app". Some web apps take up a whole origin, some origins have many. Some web apps have zero service workers, some have one, some have many. Hell, some service workers span across multiple apps. Ignore all that, the definition is fuzzy. This group should define how a website can register a web payment provider, independent to whatever concept the developer has of a "web app".

@jakearchibald,

If my understanding is correct, there's a very definite 1:1 relationship between a payment app and a service worker registration.

A developer may want to group multiple payment options under a single "Payment App", but implement different options via different service worker registrations.

A Payment App may have more than one payment option that it registers. Imagine a scenario where the Payment App uses two service worker registrations, A and B. Service worker registration A could register payment option 1 and, therefore, its active service worker will receive the paymentrequest event for it, should the user select it. Service worker registration B could register payment option 2 and, therefore, its active service worker would receive the paymentrequest event for it.

As long as some payment option is registered for a particular Payment App and the service worker registration persists, then the Payment App is "installed".

A developer may want to group multiple payment options under a single "Payment App", but implement different options via different service worker registrations.

What's the benefit of allowing this (given the massive complication it brings)?

dlongley commented Feb 17, 2017 edited

@jakearchibald,

What's the benefit of allowing this (given the massive complication it brings)?

Seems like a natural division of code. As a developer, you may want to implement payment method X in service worker script /payment-methods/x.js and payment method Y in service worker script /payment-methods/y.js. Wouldn't a developer be surprised if they couldn't do that -- or if by doing that it meant that they couldn't group related options under the banner of a single "Payment App" for display to the user?

I think the difficulty here may still be related to the terminology. I think we should stick to saying that what we register is a "payment option" -- and when the user selects that payment option, a paymentrequest event is emitted to the thing that did the registering. Ideally, the developer could group these payment options however they'd like to give the user a collective sense of using a single "Payment App". I would think that where the events go is just bound to who does the registering, not to the meta data that declares how to logically group the options for the end user.

So, from that perspective, I don't understand why we should force the developer to divide their code such that all options that will be grouped together must be handled via the same script. However, if this restriction is required in order to avoid "massive complication", then it's worth imposing it. I just don't know what "massive complication" you're referring to.

Thinking through it further now, I can see an unfortunate complication -- that only arises, I believe, from the fact that we don't plan on requiring browsers to surface more granular options. If we register these payment options from @adrianhopebailie's example above:

Origin: https://banka.com
      |- Option 1:  Bank A Business
                          |-  Option 1.1: Credit Transfer
                          |-  Option 1.2: Bank Cheque
                          |-  Option 1.3: Corp Card ****4567
      |- Option 2:  Bank A Personal 
                          |-  Option 1.1: Acard ****1234
                          |-  Option 1.2: Loyalty Points

One browser may surface these as simply:

- Bank A Business (banka.com)
- Bank A Personal (banka.com)

While another may show the full granularity of the options for user selection. Given this fact, it will be difficult for a developer to know which service worker script would receive the paymentrequest event when more granular options aren't made available to the user. 😢 That's a good reason to restrict payment option groups to a single service worker registration.

Service workers can already import scripts, and that gets even easier with es6 imports. So it isn't true that we'd be forcing developers to use the same script.

The benefit of spreading payment options across multiple service workers isn't really clear, and doesn't fit in with how other service worker APIs work. Feels like we need stronger reasoning given how much this complicated the API.

By adopting something that wraps service workers, you're now having to define a whole new life cycle. Also, developers will have to manage the life cycle of service workers within this life cycle.

I think this complicated approach makes implementations unlikely.

dlongley commented Feb 17, 2017 edited

@jakearchibald,

Service workers can already import scripts, and that gets even easier with es6 imports. So it isn't true that we'd be forcing developers to use the same script.

I didn't mean to imply that there wasn't an alternative route to accomplishing code division, but we are closing off one route for doing it. My default position is: Don't close off routes for developers unless you have a good reason to. If there would be "massive complication" if we didn't close off one route then that's a perfectly good reason to do it, especially when we can offer the developer a slightly different alternative to what they'd like to do. I'm just not sure what the massive complication is that you're referring to. However, I have specified a concrete complication above that I think is sufficient to warrant restricting payment option registration in the way that you suggest. So we're in agreement now, but perhaps for different reasons.

By adopting something that wraps service workers, you're now having to define a whole new life cycle. Also, developers will have to manage the life cycle of service workers within this life cycle.

My suggestion above was not to wrap service workers, it was to decouple grouping information. It was to simply let the developer say, in a service worker registration:

"Offer this option to the user and show it under the banner of payment app X."

If no service worker registrations exist with payment options for payment app X, then nothing is shown under payment app X (it doesn't exist). There is no additional life cycle beyond service workers and nothing new to manage.

Anyway, this doesn't work because some browsers may only implement choosing the Payment App directly, not granular choices underneath its "banner" -- and then the developer wouldn't know where to expect to receive paymentrequest events.

Contributor

ianbjacobs commented Mar 21, 2017

Closing this issue as new mechanism ("wallet") has been added to the spec.

ianbjacobs closed this Mar 21, 2017

Contributor

ianbjacobs commented Apr 13, 2017

In light of FTF discussion on 24 April [1], I am reopening this issue in order to put a marker in the FPWD.

[1] https://www.w3.org/2017/03/24-wpwg-minutes#item01

ianbjacobs reopened this Apr 13, 2017

ianbjacobs added this to the Mark in FPWD milestone Apr 13, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment