[paymentrequest] Combine API parameters into a single request object + options (#41)

By splitting the set of supported methods from the amount we remove a lot of flexibility in how a paymentRequest can express an offer.

The constructor should take two arguments, the payment request and an optional parameter specifying any processing options.

The request object should have a fairly rigid schema that is well defined in the spec and only contains data relevant to the payment. i.e. The format of the request object is defined by the WPWG (in the messaging spec). Developers should assume that anything they put in the request object MAY be passed on to the payment app.

This would address https://github.com/w3c/webpayments/issues/38 in that the merchant could be selective about the level of detail they provide in the payment details on a per payment method basis so payment methods that require detailed breakdowns (ApplePay?) are supported but merchants still have the flexibility to simply provide a single line (the Total) where that is all that is required.

The options object should be consumed by the payment mediator (User Agent) and should contain data that helps the UA to mediate between the payee application and payment app effectively. It is effectively an instruction to the mediator about how to handle the request and would contain data such as a flag to request that shipping data is collected.

This should go some way to addressing https://github.com/w3c/webpayments/issues/39

The options object will be the most likely candidate for extensibility in future and implementors can use less formal processes than the WPWG to extend this object with new features as they see fit.

Example:

```javascript
   var paymentRequest = new PaymentRequest([
        {
            "methods": [
                'https://w3id.org/payment-methods/traditional-card/#Visa',
                'https://w3id.org/payment-methods/traditional-card/#Mastercard',
                'https://w3id.org/payment-methods/traditional-card/#Discover'
            ],
            "details": {
                "groups": [
                    {
                        "id": "shipping",
                        "label": "Shipping",
                        "default":  "shipping-standard"
                    }
                ],
                "items": [
                    {
                        "id": "shipping-standard",
                        "optionGroup": "shipping",
                        "label": "Standard Shipping",
                        "amount": {"currencyCode": "USD", "value": 0} // US$0.00
                    },
                    {
                        "id": "shipping-express",
                        "optionGroup": "shipping",
                        "label": "Express Shipping",
                        "amount": {"currencyCode": "USD", "value": 500} // US$0.00
                    },
                    {
                        "id": "basket",
                        "label": "Sub-total",
                        "amount": {"currencyCode": "USD", "value": 5500} // US$55.00
                    },
                    {
                        "id": "tax",
                        "label": "Sales Tax",
                        "amount": {"currencyCode": "USD", "value": 500} // US$5.00
                    },
                    {
                        "id": "total",
                        "label": "Total due",
                        "amount": {"currencyCode": "USD", "value": 6000} // US$60.00
                    }
                ]
            },
            "data": {
                "merchantNumber": 8762387623,
                "encryption": {  //The payment method defines a mechanism for encrypting responses
                    encryptResponseData: true,
                    algorithm: "AES-CBC",
                    publicKey: 'https://payment-service-provider.example.com/keys/12'
                },
                "signature": {  //The payment method defines a mechanism for signing the request...
                    type: 'LinkedDataSignature2015',
                    creator: 'https://payment-service-provider.example.com/keys/12',
                    created: '2015-09-23T20:23:15Z',
                    nonce: '239807882930744352',
                    signatureValue: 'm4NTIyZTOGQzNGVkMzVkZ...OWM32NjIgoYzI43Q3ODIy='
                },
                "https://w3id.org/payment-methods/traditional-card/#Discover" : { //Method specific data
                    "discover-merchant-identifier" : "44ba1fd7-74f7-4d47-b04a-7f01199bdaa5"
                }
            }
        },
        {
            "methods": ['https://bitcoin.org'],
            "details": {
                "groups": [
                    {
                        "id": "shipping",
                        "label": "Shipping",
                        "default":  "shipping-standard"
                    }
                ],
                "items": [
                    {
                        "id": "shipping-standard",
                        "optionGroup": "shipping",
                        "label": "Standard Shipping",
                        "amount": {"currencyCode": "BTC", "value": 0} // BTC0.00
                    },
                    {
                        "id": "shipping-express",
                        "optionGroup": "shipping",
                        "label": "Express Shipping",
                        "amount": {"currencyCode": "BTC", "value": 24500} // BTC0.00245
                    },
                    {
                        "id": "total",
                        "label": "Total due",
                        "amount": { "currencyCode": "BTC", "value": 12300000 } // BTC0.123
                    }
                ]
            },
            "data": {
                "destination" : '3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC'
            }
        }
    ],
    {
        "requestShippingAddress": true,
    });
```
This would also be my solution to: https://github.com/w3c/webpayments/issues/37

The example has a few things worth noting that I put in as ideas for how to address some open issues:

 1. The first item in the request array has multiple method identifiers which allows the merchant to specify common data that applies to all those schemes. In this instance the card payment method is split into three methods which all have the same request data but different identifiers. This would be the case for a payment method like cards where the format of the request and response is mostly the same but the merchant only supports some schemes (example: they only accept Visa, Mastercard and Discover but not Amex or Diners). In this instance the URLs are W3C URLs because the payment method is a W3C standard. I see no value in this being a short string vs this URL? (See https://github.com/w3c/webpayments/issues/30 and https://github.com/WICG/paymentrequest/issues/35). Also note how some method specific data could still be provided in the details.
 1. The example shows how a method may provide simple mechanisms to secure data using in this case a signature for validating the request and encryption for securing the response. (See https://github.com/w3c/webpayments/issues/19)
 1. The shipping options are included in the details but put in a group (similar to the behavior of radio buttons in HTML) so that the UA knows that the user should only select one. One could imagine the UA firing an event when the user makes a selection that allows the website to send back an updated request object. This is a generic and extensible solution to including dynamic pricing in the request and could resolve https://github.com/w3c/webpayments/issues/39
 1. Amounts are expressed in the minor currency as is the standard for many existing payment protocols (notably ISO8583). This allows developers to use numbers (not strings) that require no special parsing to use them in calculations. (See: https://github.com/w3c/webpayments/issues/40)

---
Reply to this email directly or view it on GitHub:
https://github.com/WICG/paymentrequest/issues/41

Received on Thursday, 17 December 2015 14:12:05 UTC