Re: [webpayments] Should a Payment Request API have shipping address APIs? (#39)

There are two issue here I think, correct me if I'm wrong.

1. We need a way to get the buyer's shipping address so that the merchant can determine things like the cost of shipping options
 1. We need the ability to dynamically change the terms of the offer (total price in this case) based on some user input (selection of a shipping option in this case)

The first issue is the one we should be dealing with here as that is what the issue title says: "Should a Payment Request API have shipping address APIs?"

I am :+1: for gathering of shipping data being separated from the payment request. By the time we request a payment we should at a minimum already know the shipping address so we can provide shipping options in the request.

The UA could make the UI for this very slick by gathering the address data and then using the same dialogue to get the user's payment app selection:

```javascript

    navigator.payments.addEventListener("optionsChange", function (changeEvent) {
        if(changeEvent.optionGroup == "shipping")
        {
            // Process shipping options change and update amounts

        }
    });

    navigator.credentials.get({
        "type": "shippingAddress", //Not currently supported but it illustrates the mechanism
        "options" : {
            "modal" : true,
            "closeTimeout" : 15000 
            //The dialogue stays open in a "waiting state" for 
            // 15 seconds after the user selects their credential
        }
    }).then(
            function(credential) {
                if (!credential)
                //We'll have to get the address through the website UI
                // so close the dialogue that's currently waiting for us to 
                // submit another request
                navigator.credentials.close();

                //Build request based on supplied address
                // i.e. with appropriate shipping options
                var 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'
                            }
                        }
                    ];
                
                //Request payment
                navigator.payments.requestPayment(
                        req,
                        {
                            closeTimeout : 20000 //Wait 20 seconds for us to process the response
                        }
                ).then(function(paymentResponse){
                    
                    //Process the payment
                    var result = processPaymentResponse(paymentResponse)
                    
                    //Close the dialogue
                    navigator.payments.completePayment(result);
                    
                }).catch(function(err) {
                    console.error("Uh oh, something bad happened", err.message);
                });
            });


    function processPaymentResponse(paymentResponse) {
        // Process paymentResponse
        return true;
    }
```
Some explanation of this request object example is here: https://github.com/WICG/paymentrequest/issues/41

---
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webpayments/issues/39#issuecomment-165488995

Received on Thursday, 17 December 2015 15:47:58 UTC