W3C Payment API changes to Chrome 78 and 79

62 views
Skip to first unread message

Eiji Kitamura

unread,
Nov 5, 2019, 6:21:33 AM11/5/19
to Public Payment Request Announcements

Here are the changes coming to Chrome.


Canary: 80  | Beta: 79 |  Stable: 78


Changes enabled by default on 78:

  • More restrictive hasEnrolledInstrument() for Autofill Instruments

  • PaymentResponse.prototype.retry()

  • Redact Address in PaymentRequest.onshippingaddresschange Event


Changes available for testing behind flags on 79:

  • Payment Handler delegation for Desktop

  • "minimal UI" for Android

More restrictive hasEnrolledInstrument() for Autofill Instruments

We launched hasEnrolledInstrument() in Chrome 74 which helps a merchant detect whether a payment method has an enrolled instrument or not. It used to return true even when a payment instrument is missing a billing address or the expiration date has already passed as long as it is registered to the payment method.


This change improves the authorization of transactions by requiring unexpired cards and a billing address. That way, it improves the quality of autofill data and increases the chances that PaymentRequest.hasEnrolledInstrument() returns true. This improves the user experience on transactions that use autofill data.


// Checking for instrument presence.

if (request.hasEnrolledInstrument) {

 // In Chrome 74 and after.

 request.hasEnrolledInstrument().then(handleInstrumentPresence).catch(handleError);

} else {

 // Before Chrome 74.

 request.canMakePayment().then(handleInstrumentPresence).catch(handleError);

}


Note that we still recommend you to feature detect hasEnrolledInstrument() as shown in the sample code above.

PaymentResponse.prototype.retry()

When there is an error in a payment response (for example, the shipping address is a PO box), you would have to start over the payment request session from the beginning. The retry() method of a PaymentResponse instance now allows you to ask a user to retry a payment.


async function handlePayment() {

  const payRequest = new PaymentRequest(methodData, details, options);

  try {

    let payResponse = await payRequest.show();

    while (payResponse has errors) {

      /* let the user edit the payment information,

         wait until they submit */

      await response.retry();

    }

    await payResponse.complete("success");

  } catch(err) {

    /* handle the exception */

  }

}


Redact Address in PaymentRequest.onshippingaddresschange Event

PaymentRequest.onshippingaddresschange is used to communicate the shipping address a user has selected to the merchant so they can make adjustments to the payment amounts such as shipping cost and tax. At this point, the user has not fully committed to the transaction, so the principle should be to return as little information as possible to the merchant.


With this change, Payment Request API will remove fine-grained information from the shipping address before exposing it to a merchant website in the ShippingAddressChange event. The redaction removes recipient, organization, addressLine and phoneNumber from the shipping address because these are not typically needed for shipping cost and tax computation.


Payment Handler delegation for Desktop

Through Payment Request merchants can request shipping and contact information along with payment method information. Payment Handlers have previously only been able to respond to the payment method portion of the request with the shipping and contact information coming from the browser.  


This change enables web-based Payment Handlers to also provide shipping and contact information on Desktop. Payment Handlers can specify which information they are able to provide during their installation via calling enableDelegations:



// Payment Handler
async function install() {
  try {
    ...
    await registration.paymentManager
      .enableDelegations(
        ['shippingAddress',
          'payerName', 'payerPhone',
          'payerEmail'
        ]);
    ...
    return 'success';
  } catch (err) {
    /* handle the exception */
  }
}


The payment handlers are then responsible for providing the specified implementation as part of their reply to the payment request.


self.addEventListener('paymentrequest', (evt) => {
    evt.respondWith({
        ...,
        shippingAddress: evt.paymentOptions.requestShipping? {
            city: 'Reston',
            country: 'US',
            dependentLocality: '',
            organization: 'Google',
            phone: '+15555555555',
            postalCode: '20190',
            recipient: 'Jon Doe',
            region: 'VA',
            sortingCode: '',
            addressLine: [
                '1875 Explorer St #1000',
            ],
        }: {},
        shippingOption: evt.paymentOptions.requestShipping? 'express' : '',
        payerName : evt.paymentOptions.requestPayerName? 'Jon Doe' : '',
        payerEmail: evt.paymentOptions.requestPayerEmail ? 'jon...@gmail.com': '',
        payerPhone: evt.paymentOptions.requestPayerPhone ? '+15555555555': '',
    });
});


Two important things to note:

  • Skip the sheet: Chrome will skip the Chrome payment sheet and go directly to the Payment Handler’s UI whenever there is a: 1) one Payment Handler who can handle the request; and 2) that Payment Handler can provide all information requested by the merchant (“full delegation”).

  • Partial delegation: Chrome has no plans to fully support partial delegation. This means:

    • Payment Handlers can expect to be shown if they can return all the user information being requested by the merchant (e.g., merchant requests shipping and contact information and Payment Handler has stated it can handle delegation for both shipping and contact information)


  • Payment Handlers can expect to only provide payment method information (i.e.,the current experience) when they have not specified that they can support all the information being requested by the merchant (e.g., merchant requests shipping and contact information but the Payment Handler has only specified that they can handle contact information)


The merchants are able to register listeners for shipping[option|address]change events and update payment request details (e.g. update total cost based on shipping address or option) in response to these changes. The Payment Handlers which provide the shipping address will also notify the browser about these events. 



self.addEventListener('paymentrequest', (evt) => {

  evt.respondWith(new Promise((confirmPaymentFunction, rejectPaymentFunction) => {

    if (evt.changeShippingAddress === undefined) {

      // Not implemented in this version of Chrome.

      return;

    }

    // Notify merchant that the user provided a different shipping address.

    evt.changeShippingAddress(userProvidedShippingAddress)

    .then((responseFromMerchant) => {

      if (responseFromMerchant === null) {

        // Merchant ignored the ‘shippingaddresschange’ event.

        return;

      }

      handleResponseFromMerchant(responseFromMerchant);
    })

    .catch((error) => {

      handleError(error);

    });

  }));

});



There are a number of future enhancements to delegation under works, including:

  • Android support; and

  • Delegation support for native Payment Handlers.


More information can be found in the explainer


To test this feature:

- Use Chrome Canary on desktop

- Enable chrome://flags/#enable-experimental-web-platform-features


"minimal UI" for Android

This is an experimental flow developed to demonstrate Payment Handlers to provide a minimal UI path optimized for digital microtransactions. Broader launch of this flow is pending feedback and interest from Payment Handlers.


To test this feature:

- Use Chrome Canary on Android

- Enable chrome://flags/#enable-web-payments-experimental-features

- Go to https://rsolomakhin.github.io/pr/apps/micro/

- Click the “Install” button.

- Go to https://rsolomakhin.github.io/pr/apps/micro-test/ by clicking "Test it out" link.

- Click the "Buy" button.



Reply all
Reply to author
Forward
0 new messages