-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should a Payment Request API have shipping address APIs? #39
Comments
No, it should not for at least the following reasons:
|
I'm +1 on removing shipping address from this API. Let's take this in baby steps, leaving the shipping address collection details up to the merchants for now (as it is today). I agree that we may want a more generalized solution (and standard API) for collecting ancillary information that is related to the payment but not necessarily core to it. A generalized mechanism could potentially be reused for other use cases as well. Because we aren't yet sure how this will look, let's not build something that could potentially be wrong now just for one particular use case, even if it is a common one. We could briefly discuss a future path forward to ensure we won't box ourselves out, but I don't think we should deal with this now. |
Related to: https://github.com/WICG/paymentrequest/issues/28 👍 for a more generalized method for exchanging data between payee application (website) and payment app outside of the payment request and response messages. But, I'd like to establish if this is a firm requirement for the API before we define the way it is done. The only use case I can think of that requires this is when the data exchanged alters the parameters of the payment so that the payee needs to update the payment request. In this case, setting a shipping address changes the shipping cost which in turn changes the amount. Are there use cases beyond shipping where the payee may need the ability to update the payment request before the payment app responds? |
Yes (but that is probably not surprising). Physical good purchases are the majority of online transactions, and part of that flow is the collection of shipping information. Shipping information is special because, unlike loyalty cards, etc, it is impossible to fulfill the transaction without it. It is both ubiquitous and critical across all physical good transactions. In addition, one of our intended benefits is the reduction of shopping cart abandonment. Improving the final step of a 4-5 step cumbersome checkout flow is not ultimately all that useful. You have to go earlier in the funnel as well. So to re-iterate, I don't view shipping address and things like loyalty cards, over 18, etc in the same league. Billing address, at least in our proposal, comes from the payment method. If the Credentials CG or the Verifiable Claims TF produces a spec that is usable and is something we want, we can find a way to request additional information at a later date. |
@zkoch, how easily can the "shipping address" approach in your spec be extended to the exchange of other types of data (related to your "later date" comment)? Ian |
@ianbjacobs I don't think we would extend the current way we handle shipping. I think shipping should be handled separately. I can, however, see us handling additional "assertions" in some standard way at a later date (e.g. over 21, etc). I'm not sure what that would look like right now, as I don't have a good mental model for how to think about those. That's why I was saying if/when the VF TF comes up with something, we should look at that and figure out if it makes sense and how it makes sense. |
This is concerning to me. Building features into the Web Platform that we know are short-term point solutions (like a special API for collecting shipping address) creates technical debt in the Web Platform. If we want a more standard way of handling assertions like shipping address, which I assert is not special wrt. other types of credentials collected during the payment flow, then we should understand what the mechanism looks like before we standardize on an ersatz version of it.
Others, namely many of the participants in the VCTF, have been looking at this problem for a while now do have a more developed mental model of how this stuff should work. We haven't been able to discuss it in the WPWG yet because the discussion keeps being corralled into the VCTF work, but there are a set of proposals that have been discussed/worked on for multiple years now (Credential Management API from Google being one of them) as well as working code that demonstrates an alternative. ... but going back to Adrian's request: "I'd like to establish if this is a firm requirement for the API before we define the way it is done." I'd assert that gathering the shipping address isn't a firm requirement for the web payments browser API in Phase I for at least the following reasons:
|
To be clear, I don't think that anyone is arguing that shipping information is not important. We do want to automate the collection of it. That said, we don't want to automate it in a way that incurs technical debt in the Web Platform. Once you add a questionable feature to the Web, it's very hard to <marquee>remove it</marquee>. |
How does this feature reduce shopping cart abandonment? |
I tried to address that in the sentence following the one you quoted. Much of abandonment, at least on mobile, happens long before the user arrives at the point of collecting payment information (coming from our research). So to improve only the final step doesn't go far enough.
I suspect you're confusing things. requestAutocomplete was a solution geared towards improving payments in the browser. Shipping was just one component of that. Perhaps you mean autofill? And we could, but this relies on users still knowing that autofill is enabled before dropping off the checkout flow (which they don't, and they drop off). Also, rAc isn't widely supported and will probably be deprecated in favor of whatever payments API emerges from this.
I disagree that this is technical debt, because I don't see shipping addresses and things like loyalty cards as being in the same category. So I think we can standardize shipping, which again, is ubiquitous to all physical good transactions, and later standardize other assertions or things like loyalty cards. |
There are two issue here I think, correct me if I'm wrong.
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 👍 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: 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 |
In this research, shopping cart abandonment occurred 22% of the time because shipping costs were displayed too late in the payment process. This, it seems, could only be mitigated by requesting the shipping information (or a shipping estimate at the very least) earlier in the process. The current API would encourage merchants to collect shipping information and display updated final prices at the very end of the process, potentially codifying this portion of the shopping cart abandonment problem into the Web Payments API. The research also indicates that 44% of shopping cart abandonment was due to the cost of shipping. It seems clear to me that the change of price at the last minute, after a user has already done all of their shopping is a very significant trigger for cart abandonment. This can be due to taxes or shipping or other costs that are hidden until too late in the process. Therefore, in my view, if we can, we should try to avoid building a high-level API that suggests that the merchant ought to collect shipping information late and adjust prices after a payment request has already been submitted. In order to prevent abandonment, merchants need to be encouraged to include the cost of shipping in their products, offer free shipping, or collect shipping/location/taxes information earlier. We should be trying to push them in that direction, yet, I believe the current approach would encourage them to head the opposite way. |
A priori, there is no reason a payment system needs to know anything about shipping. Also, there is an improvement in user privacy in shipping information is not communicated to the merchant unless the user deems it necessary and not sent earlier than necessary. There is nothing that prevents a web shop from achieving the best of both worlds by offering a cart and shipping bar where users saw information like the value in their cart and shipping if know. And users could enter a fragment of the shipping information needed to compute shipping costs. I doubt payment needs to impact that flow however. |
PROPOSAL: The Web Payments browser API should not support the collection of shipping information through API calls because there may be work starting shortly in the Verifiable Claims work and the Credential Management API that would almost immediately deprecate the mechanism. The Web Payments Browser API may support it via a key/value pair in the payment request data or options object passed to the API if the Verifiable Claims / Credential Management APi fails. |
Moved @msporny proposal to it's own issue so that the discussion may continue on this thread if the proposal is not accepted. |
I think it's premature to try and resolve this question without seeing how the API would be implemented and used through some demos or wireframes. This issue is highly influenced by UX. @msporny makes an argument against gathering the shipping address through the API on the basis that this should be done through more appropriate APIs. The counter-argument is that browsers already hold this data today and should use it to make the checkout experience better for physical goods purchases AND the payments work should not create a dependency on work that hasn't even been chartered yet. The flow is as follows:
There is a UX-related argument that context switching the user between an address selection dialogue, the website and then a payment app selection dialogue is too much friction. i.e. Completely separate APIs and UI for steps 1 - 3 and then steps 4 - 6 as proposed will be a bad UX. So there is a requirement to either:
The advantage of 1 is that we have a separation of concerns between getting the shipping address and the payment request. This may negate the need to manage state of the payment request. The disadvantage is that if the website gets the shipping address and then never calls the payment request API you could have a dialogue in focus waiting for the website (and not taking input from the user). So to support this model you'd need to give the website an ability to close that dialogue explicitly or indicate that it will not be requesting a payment afterwards. The advantage of option 2 is that the browser worries about when to show/hide the dialogue but this introduces a need for the website to be able to update the payment request mid-flow, in effect creating a similar flow to option 1. This seems like a poor design; if there is a high likelihood that the website will update the payment request after initially creating it then why force it to be created at step 1 at all? COUNTER-PROPOSAL: The API should allow the website to leverage the ability of the browser to efficiently gather a shipping address by exposing a function to do so. In time this will be deprecated in favor of more generic APIs like those being worked on by the VCTF. This API endpoint should be separate from the payment request API endpoint. The API should also support the use case where the website does not intend to submit a payment request once it has the shipping address, or this process times out. Example: interface ShippingAddressResponse {
Promise<void> closeDialogue();
...
}
[NoInterfaceObject]
interface Payments {
Promise<PaymentResponse> requestPayment(...);
Promise<ShippingAddressResponse> getShippingAddress(optional boolean closeDialogueAfter);
};
partial interface Navigator {
readonly attribute Payments payments;
}; |
This is false. The Credential Management API exists in an officially Chartered WG and is on the W3C Recommendation track: |
Do not build cruft into the Web Platform. The API call will /never/ be deprecated or removed from the browser because websites will start to depend on it. If we are going to do this, we must make a best effort to get it right. APIs for the Web Platform aren't like a software libraries - you can't deprecate them (unless next to no one uses them). -1 to the counter-proposal that builds cruft into the Web Platform. |
On this thread you wrote "...because there may be work starting shortly in the Verifiable Claims work and the Credential Management API that would almost immediately deprecate the mechanism.." My comments about dependencies referred to the VCTF. I had not made the connection to the Credential Management API so need to think more about the relationship of that work to the current question of shipping data. |
This question was tabled as a proposal (#63) at the WG call on 21 Jan but not resolved. @ianbjacobs wrote:
@msporny wrote:
@zkoch wrote:
@mikewest wrote:
@msporny wrote:
@msporny wrote:
@mikewest wrote:
@dlongley wrote:
@bifurcation wrote:
@dlongley wrote:
@nickjshearer wrote:
@msporny wrote:
@nickjshearer wrote:
David Singer [email protected] wrote:
|
Self-issued credentials may or may not be able to be verified. We're splitting hairs at this point, but the Credentials CG has a pretty solid model about how we think about these sorts of things, and it goes something like this:
A shipping address can be low-stakes (ship this box of gum to this address), or it can be high-stakes (ship this box of guns to this address). Clearly the latter use case could benefit from a verifiable address credential (along with a whole slew of other verifiable credentials).
The proposal is built around the assumption that there are other groups working on this problem in a generalized way and the PaymentRequest approach for gathering a shipping address seems to 1) overlap heavily with that work, and/or 2) be a highly specific solution to a more general problem (collection of payment related information - what about billing address, what about loyalty card, what about coupons and discount codes - why aren't we special casing those things as well?). What do we lose from not putting this "shipping address collection" feature in Phase I (other than some downside from a usability perspective)? |
I've offered a proposal that includes shipping address collection here: https://github.com/w3c/webpayments/wiki/Checkout-API |
Closing this issue as the browser vendors seem to be determined to put shipping address collection in the payments API and multiple attempts at properly layering the APIs have failed. |
The current paymentRequest API has specific facilities for gathering shipping address information:
http://wicg.github.io/paymentrequest/specs/paymentrequest.html#paymentrequest-interface
The Web Payments CG's Browser API spec delegates this functionality to the Credential Management API (aka/or Verifiable Claims API).
Should the payment request API have shipping address APIs?
The text was updated successfully, but these errors were encountered: