Skip to content
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

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

Open
ianbjacobs opened this issue Sep 12, 2018 · 13 comments

Comments

@ianbjacobs
Copy link
Collaborator

Hi all,
cc @adimallikarjunareddy

This post is inspired by:
#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):

  • The browser computes the intersection of merchant-accepted and user-supported payment methods.
  • The browser automatically displays that information in the page at a location determined through code by the merchant (implementation details to be determined). However, the set of payment methods displayed must not be shared with the merchant (thus, for example, does not change
    the DOM).
  • For the display, the browser fetches an icon associated with each payment method (e.g., through the corresponding payment method manifest).
  • If the user selects an icon, the browser launches PR API for just that payment method. The browser can optimize (as Chrome already does), showing the sheet if necessary or jumping straight to a single relevant payment handler.

Some advantages to this approach occur to me:

  • The user experience would match user expectations. They expect to see buttons on page, and they do.
  • The merchant would have less work to achieve that user experience. They just call PR API and magic happens to get the right logos.
  • The user experience is optimized for the user. The list of buttons is scoped to the intersection, so that improves on the NASCAR effect.
  • User privacy is protected. The merchant does not receive information about the user's environment before the user has chosen a payment method.
  • The sheet is still relevant (when collecting shipping and contact information).
  • Merchants have flexibility. Merchants could highlight payment buttons they want to highlight, and still use Payment Request this way for other payment methods.
  • We may not need any additional specifications beyond Payment Request API and Payment Method Manifest. Note that this idea does not require implementation of Payment Handler API. It can leverage Payment Handler API where Payment Handler is supported. However, see below for my point that for some calls to PR API the merchant may not want automatic button generation.
  • It seems like it would respect brand guidelines for buttons. For example, the user would see the Apple Pay button (if relevant for the transaction) and clicking that button would call Payment Request API with just the Apple Pay payment method.
  • The Web Payments visual identity needs to do less heavy lifting. Users see familiar brands and click those buttons. We can still have a Web Payments visual identity but it doesn't have to work as hard to communicate a user experience people will get when they click on an unfamiliar button.
  • For security reasons, it needs to be made clear that this display is owned by the browser, not the merchant. So the display of information is obviously very very important!

So:

  • Does this make sense? What are the other benefits or issues with something like this?
  • Are browsers interested in doing a bit more natively to enhance the PR API user experience?
  • How would the information (namely a list of clickable payment methods) be presented to users
    in a manner that is convenient and secure? How would it work on mobile?
  • Would every call to Payment Request API behave like this, or only some of them? For instance, one could imagine a "Buy" button that calls Payment Request where the merchant really wants their button to be displayed. I can imagine that only some calls to PR API should have this behavior of browser-generated buttons.
  • How would this relate to polyfills that are being used today while PR API implementations are not yet universal?

I look forward to your comments.

Ian

@asolove-stripe
Copy link

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
Copy link
Collaborator Author

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
Copy link

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:

#27 (comment)

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
Copy link

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
Copy link

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:

  • A single container approach is a good starting point, but comes with an interesting set of problems, mainly around not overloading the buyer with information and merchant control around displaying said container. For our merchants, we've not seen this to be the best approach possible.
  • Whatever the solution, some merchants will have legal bounding agreements with payment processors to show them in a specific order. Just something to keep in mind, as @ianbjacobs previously mentioned.

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

  • Help set buyer expectations about their purchase journey?
  • Ensure that payment method branding is well represented upstream?
  • Help adoption of PaymentRequest?
  • All of the above?

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
Copy link

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
Copy link
Collaborator Author

@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:

  • The merchant wants some control over the display of information, both due to branding requirements and the merchant's style requirements.

  • Any branding logos should come from the payment method owner, not the merchant (for security
    reasons). E.g., if the payment method owner specifies icons in a Web App Manifest, perhaps the merchant could just refer to entries in that manifest. I don't know whether this would offer merchants sufficient flexibility.

  • We want to leak as little information about the merchant environment as possible with the merchant prior to payment handler selection.

@adrianhopebailie
Copy link
Collaborator

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
Copy link
Collaborator Author

@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
Copy link
Collaborator

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
Copy link
Collaborator Author

@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
Copy link
Collaborator

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

@ianbjacobs
Copy link
Collaborator Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
@adrianhopebailie @dlongley @marcoscaceres @Krystosterone @ianbjacobs @asolove-stripe and others