- From: Rouslan Solomakhin <notifications@github.com>
- Date: Fri, 06 Oct 2017 16:16:31 +0000 (UTC)
- To: w3c/payment-request <payment-request@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/payment-request/issues/639/334801601@github.com>
> It falls out of some assumptions about the API rather than specific contracts. It's true that the spec does not specify when the scan for the payment apps should happen. There's a fine line between predictability of API behavior and tying the hands of browser manufacturers. I see your point here, though. Perhaps this is good behavior to standardize across browsers, so that web developers can rely on it. @ianbjacobs Can we put this on agenda for the next call or the face-to-face in November? > Right now, it looks like the Payment Handler spec says that handlers receive total. The [`PaymentRequestEvent`](https://www.w3.org/TR/payment-handler/#the-paymentrequestevent) is fired in the selected payment handler when the user clicks the [Pay] button in the browser payment sheet UI. Constructing `PaymentRequest`, calling `canMakePayment()`, or calling `show()` will not trigger the `PaymentRequestEvent`. So the payment handler does not get the `total` until after user consent. I have a [proposal](https://github.com/w3c/payment-handler/pull/170) in the works to optionally fire `CanMakePaymentEvent` in the payment handler. This would be fired during `PaymentRequest` construction while scanning the locally installed payment apps. This event will not contain the `total`. In summary, the corresponding events between the merchant and the payment app are: User | Merchant | Payment Handler --|----------|-------------------------------------------------------------------------------------- Visit page. | `pr = new PaymentRequest();` | App scan: If the payment handler supports [standardized payment method identifier](https://w3c.github.io/payment-method-id/#standardized-payment-method-identifiers) (e.g., `"basic-card"`), then the browser compares merchant's request to capabilities of the payment handler and stores matching payment handlers in `apps` list in memory. If the payment handler supports only [URL-based payment method identifiers](https://w3c.github.io/payment-method-id/#url-based-payment-method-identifiers) (e.g., `https://android.com/pay`), then the browser fires `CanMakePaymentEvent` event in the payment handler and stores the ones that returned `true` in the `apps` list in memory. No action required. | `pr.canMakePayment();` | Wait until app scan completes, then return `!apps.empty()`. Click [Buy_Now] button on the page. | `pr.show();` | Show the payment sheet UI with a "Loading..." spinner, wait until the app scan completes, then show the `apps` in the sheet. Click [Pay] in the browser payment sheet UI. | | Fire `PaymentRequestEvent` in the selected payment handler. > There doesn't seem to be anything stopping a browser from forcing `canMakePayment()` being called before `show()`. This can get a little confusing, so let's clarify a bit. According to the spec, calling `show()` without calling `canMakePayment()` is OK, but calling `canMakePayment()` after calling `show()` on the same instance of `PaymentRequest` will throw `InvalidStateError`. ```javascript // CASE 1: This is fine: pr = new PaymentRequest(); pr.canMakePayment(); pr.show(); // CASE 2: This is also fine: pr = new PaymentRequest(); pr.show(); // CASE 3: This will throw in canMakePayment(): pr = new PaymentRequest(); pr.show(); pr.canMakePayment(); // InvalidStateError ``` Is it possible, however, that a browser implements the PaymentRequest spec correctly, but does not work in `CASE 2` above? The answer is "No". Although this is not explicitly stated in the spec, this is prevented by the definitions of the algorithms for [`canMakePayment()`](https://w3c.github.io/payment-request/#canmakepayment()-method) and [`show()`](https://w3c.github.io/payment-request/#show()-method). The `canMakePayment()` algorithm does not change any internal state, so there's nothing for the `show()` algorithm to check. We can enforce this via an explicit [web platform test](https://w3c-test.org/payment-request/), as well. Note that the opposite is not true. The `show()` algorithm sets the internal field _request_.[[state]] to "interactive" and `canMakePayment()` throws `InvalidStateError` with this state. In practice this means that you can't run `canMakePayment()` after `show()` was called on the same instance of `PaymentRequest`, as shown in `CASE 3` above. I hope this information is useful. Please let me know if I can help with any other concerns you might have. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/w3c/payment-request/issues/639#issuecomment-334801601
Received on Friday, 6 October 2017 16:17:33 UTC