[w3c/payment-handler] Allow Payment instrument to respond with user data (#218)

**Summary:** Provide a way for payment instruments to respond with information that would normally be provided by the user

## Description

The Payment Request spec now relies on the `options` argument to specify if it needs additional user information to complete the payment. If specified, this will surface additional fields in the `PaymentRequest` UI that the user can fill out.

For example:

```javascript
const options = {
  requestPayerEmail: false,
  requestPayerName: true,
  requestPayerPhone: false,
  requestShipping: true,
}
```

would signify that the `PaymentRequest` UI would surface inputs for the payer name and shipping address.

It would be useful for a payment instrument to be able to send back that additional information, rather than relying on the user to provide that information. This can be useful in cases where a Payment App has already stored user information previously.

## Use case

Two existing payment methods come to mind: Amazon Pay and Paypal Express Checkout. While we realize that these payments applications are not actively participating in the W3C effort, their use case is common enough.

**Amazon Pay**
The Amazon Pay API currently works with their widgets, which are embedded iframes that can provide:

- The shipping address;
- The payment method, with the billing address.

When interacting with these widgets and API, as a developer, you can never send a shipping address from the platform to Amazon Pay. Amazon will use the address they have on file, or require the user to add one to their profile.

This means that the current implementation of Payment Handler is lacking, as the shipping address provided by the user would not be propagated to Amazon Pay, as their APIs do not allow that use case.

**Paypal Express**
Paypal Express has pretty much the same use case, though their API **does** accept specifying a shipping address outside of their system.

## API implementation ideas

What if, while binding the instrument, the user-agent (or developer) could specify if the instrument is expected to provide this additional user information?

**Payment instrument registration**

```javascript
const instrumentKey = "c8126178-3bba-4d09-8f00-0771bcfd3b11";
const { registration } = await navigator.serviceWorker.register("/register/sw.js");
await registration.paymentManager.paymentInstruments.set({
  instrumentKey,
  {
    name: "My Bob Pay Account: john@example.com",
    enabledMethods: ["https://bobpay.com/"],
    icons: [{
      src: "icon/lowres.webp",
      sizes: "48x48",
      type: "image/webp"
    }],
    
    // Specify if the payment instrument can provide user information
    options: {
      providesPayerEmail: true,
      providesPayerName: true,
      providesPayerPhone: true,
      providesShipping: true,
    },
  });
```

**Payment resolution**

Being that the instrument now has to provide that information, there could be validation on `respondWith` resolution to ensure that the appropriate data is provided.

```javascript
self.addEventListener('paymentrequest', function(e) {
  e.respondWith(new Promise(function(resolve, reject) {
    self.addEventListener('message', listener = function(e) {
      self.removeEventListener('message', listener);
      if (e.data.hasOwnProperty('name')) {
        reject(e.data);
      } else {
      
        // On resolution, ensure that the user information is provided
        // Payload could look like:
        // details: {
        //   payerEmail: "krystian@shopify.com",
        // }
        resolve(e.data);
      }
    });
  }));
});
```

-- 
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-handler/issues/218

Received on Friday, 29 September 2017 14:04:17 UTC