w3c / payment-request

Payment Request API
https://www.w3.org/TR/payment-request/
Other
486 stars 133 forks source link

To address branded button issues and improve privacy, add browser support for payment method selection before the sheet #777

Open ianbjacobs opened 5 years ago

ianbjacobs commented 5 years ago

Hi all, cc @adimallikarjunareddy

This post is inspired by: https://github.com/w3c/payment-request/issues/774

I would like to start discussion around a proposal for adding browser support for payment method selection before the sheet. Perhaps we can discuss at TPAC in October.

It seems to me that canMakePayment() is serving multiple roles. Perhaps we can tease those apart into at least least two needs:

(1) The merchant wants to know whether to provide a Payment Request API user experience or a traditional Web form. (2) Having determined PR API is available, the merchant wants to know which payment buttons to show in a manner consistent with brand-specific requirements.

Perhaps we can find away to limit canMakePayment() usage to just the first one. This would reduce the number of calls, improving privacy and perhaps avoiding rate limiting issues.

To address the second need, I propose that the browser offer a new user experience.

The browser knows the intersection of the payment methods accepted by the merchant and those for which the user has payment handlers. Today the browser shows that intersection in the sheet. What we are hearing is that we need something before the sheet as well.

Therefore, I propose the following (at a high level):

Some advantages to this approach occur to me:

So:

I look forward to your comments.

Ian

asolove-stripe commented 5 years ago

I think this proposal makes a lot of sense at a high level, and also has a lot of fun low-level questions. One in particular: showing logos over third-party content in a not-ugly way requires some kind of standard for what background they get shown on, roughly what size/style of icon is present, etc. This seems like a tricky thing for a spec to handle, but I think in practice merchants would be very reluctant to have a bunch of non-matching icons on top of their custom-styled checkout page.

ianbjacobs commented 5 years ago

Hi @asolove-stripe,

It seems to me that payment method owners own the branding requirements. If automatic selection based on the payment method manifest does not suffice, we could enhance (and complicate) this approach by enabling the merchant to express a preference for size and color, from among the logos authorized by the payment method owner. So the merchant does not provide the logo (which would raise security issues) but instead expresses a preference (e.g., for a specific icon) that is verified by the browser against the options offered by the payment method owner. Errors could be managed by the browser showing something authorized by the payment method owner.

There are other approaches as well, such as the merchant specifying a target height (for example) and letting the browser try to optimize logos for that height.

I hear the point and, if there's interest overall, we can get suggestions from the group.

Perhaps a tougher point would be ordering of the logos. However, there may be a way to leverage existing data from Payment Request API for that.

dlongley commented 5 years ago

I'm +1 to the group discussing this sort of approach. I recommended some kind of browser-controlled UI components to address this issue and others at TPAC a while back and here as well:

https://github.com/w3c/payment-request/issues/27#issuecomment-218786016

If we have success with this idea, it could also make it easier for sites to customize their checkouts to support more things like discount codes without requiring browser code to change. The idea isn't without its challenges, but it could make extensions, customization, and good UX much easier to implement for merchants and their software partners.

Krystosterone commented 5 years ago

Sorry for the spam, I erroneously pasted a response in the wrong github thread. I do have some thoughts on this that I'll share with the group shortly.

Krystosterone commented 5 years ago

Shopify would very much be interested in discussing such an approach; branded buttons and payment method branding is something we think Web Payments can potentially solve elegantly. It does comes with some inherently interesting difficulties, mainly UX ones.

Some quick thoughts from a merchant perspective:

I'd like to clarify what the underlying need and goal of such a spec would be. Are we trying to:

I would have though that long term, PaymentRequest's value prop of streamlining the checkout process would trump branding requirements upstream, as their available in the payment sheet.

I'm excited by this though as I can very well see this spec bridging the gap between currently available payment methods through SDKs and new arrivals present through Payment Request.

Krystosterone commented 5 years ago

In the spirit of getting the ball rolling, I'll drop some ideas that come off the top of my head. These mostly concentrate on allowing the merchant to decide what's the best way to present buttons, all the while trying to protect the buyer's privacy.

Idea 1

Could we envision a world where PaymentRequest gives us back the list of accepted payment methods? (i.e. a more granular canMakePayment()) This new call would still be rate-limited.

Say: paymentRequest.availablePaymentMethods(): string[] (a list of payment method identifiers)

Accompagnied to this, each payment handler can be queried for their button asset say: registration.paymentManager.instruments.get("payment-method-id").buttonImage

Idea 2

Could we envision a high level abstraction that enables a merchant to build a tuple of branded button and PaymentRequest, without leaking to the merchant what payment method is being presented to the buyer.

For example:

interface PaymentMethod {
    paymentButton: PaymentButton;
    paymentRequest: ScopedPaymentRequest;
}

buildPaymentMethods([
    { supportedMethods: "basic-card" },
    { supportedMethods: "samsung-pay" },
    { supportedMethods: "google-pay" },
] as PaymentMethodData[]): PaymentMethod[]

A ScopedPaymentRequest would be a PaymentRequest without the ability to specify methodData[]. Every ScopedPaymentRequest would only ever have a single payment method.

A PaymentButton would be the browser control container containing the payment method brand.

buildPaymentMethods would only ever return the PaymentMethods that respond positively to canMakePayment().

In all cases, the merchant would never be able to query any object to determine what is being presented to the buyer.

ianbjacobs commented 5 years ago

@Krystosterone, thanks for sharing these ideas. Of your goals, I like "Help set buyer expectations about their purchase journey?" and "Help adoption of PaymentRequest?" I would reframe "Ensure that payment method branding is well represented upstream?" as "Ensure that PaymentRequest supports the realities of requirements related to payment method branding."

I need to think more about your Idea 2.

I am hearing the desirable properties:

adrianhopebailie commented 5 years ago

What if we proposed some declarative way of binding a payment request to DOM elements? Something like:

<img src="./card-logo.png" id="card_button" onclick="myPaymentRequest.show()" />
<img src="./gpay-logo.png" id="gpay_button" onclick="myPaymentRequest.show()" />
<script>
var myPaymentRequest = new PaymentRequest(...)
myPaymentRequest.applyClass('visible', 'basic-card', getElementById('card_button'))
myPaymentRequest.applyClass('visible', 'http://google.com/pay', getElementById('gpay_button'))
</script>

Is there a safe way to do this without the user being able to figure out the supported methods? Could the CSS class be applied but not reported?

ianbjacobs commented 5 years ago

@adrianhopebailie,

I'm not sure to understand the proposal. Also, it seems to put the control of branding logos into the hands of merchants, so if the browser is automatically to display these things "in a browser-owned window," that would seem to create a security problem as we have heard in the past. (However, I'm not sure that is what you intended.)

Ian

adrianhopebailie commented 5 years ago

Any branding logos should come from the payment method owner, not the merchant (for security reasons)

Could someone explain what these security reasons are? This seems in conflict with allowing the merchant "some control over the display of information, both due to branding requirements and the merchant's style requirements".

The checkout page on the merchant website will never be, or contain, a browser-owned window as this is too easy to spoof. My understanding of the problem we are solving is:

  1. A merchant wants to display various elements/buttons on their checkout page and style these and lay them out differently depending on which payment methods the user has available.
  2. The browser should be able to facilitate this without revealing to the merchant the actual list of supported methods.

So a declarative solution is, the merchant provides all elements for all payment methods they support and provides hints to the browser about how to arrange those elements using CSS based on which methods the user has.

ianbjacobs commented 5 years ago

@adrianhopebailie wrote:

"Could someone explain what these security reasons are?"

I have heard that if the merchant can choose an arbitrary image, they could, for example, show a BobPay image but actually code the payment method as evalpay.com via PR API. Therefore, we want to let the browser get the image from the domain of the payment method.

adrianhopebailie commented 5 years ago

How would this prevent evilpay from simply using BobPay's logo in their manifest?

ianbjacobs commented 5 years ago

I don't think we can prevent collusion except through browser whitelists. In the case where the payment method owner is legitimate, this prevents abuse on the EvilMerchant side.