Re: [w3ctag/design-reviews] Payment Handler (#231)

So I've read through the spec, thought about it a bit, and talked to a few colleagues about it.  While I don't consider this a complete review, I've done a bit of thinking at this point, and come up with five architectural questions that I think are worth examining here:

1. Does this API make the right tradeoffs between permissions, extensibility, and user confusion?  In particular, we'd like the web to allow [payment processors](https://w3c.github.io/webpayments-ig/latest/glossary/#dfn-payment-processor) and [payment methods](https://w3c.github.io/webpayments-ig/latest/glossary/#dfn-payment-method) that we don't know about, since allowing more competition is likely to benefit merchants and users.  But at the same time we should consider whether it's a problem if either the merchants or the users to be confused about what payment systems they're using. (see [overview](https://w3c.github.io/payment-handler/#model), points 1 and 5)

2. Does this API make the right tradeoffs in terms of running the necessary level of detail through the API to allow browsers to present users with trusted payment user interface (or, if needed, giving the user the right security indicators about the level of trust) versus letting the payment handler customize what it needs? (see overview, point 7)

3. Does it allow both user-agents and merchants to make choices about whether the user should only be presented with already-configured payment mechanisms, or given the option to set up new ones?  (It doesn't seem to allow setup as part of the overview.)  Or is it at least extensible to allow this in the future?

4. Does it make the right tradeoffs about reusing pieces of technology already present in the platform versus inventing new things?

5. Does this specification introduce new mechanisms for communication between origins that need to be considered carefully?


For background, this spec has a close relationship to three other specs that I'm aware of:  [Payment Request API](https://w3c.github.io/payment-request/), [Payment Method Identifiers](https://w3c.github.io/payment-method-id/), and [Payment Method Manifest](https://w3c.github.io/payment-method-manifest/).  (While this specification doesn't reference Payment Method Manifest, the Payment Method Manifest spec imposes requirements on users of certain Payment Method Identifiers, though I'd note that it's odd that [these requirements](https://w3c.github.io/payment-method-manifest/#use-cases) ("the requirement that every payment method whose identifier is URL-based will provide a payment method manifest file in JSON format") aren't in the Payment Method Identifiers spec.)

The high-level structure of the spec, which I'm writing down since I've been tending to confuse myself if I don't, is that a service worker (together with the code that registers it) can be payment handler if it has instruments registered; it can have multiple instruments, which in turn can each support multiple payment methods.  I had thought that this would mean that something like a credit card would be a payment instrument; however, the userHint property (described as intending to be things like "**** 1234" to remind a user of a card) is associated with the entire payment handler.

### Extensibility, permissions, and UI

So delving a little bit deeper into point (1) above:

It's not clear to me how browsers plan to explain to users what installing a payment handler means.  In particular, will the user need to make judgments about what powers the payment handler has, or only about whether the user wants to allow a particular site to install something that handles payments?  (Will the payment instruments then later be identified with that site when it's time for the user to choose them, perhaps?)  I think the norm today is that payers think primarily in terms of payment instruments and a little bit in terms of what mechanisms that card supports (e.g., I have this card, and maybe that the card supports both credit and debit), whereas payees (merchants) also think in terms of payment methods or processors since they have different costs to the merchant.  So perhaps the user permission issue isn't a big deal, assuming that the intent is the simple form of the question and there's a belief that that form is sufficient.  But if there's a need for the user to understand more detail, then it's not clear to me that this system gives that detail in any form that can be presented to the user as reliable or trustworthy information.

I suppose then there's the related question of whether the identifiers pose risks to merchants.  Presumably if somebody installs a malicious payment handler as a way to cheat merchants, claiming to support a particular payment method that the merchant wants, the expected way to deal with this is that the payment processor and the merchant involved need to validate all the data sufficiently to ensure that they're getting the expected payment.  Given that the merchant can't trust any security checking that the browser does anyway (even if the browser does end up verifying something based on the payment method manifest connected to the identifier), this seems like it has to be the answer.  Perhaps that should be called out a little more clearly in the section on security considerations?

### Detail and user interface

Based on the user interface I've seen so far, I'm more concerned about point (2).  The current experimental Chrome user interface includes UI from the payment handler within what looks like privileged browser UI.  For example, if you:

 * go to [chrome://flags](chrome://flags) and enable "Service Worker payment apps"
 * go to [BobPay](https://bobpay.xyz/) and click "Install BobPay Web Payment App" in the lower right
 * go to the [BobPay Demo](https://rsolomakhin.github.io/pr/bob/) from the [list of demos](https://rsolomakhin.github.io/pr/apps/)
 * click the "Buy" button
 * click the "Pay" button in the browser chrome sheet that pops down

you'll currently end up seeing Web Content inside browser chrome UI (screenshot courtesy @marcoscaceres via https://github.com/mozilla/standards-positions/issues/23#issuecomment-372537251):

<img width="657" alt="screenshot_2018-03-12_23_43_31" src="https://user-images.githubusercontent.com/870154/37321106-f0577f1c-26ca-11e8-86e5-c7f91eb7c16f.png">

This is explicitly described in the [2.1 Handling a Payment Request](https://w3c.github.io/payment-handler/#handling-a-payment-request) which says:

<blockquote>Handling a payment request may include numerous interactions: with the user through a new window or other APIs (such as [WebCryptoAPI]) or with other services and origins through web requests or other means.</blockquote>

This UI raises a number of questions.  Does this UI from the payment handler's origin that is shown within the browser chrome have the usual permissions that web pages have, or more, or less?  What happens if it asks for permissions that require prompts?  Does it share things like permissions and storage with regular tabs from the origin, or are they somehow different?  Does it influence computations that depend on whether and how long the user is interacting with a page from the origin?  Does it honor settings like private browsing mode?  And there are many more questions like this.  It's concerning because it's a new sort of UI, adding new complexity in an area where user interface is closely connected to origins and to the parts of the web's security model that we hope the web's users will understand.

It's not clear to me that this sort of user interface will be accepted across browser vendors; in fact I suspect it will not be.  That raises the next question:  why is this user interface needed?  And would passing additional data through the payment handler API allow the browser to present the necessary information to the user in a way that could avoid this user interface... or at least avoid every having to present it in privileged UI rather than as a regular web page?  If additional API surface is needed, should it be added?

### Configured vs. new payment mechanisms?

On point (3), it doesn't seem like this specification offers a mechanism for the user to configure a new payment handler if none are currently available.  However, it seems at least worth making sure the system could be extended to allow that if it becomes desirable.  It seems to me that payment method manifest would allow such an extension, since the payment request contains payment method identifiers that should allow locating a payment method manifest.  So I don't think this is something to worry about, but I wanted to check that others agree.

### Reusing existing pieces of the platform vs. making new ones?

There are a number of places where parts of this specification are closely modeled on existing mechanisms in the ServiceWorker specification.  That seems like a good thing.

I'm a little worried, however, about the proliferation of manifest formats, and (as mentioned above) the proliferation of ways of specifying icons.

### Communication between origins?

One other question I had ((5) above) was whether this introduces new mechanisms for communication between origins that don't exist today.  In particular, I'm wondering about the ability of the CanMakePayment event to communicate with a payment handler installed by another origin (without triggering any immediate network traffic).  It's not clear to me whether this is something Service Workers allow today (I'm not particularly knowledgable on handling of cross-origin requests by Service Workers) or whether there are other features of the Web that already allow similar things.  This is a concern that may be trivial to refute by demonstrating that it's something already allowed, but if it's not, it may be worth thinking about more closely.

### Other

A few other details:
- I'm slightly concerned that [2.3 Relation to Other Types of Payment Apps](https://w3c.github.io/payment-handler/#relation-to-other-types-of-payment-apps) talks about connections to native payment apps, yet I'm not aware of a spec that explains how such apps relate to payment method identifiers and payment method manifests.
- It might be worth discussing [`PaymentManager.requestPermission()`](https://w3c.github.io/payment-handler/#requestpermission-method) and its relationship to disputes over the Permissions API.  It's also poor form for a "NOTE" (at the start of the section) to modify the requirements in normative text (item (4) in the list); instead the normative text should be modified accordingly.
- the issue of specifying icons discussed above
- I wonder if the `PaymentInstruments.get()` method should resolve to `null` rather than `undefined` when there isn't an instrument.  I think at the very least WebIDL supports this better (`Promise<PaymentInstrument?>` rather than `Promise<any>`) though I'm not sure what conventions are.  It seems like some specs go both ways, e.g., [`Clients.get()`](https://w3c.github.io/ServiceWorker/#clients-interface) and [`ServiceWorkerContainer.getRegistration()`](https://w3c.github.io/ServiceWorker/#navigator-service-worker-getRegistration) resolve to undefined, but [`Clients.openWindow()`](https://w3c.github.io/ServiceWorker/#clients-openwindow), [`CredentialsContainer.get()`](https://w3c.github.io/webappsec-credential-management/#credentialscontainer), and [`PushManager.getSubscription()`](https://w3c.github.io/push-api/#pushmanager-interface) resolve to null.  I suspect the [design principles document](https://w3ctag.github.io/design-principles/) ought to say something about `undefined` vs `null`, although maybe there's a subtle semantic difference here that I'm missing.
- step 1 of the [`set()` method](https://w3c.github.io/payment-handler/#set-method) needs to specify needs to specify the permission descriptor type (i.e., which permission) (and also the link is broken)
- is it ok that step 3 of the [`set()` method](https://w3c.github.io/payment-handler/#set-method) returns a promise that's already rejected?
- is it ok that step 6 of the [`set()` method](https://w3c.github.io/payment-handler/#set-method) sets an internal slot on a dictionary?  What does that mean, especially since the dictionary is then stored into what is described only informally as a collection.
- Given what step 3 of the [`keys()` method](https://w3c.github.io/payment-handler/#keys-method) says, step 8 of the [`set()` method](https://w3c.github.io/payment-handler/#set-method) should probably say append rather than insert.
- there are a number of places (e.g., `PaymentInstrument.name`) where this specification has APIs involving text that is to be presented to the user.  Are there going to be issues with localization or internationalization with this?  That is, is the assumption that localization can be done prior to registration of the service worker safe, and is the assumption that only plain text will be sufficient for internationalization correct?
- The [Convert image objects section](https://w3c.github.io/payment-handler/#convert-image-objects) seems to repeatedly say "return an empty Sequence of `ImageObject`" (which means that the entire algorithm returns an empty list because of the failure of just one of the images) when it means to say [continue](https://infra.spec.whatwg.org/#iteration-continue).
- [`ExtendableEvent`](https://w3c.github.io/ServiceWorker/#extendableevent) and [`ExtendableEventInit`](https://w3c.github.io/ServiceWorker/#dictdef-extendableeventinit) aren't hyperlinked, but should be.
- Is `CanMakePaymentEvent.respondWith` intended to integrate with the [extend lifetime promises](https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises) of the ExtendableEvent?  The [definition](https://w3c.github.io/payment-handler/#respondwith-method) seems rather short.  See, for example, the definition of [`FetchEvent.respondWith()`](https://w3c.github.io/ServiceWorker/#fetch-event-respondwith), or even `PaymentRequestEvent.respondWith()`.
- steps 2 ("Let registration be a ServiceWorkerRegistration.") and 3 ("If registration is not found, terminate these steps.") of [4.3 Handling a CanMakePaymentEvent](https://w3c.github.io/payment-handler/#handling-a-canmakepaymentevent) don't seem to make sense together.  It seems like something ought to be describing which service workers should have the event dispatched, perhaps by integrating with [4.5 Filtering of Payment Instruments](https://w3c.github.io/payment-handler/#filtering-of-payment-instruments)?
- the defitions of [`topLevelOrigin`](https://w3c.github.io/payment-handler/#toplevelorigin-attribute) and [`paymentRequestOrigin`](https://w3c.github.io/payment-handler/#paymentrequestorigin-attribute) should probably refer to the *serialization* of the origin.  ([5.4 Handling a PaymentRequestEvent](https://w3c.github.io/payment-handler/#handling-a-paymentrequestevent) gets this right.)
- should the [Open Window Algorithm](https://w3c.github.io/payment-handler/#open-window-algorithm) also integrate with the extend lifetime promises?
- in the Open Window Algorithm, the reference to being "triggered by user activation" seems like it might be misplaced; do the normal uses of this API actually meet this definition?
- the Open Window Algorithm doesn't seem to allow the behavior suggested in the earlier note: "A single payment handler SHOULD NOT be allowed to open more than one client window using this method."  It seems like it should give the UA rather more discretion about when opening windows is allowed (likely even more than the note allows).
- The Open Window Algorithm should probably be clearer about what its parameters are (both in the algorithm and at its caller).
- [8. Security and Privacy Considerations](https://w3c.github.io/payment-handler/#security) says: "The API does not share information about the user's registered payment handlers. Information from origins is only shared with the payee with the consent of the user."  I'm struggling to understand how this is the case; doesn't `CanMakePaymentEvent` allow this?  And is it clear to the user what information is being shared with whom?
- Likewise, the meaning of "Similarly, user agents should not share payment request information with any payment handler until the user has selected that payment handler." isn't clear to me in the presence of `CanMakePaymentEvent`.
- [8.4 Payment App Authenticity](https://w3c.github.io/payment-handler/#payment-app-authenticity) sounds good, but it's not clear if this specification describes a mechanism that allows it to be enforced.  More detail would be helpful.
- [8.5 Supported Origin](https://w3c.github.io/payment-handler/#supported-origin) should link to the normative text that it refers to.
- [8.6 Data Validation](https://w3c.github.io/payment-handler/#data-validation) should probably be expanded a good bit; shouldn't payees also validate against data from a connection they have to the payment processor in many cases?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/231#issuecomment-377645336

Received on Friday, 30 March 2018 23:28:42 UTC