From 8b6561fde3cf5de3841ceae47ae08c19578af0af Mon Sep 17 00:00:00 2001 From: Rouslan Solomakhin Date: Tue, 6 Jun 2017 11:59:03 -0400 Subject: [PATCH 1/5] Add CanMakePaymentEvent. --- index.html | 291 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 274 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index aeaaeed..b3b5f6e 100644 --- a/index.html +++ b/index.html @@ -133,7 +133,7 @@

operating-system specific mechanisms (e.g., "native mobile apps") handle payment requests.

-

+

The term "payment app" may be useful as a shorthand for "Web app that can handle payments with Payment Request API."

@@ -208,13 +208,14 @@

  • When the merchant (or other payee) calls the - [[payment-request]] method show() (e.g., when the user pushes a - button on a checkout page), the user agent computes a list of candidate - payment handlers, comparing the payment methods accepted by the - merchant with those supported by registered payment handlers. For - payment methods that support additional filtering, merchant and payment - handler capabilities are compared as part of determining whether there - is a match. + [[payment-request]] method canMakePayment() or show() + (e.g., when the user pushes a button on a checkout page), the user + agent computes a list of candidate payment handlers, comparing the + payment methods accepted by the merchant with those supported by + registered payment handlers. For payment methods that support + additional filtering, either merchant and payment handler capabilities + are compared or CanMakePaymentEvent is used as part of + determining whether there is a match.
  • The user agent displays a set of choices to the user: the registered instruments of @@ -357,7 +358,11 @@

    partial interface ServiceWorkerRegistration { readonly attribute PaymentManager paymentManager; }; - + +

    + The paymentManager attribute exposes payment handler + functionality in the service worker. +

    @@ -368,7 +373,7 @@

    interface PaymentManager { [SameObject] readonly attribute PaymentInstruments instruments; [Exposed=Window] static Promise<PermissionState> requestPermission(); - attribute DOMString userHint; + attribute DOMString userHint; };

    @@ -913,6 +918,84 @@

    limited number of display requirements; most user experience details are left to implementers.

    +
    +

    + Filtering of Payment Instruments +

    +

    + Given a PaymentMethodData and a PaymentInstrument that + match on payment method identifier, this algorithm returns + true if this instrument can be used for payment: +

    +
      +
    1. Let instrument be the given PaymentInstrument. +
    2. +
    3. Let methodName be the payment method identifier + string specified in the PaymentMethodData. +
    4. +
    5. Let methodData be the payment method specific data of + PaymentMethodData. +
    6. +
    7. If methodName is a standardized payment method + identifier, filter based on capabilities: +
        +
      1. For each key in methodData: +
          +
        1. If the intersection of methodData[key] and + instrument.capabilities[key] is empty, return + false. +
        2. +
        +
      2. +
      3. Otherwise, return true. +
      4. +
      +
    8. +
    9. Otherwise, fire the CanMakePaymentEvent in the payment + handler and return the result. +
    10. +
    +
    +

    + How to specify capabilities +

    +

    + Example of how a payment handler should provide the list of all its + active cards to the browser. +

    +
    +          await navigator.serviceWorker.register('/pw/app.js');
    +          const registration = await navigator.serviceWorker.ready;
    +          registration.paymentManager.userHint = '(Visa ****1111)';
    +          await registration.paymentManager.instruments.set(
    +            '12345',
    +            {
    +              name: "Visa ****1111",
    +              icons: [{
    +                src: '/pay/visa.png',
    +                sizes: '32x32',
    +                type: 'image/png',
    +              }],
    +              enabledMethods: ['basic-card'],
    +              capabilities: {
    +                supportedNetworks: ['visa'],
    +                supportedTypes: ['credit'],
    +              },
    +            });
    +          
    +

    + In this case, new PaymentRequest([{supportedMethods: + 'basic-card'}], shoppingCart).canMakePayment() should return + true because there's an active card in the payment + handler. Note that new PaymentRequest([{supportedMethods: + 'basic-card', data: {supportedTypes: ['debit']}}], + shoppingCart).canMakePayment() would return + false because of mismatch in + supportedTypes in this example. +

    +
    +

    Ordering of Payment Handlers @@ -1005,6 +1088,163 @@

    +
    +

    + Can make payment +

    +

    + If the payment handler supports CanMakePaymentEvent, the + user agent may use it to help with filtering of the available + payment handlers. +

    +

    + Implementations may impose a timeout for developers to respond to the + CanMakePaymentEvent. If the timeout expires, then the + implementation will behave as if respondWith() was called with + false. +

    +
    +

    + Extension to ServiceWorkerGlobalScope +

    +

    + This specification extends the ServiceWorkerGlobalScope + interface. +

    +
    +        partial interface ServiceWorkerGlobalScope {
    +          attribute EventHandler oncanmakepayment;
    +        };
    +        
    +
    +

    + oncanmakepayment attribute +

    +

    + The oncanmakepayment attribute is an event handler + whose corresponding event handler event type is + canmakepayment. +

    +
    +
    +
    +

    + The CanMakePaymentEvent +

    +

    + The CanMakePaymentEvent is used to check whether the payment + handler is able to respond to a payment request. +

    +
    +        [Constructor(DOMString type, CanMakePaymentEventInit eventInitDict), Exposed=ServiceWorker]
    +        interface CanMakePaymentEvent : ExtendableEvent {
    +          readonly attribute USVString topLevelOrigin;
    +          readonly attribute USVString paymentRequestOrigin;
    +          readonly attribute FrozenArray<PaymentMethodData> methodData;
    +          readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
    +          void respondWith(Promise<boolean>canMakePaymentResponse);
    +        };
    +        
    +

    + The topLevelOrigin, paymentRequestOrigin, + methodData, and modifiers members share their + definitions with those defined for PaymentRequestEvent. +

    +
    +

    + respondWith() method +

    +

    + This method is used by the payment handler to indicate whether it + can respond to a payment request. +

    +
    +
    +

    + CanMakePaymentEventInit dictionary +

    +
    +            dictionary CanMakePaymentEventInit : ExtendableEventInit {
    +              USVString topLevelOrigin;
    +              USVString paymentRequestOrigin;
    +              sequence<PaymentMethodData> methodData;
    +              sequence<PaymentDetailsModifier> modifiers;
    +            };
    +          
    +

    + The topLevelOrigin, paymentRequestOrigin, + methodData, and modifiers members share their + definitions with those defined for PaymentRequestEvent. +

    +
    +
    +
    +

    + Handling a CanMakePaymentEvent +

    +

    + Upon receiving a PaymentRequest, the user agent MUST + run the following steps: +

    +
      +
    1. If user agent settings prohibit usage of + CanMakePaymentEvent (e.g., in private browsing mode), + terminate these steps. +
    2. +
    3. Let registration be a + ServiceWorkerRegistration. +
    4. +
    5. If registration is not found, terminate these steps. +
    6. +
    7. Invoke the handle functional event algorithm with a + ServiceWorkerRegistration of registration and + callbackSteps set to the following steps: +
        +
      1. Set global to the global object that was provided + as an argument. +
      2. +
      3. Create a trusted event, e, that uses the + CanMakePaymentEvent interface, with the event type + canmakepayment, which does not bubble, cannot be canceled, and + has no default action. +
      4. +
      5. Set the topLevelOrigin, + paymentRequestOrigin, + methodData, and + modifiers + attributes of e the same way as when handling + PaymentRequestEvent. +
      6. +
      7. Dispatch e to global. +
      8. +
      9. Wait for all of the promises in the extend lifetime + promises of e to resolve. +
      10. +
      +
    8. +
    +
    +
    +

    + Example of handling the CanMakePaymentEvent +

    +

    + This example shows how to write a service worker that listens to the + CanMakePaymentEvent. When a CanMakePaymentEvent is + received, the service worker always returns true. +

    +
    +          self.addEventListener('canmakepayment', function(e) {
    +            e.respondWith(true);
    +          });
    +        
    +
    +

    Invocation @@ -1166,7 +1406,7 @@

    - openWindow() method + openWindow() method

    This method is used by the payment handler to show a window to the @@ -1886,6 +2126,9 @@

    information with any payment handler until the user has selected that payment handler.

  • +
  • User agents should allow users to disable support for the + CanMakePaymentEvent. +
  • @@ -1971,6 +2214,11 @@

    either that the user log in to the origin or re-enter payment instrument details. +
  • The CanMakePaymentEvent event should not be fired in + private browsing mode. The user agent should behave as if + respondWith() + was called with true. +
  • @@ -2003,7 +2251,9 @@

    PaymentMethodData, ID, - show(), and + canMakePayment(), + show(), and user accepts the payment request algorithm are defined by the @@ -2034,9 +2284,16 @@

    Payment Method Identifiers
    - The terms payment method - identifier is defined by the Payment Method Identifier - specification [[!payment-method-id]]. + The terms payment method + identifier, standardized + payment method identifier, and URL-based + payment method identifier are defined by the Payment Method + Identifier specification [[!payment-method-id]].
    Basic Card Payment @@ -2045,9 +2302,9 @@

    The terms basic-card, supportedNetworks, + "!payment-method-basic-card#dom-basiccardrequest-supportednetworks">supportedNetworks, and supportedTypes + "!payment-method-basic-card#dom-basiccardrequest-supportedtypes">supportedTypes are defined in [[!payment-method-basic-card]].
    From 0b6badd0d27e052a3e2ebc3e5713394fbe9a0bfd Mon Sep 17 00:00:00 2001 From: Rouslan Solomakhin Date: Mon, 12 Mar 2018 09:56:30 -0400 Subject: [PATCH 2/5] Mention supported-origins-star, add an issue pointer for filtering, and fix a link. --- index.html | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index bce32fb..98c183e 100644 --- a/index.html +++ b/index.html @@ -882,7 +882,9 @@

    PaymentMethodData.
  • If methodName is a standardized payment method - identifier, filter based on or is a URL-based payment method identifier + with "supported_origins": "*" in its payment method + manifest, filter based on capabilities:
    1. For each key in methodData: @@ -901,6 +903,11 @@

      handler and return the result.

    +
    + This is the current thinking about filtering of payment instruments. + As we continue to experiment with implementations, we are soliciting + feedback on this approach. +

    How to specify capabilities @@ -2247,7 +2254,7 @@

    "!payment-method-id#standardized-payment-method-identifiers">standardized payment method identifier, and URL-based + "!payment-method-id#url-based-payment-method-identifiers">URL-based payment method identifier are defined by the Payment Method Identifier specification [[!payment-method-id]]. From b5387a6f3d00e252a002f468a18cc5404db151e9 Mon Sep 17 00:00:00 2001 From: Rouslan Solomakhin Date: Mon, 12 Mar 2018 10:01:03 -0400 Subject: [PATCH 3/5] Fix merge. --- index.html | 188 ----------------------------------------------------- 1 file changed, 188 deletions(-) diff --git a/index.html b/index.html index 98c183e..8772d60 100644 --- a/index.html +++ b/index.html @@ -852,194 +852,6 @@

    -
    -

    - Origin and Instrument Display for Selection -

    -

    - After applying the matching algorithm defined in Payment Request API, - the user agent displays a list of instruments from matching payment - apps for the user to make a selection. This specification includes a - limited number of display requirements; most user experience details - are left to implementers. -

    -
    -

    - Filtering of Payment Instruments -

    -

    - Given a PaymentMethodData and a PaymentInstrument that - match on payment method identifier, this algorithm returns - true if this instrument can be used for payment: -

    -
      -
    1. Let instrument be the given PaymentInstrument. -
    2. -
    3. Let methodName be the payment method identifier - string specified in the PaymentMethodData. -
    4. -
    5. Let methodData be the payment method specific data of - PaymentMethodData. -
    6. -
    7. If methodName is a standardized payment method - identifier or is a URL-based payment method identifier - with "supported_origins": "*" in its payment method - manifest, filter based on capabilities: -
        -
      1. For each key in methodData: -
          -
        1. If the intersection of methodData[key] and - instrument.capabilities[key] is empty, return - false. -
        2. -
        -
      2. -
      3. Otherwise, return true. -
      4. -
      -
    8. -
    9. Otherwise, fire the CanMakePaymentEvent in the payment - handler and return the result. -
    10. -
    -
    - This is the current thinking about filtering of payment instruments. - As we continue to experiment with implementations, we are soliciting - feedback on this approach. -
    -
    -

    - How to specify capabilities -

    -

    - Example of how a payment handler should provide the list of all its - active cards to the browser. -

    -
    -          await navigator.serviceWorker.register('/pw/app.js');
    -          const registration = await navigator.serviceWorker.ready;
    -          registration.paymentManager.userHint = '(Visa ****1111)';
    -          await registration.paymentManager.instruments.set(
    -            '12345',
    -            {
    -              name: "Visa ****1111",
    -              icons: [{
    -                src: '/pay/visa.png',
    -                sizes: '32x32',
    -                type: 'image/png',
    -              }],
    -              enabledMethods: ['basic-card'],
    -              capabilities: {
    -                supportedNetworks: ['visa'],
    -                supportedTypes: ['credit'],
    -              },
    -            });
    -          
    -

    - In this case, new PaymentRequest([{supportedMethods: - 'basic-card'}], shoppingCart).canMakePayment() should return - true because there's an active card in the payment - handler. Note that new PaymentRequest([{supportedMethods: - 'basic-card', data: {supportedTypes: ['debit']}}], - shoppingCart).canMakePayment() would return - false because of mismatch in - supportedTypes in this example. -

    -
    -
    -
    -

    - Ordering of Payment Handlers -

    -
      -
    • The user agent MUST favor user-side - order preferences (based on user configuration or behavior) over - payee-side order preferences. -
    • -
    • The user agent MUST display matching - payment handlers in an order that corresponds to the order of - supported payment methods provided by the payee, except where - overridden by user-side order preferences. -
    • -
    • The user agent SHOULD allow the user - to configure the display of matching payment handlers to control the - ordering and define preselected defaults. -
    • -
    -

    - The second bullet above may be amended to remove explicit mention of - ordering defined by the payee. -

    -

    - The following are examples of payment handler ordering: -

    -
      -
    • For a given Web site, display payment handlers in an order that - reflects usage patterns for the site (e.g., a frequently used payment - handler at the top, or the most recently used payment handler at the - top). -
    • -
    • Enable the user to set a preferred order for a given site or for - all sites. -
    • -
    • If the origin of the site being visited by the user matches the - origin of a payment handler, show the payment handler at the top of - the list. -
    • -
    -

    - The Working Group has discussed two types of merchant preferences - related to payment apps: (1) highlighting merchant-preferred payment - apps already registered by the user and (2) recommending payment apps - not yet registered by the user. The current draft of the - specification does not address either point, and the Working Group is - seeking feedback on the importance of these use cases. Note that for - the second capability, merchants can recommend payment apps through - other mechanisms such as links from their web sites. -

    -
    -
    -

    - Display of Instruments -

    -

    - The user agent MUST enable the user to - select any displayed instrument. -

    -
      -
    • At a minimum, we expect user agents to display an icon and label - for each matching origin to help the user make a selection. -
    • -
    • In some contexts (e.g., a desktop browser) it may be possible to - improve the user experience by offering additional detail to the - user. For example, if the user's "bank.com" origin knows about two - credit cards (thus, two potential responses to the same payment - method "basic-card"), the user agent could display each credit card's - brand and the last four digits of the card to remind the user which - cards the origin knows about. -
    • -
    -

    - The Working Group is discussing how default payment instrument - display could further streamline the user experience. -

    -
    -
    -

    - Selection of Instruments -

    -

    - Users agents may wish to enable the user to select individual - displayed Instruments. The payment handler would receive information - about the selected Instrument and could take action, potentially - eliminating an extra click (first open the payment app then select - the Instrument). -

    -
    -

    Can make payment From a8a27a6ae7f9c9101ee623a5915bdd76d18810f3 Mon Sep 17 00:00:00 2001 From: Rouslan Solomakhin Date: Tue, 13 Mar 2018 13:46:38 -0400 Subject: [PATCH 4/5] Restore the section on filtering of payment instruments and the issue marker. --- index.html | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/index.html b/index.html index 8772d60..b987a61 100644 --- a/index.html +++ b/index.html @@ -1008,6 +1008,91 @@

    });

    +
    +

    + Filtering of Payment Instruments +

    +

    + Given a PaymentMethodData and a PaymentInstrument that + match on payment method identifier, this algorithm returns + true if this instrument can be used for payment: +

    +
      +
    1. Let instrument be the given PaymentInstrument. +
    2. +
    3. Let methodName be the payment method identifier + string specified in the PaymentMethodData. +
    4. +
    5. Let methodData be the payment method specific data of + PaymentMethodData. +
    6. +
    7. If methodName is a standardized payment method + identifier or is a URL-based payment method identifier + with "supported_origins": "*" in its payment method + manifest, filter based on capabilities: +
        +
      1. For each key in methodData: +
          +
        1. If the intersection of methodData[key] and + instrument.capabilities[key] is empty, return + false. +
        2. +
        +
      2. +
      3. Otherwise, return true. +
      4. +
      +
    8. +
    9. Otherwise, fire the CanMakePaymentEvent in the payment + handler and return the result. +
    10. +
    +
    + This is the current thinking about filtering of payment instruments. + As we continue to experiment with implementations, we are soliciting + feedback on this approach. +
    +
    +

    + How to specify capabilities +

    +

    + Example of how a payment handler should provide the list of all its + active cards to the browser. +

    +
    +          await navigator.serviceWorker.register('/pw/app.js');
    +          const registration = await navigator.serviceWorker.ready;
    +          registration.paymentManager.userHint = '(Visa ****1111)';
    +          await registration.paymentManager.instruments.set(
    +            '12345',
    +            {
    +              name: "Visa ****1111",
    +              icons: [{
    +                src: '/pay/visa.png',
    +                sizes: '32x32',
    +                type: 'image/png',
    +              }],
    +              enabledMethods: ['basic-card'],
    +              capabilities: {
    +                supportedNetworks: ['visa'],
    +                supportedTypes: ['credit'],
    +              },
    +            });
    +          
    +

    + In this case, new PaymentRequest([{supportedMethods: + 'basic-card'}], shoppingCart).canMakePayment() should return + true because there's an active card in the payment + handler. Note that new PaymentRequest([{supportedMethods: + 'basic-card', data: {supportedTypes: ['debit']}}], + shoppingCart).canMakePayment() would return + false because of mismatch in + supportedTypes in this example. +

    +
    +

    From 65e5ec4c733f85e7e4cb5be0d5da4ca23d5d209e Mon Sep 17 00:00:00 2001 From: Rouslan Solomakhin Date: Mon, 26 Mar 2018 11:29:21 -0400 Subject: [PATCH 5/5] Add a link to the wiki page. --- index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index b987a61..db2a69c 100644 --- a/index.html +++ b/index.html @@ -1051,7 +1051,9 @@

    This is the current thinking about filtering of payment instruments. As we continue to experiment with implementations, we are soliciting - feedback on this approach. + feedback on this approach. Also see the + Wiki page.