Closed adimallikarjunareddy closed 5 years ago
Just to add to the existing one I found one more article that talks
If you are a merchant, implement Google Pay API with its JavaScript library rather than the Payment Request API.
Hi @adimallikarjunareddy, thanks for reaching out.
Regarding your assumptions:
The API is Vendor agnostic: Agree.
One button: Partly agree. Different merchants will have different preferences. Some may show one or two payment options as branded buttons and then a list of "other" payment options through Payment Request API. Some may put all the payment options behind a single button. Some may use canMakePayment() to make real-time decisions which branded buttons to show. I think we will require more merchant experience before we see patterns solidify.
canMakePayment() and privacy: We have sought to strike a balance between giving the merchant some information on which to base the checkout experience, and protecting user privacy. Browsers are implementing mechanisms to reduce opportunities for abuse. This is still an area where I think we could learn more based on real-world usage.
Regarding other comments:
Regarding button and brand guidelines. This is a good question; I will check with colleagues to see what practice they recommend. I will get back to you.
If I understand this comment, it means: I have entered card X in Chrome but it doesn't show up in a browser from another company. That is correct. Many browsers will have an option to store information in the cloud so that when you are logged in to any other browser from the same company, that information is available. But browsers do not today share information among themselves automatically (just as they don't, for example, share browsing history among themselves). Moving forward, we hope that third party payment handlers will offer the ability to store information that may be used across different browsers. See the Payment Handler API (and experiment with it in Chrome 68): https://w3c.github.io/payment-handler/
This sounds like a Chrome-specific question, so let me cc @rsolomakhin.
This sounds like a Stripe-specific question, so let me cc @asolove and @michelle
Finally you asked: "Do you recommend using Payment Request API in its current state for production use, if we intend to support multiple payment methods with single button?"
My answer to this would be: This is a great time to experiment. See, for instance, Shopify's recent blog post on their experiments: https://engineering.shopify.com/blogs/engineering/shaping-the-future-of-payments-in-the-browser
Their experiment (and, for example, JCrew's use on their production site) provide strong indicators that Payment Request API speeds up checkout, but that some additional tweaks to implementations and the specification may be necessary to ensure the best user experience. The Web Payments Working Group is doing more on visual identity, for example, to help users recognize this browser-based experience across the Web.
Browser deployments are stable but may change a bit as we close the final issues for "version 1" of the specification.
So I encourage you to experiment and would appreciate more feedback.
I welcome comments from others in the Web Payments Working Group as well!
If you want to chat about experimentation, please contact me at ij@w3.org.
Ian
@adimallikarjunareddy wrote:
Google Pay with PaymentRequest API distinguishes between cards that are added in Android devices and cards added directly to Google Pay Account. Some times it does not show the cards added through Google Pay Account
See https://blog.chromium.org/2018/07/bringing-google-pay-to-paymentrequest.html - "As of version 70, Chrome will no longer return cards stored in a user’s Google Account as part of the basic-card payment method. To continue getting access to cards stored in a user’s Google Account, developers will need to add support for Google Pay. "
To get the best results, your PaymentRequest objects should include as many payment methods as you can support:
const request = new PaymentRequest([{
supportedMethods: "basic-card",
data: {/* payment-method-specific-data */},
}, {
supportedMethods: "https://pay.google.com", // Double-check the actual identifier.
data: {/* payment-method-specific-data */},
}, {
supportedMethods: "https://apple.com/apple-pay", // Double-check the actual identifier.
data: {/* payment-method-specific-data */},
}, {
supportedMethods: "https://samsung.com/pay", // Double-check the actual identifier.
data: {/* payment-method-specific-data */},
}, {
supportedMethods: "tokenized-card", // Double-check the actual identifier.
data: {/* payment-method-specific-data */},
}], shoppingCart);
The benefits of this style are:
Keep in mind that some payment apps are available only on some platforms. For example, Samsung Pay is on Samsung phones only. Apple Pay is in Safari only. For the latter case, you can check the user agent string to customize your button appearance accordingly.
Hi @adimallikarjunareddy, as you point out, the reality of the world today doesn't match all of the long-term goals of Payment Request. There are lots of minor details about the state of different browser implementations, the rules of individual payment methods, etc., which make it currently impossible to ignore the details and just use one Payment Request API call everywhere. But, the group is making progress on some of these issues and there are already many cases where using Payment Request in a smart way (where available, subject to rules, etc.) can provide a better and higher-conversion experience than most online checkout pages.
Let me reply to your four challenges and then at the bottom offer some summary thoughts on what merchants should think about:
- Apple Pay API and branding rules
There are two versions of the Apple Pay API, an older one that is not Payment Request based and a newer one that is Payment Request-based but does not have quite all of the same features. Apple Pay only ever works in Safari, and no other payment methods are available via Payment Request in Safari. (This may change in the future, but I don't believe Safari has any public plans to add other payment methods.) Apple's guidelines require you to use the official Apple Pay button even when using Payment Request-based API. But this isn't much of a problem since Apple Pay is the only method that works via Payment Request in Safari anyways.
- Payment Request on Chrome + Google Pay
Chrome's Payment Request implementation supports basic-card and custom url payment methods, of which Google Pay is one option. The basic-card method also works in some other browsers (including MS Edge).
As you mention, Google has a pay.js library which will let you access Google Pay cards from other browsers, though it doesn't always use the Payment Request API (because of browser support) and prevents you from also requesting other types of payment methods through the same button.
- Various kinds of cards in Google Pay/Chrome
Rouslan answered this better than I can above.
- Stripe's Apple Pay / Payment Request button
Because Safari only supports Apple Pay, and Apple Pay is only supported in Safari, right now Stripe provides this integration option that will show the Apple Pay button in Safari and a generic Payment Request button in other browsers that support it. The Stripe.js code handles all the browser detection and meeting the Apple branding guidelines so that you don't have to worry about it. But you could implement the same strategy yourself without Stripe's library if you wanted to.
The situation today is complicated, no mistake! It definitely isn't as smooth and wonderful as the ideal future of a single Payment Request button would be.
A few personal thoughts (this is wearing my "works on payment request" hat, rather than my "employee of Stripe" hat):
(Putting on my Stripe hat)
@adimallikarjunareddy wrote:
Google Pay with PaymentRequest API distinguishes between cards that are added in Android devices and cards added directly to Google Pay Account. Some times it does not show the cards added through Google Pay Account
See https://blog.chromium.org/2018/07/bringing-google-pay-to-paymentrequest.html - "As of version 70, Chrome will no longer return cards stored in a user’s Google Account as part of the basic-card payment method. To continue getting access to cards stored in a user’s Google Account, developers will need to add support for Google Pay. "
To get the best results, your PaymentRequest objects should include as many payment methods as you can support:
const request = new PaymentRequest([{ supportedMethods: "basic-card", data: {/* payment-method-specific-data */}, }, { supportedMethods: "https://pay.google.com", // Double-check the actual identifier. data: {/* payment-method-specific-data */}, }, { supportedMethods: "https://apple.com/pay", // Double-check the actual identifier. data: {/* payment-method-specific-data */}, }, { supportedMethods: "https://samsung.com/pay", // Double-check the actual identifier. data: {/* payment-method-specific-data */}, }, { supportedMethods: "tokenized-card", // Double-check the actual identifier. data: {/* payment-method-specific-data */}, }], shoppingCart);
The benefits of this style are:
- Single checkout button the webpage.
- The same code works in Edge, Chrome, Safari, Samsung Internet, and soon Firefox.
- The same code works with cards stored in the browser, Google Pay, Apple Pay, Microsoft Pay, Samsung Pay, and soon other payment handlers.
Keep in mind that some payment apps are available only on some platforms. For example, Samsung Pay is on Samsung phones only. Apple Pay is in Safari only. For the latter case, you can check the user agent string to customize your button appearance accordingly.
Thanks for the details on what is supported with latest chrome browsers. I slightly disagree on the recommendation that I have to now use extra User agent check to customize the button.
Hi @adimallikarjunareddy, thanks for reaching out.
Regarding your assumptions:
- The API is Vendor agnostic: Agree.
- One button: Partly agree. Different merchants will have different preferences. Some may show one or two payment options as branded buttons and then a list of "other" payment options through Payment Request API. Some may put all the payment options behind a single button. Some may use canMakePayment() to make real-time decisions which branded buttons to show. I think we will require more merchant experience before we see patterns solidify.
The problem with this^ is, I end up writing different client-side JS libraries to handle different branded payment methods and we lose the advantage of having Payment Request API that is aiming to unify the payments processing in the browser. Also, as you may know, that one can instantiate PaymentRequest API object more than once.
- canMakePayment() and privacy: We have sought to strike a balance between giving the merchant some information on which to base the checkout experience, and protecting user privacy. Browsers are implementing mechanisms to reduce opportunities for abuse. This is still an area where I think we could learn more based on real-world usage.
One example on why we need minimum information about the payment method supported on browsers. Apple Pay supports this extra event onmerchantvalidation which provides an URL to validate merchant on the fly. This does not return any merchant Id or any other details about the payment method that is invoking this event. One can say that this is specific to Apple Pay, but if someother payment method wants to follow the similar validation, we do not have a way to identify the payment method type which is requesting for validation.
Regarding other comments:
- Regarding button and brand guidelines. This is a good question; I will check with colleagues to see what practice they recommend. I will get back to you.
- If I understand this comment, it means: I have entered card X in Chrome but it doesn't show up in a browser from another company. That is correct. Many browsers will have an option to store information in the cloud so that when you are logged in to any other browser from the same company, that information is available. But browsers do not today share information among themselves automatically (just as they don't, for example, share browsing history among themselves). Moving forward, we hope that third party payment handlers will offer the ability to store information that may be used across different browsers. See the Payment Handler API (and experiment with it in Chrome 68): https://w3c.github.io/payment-handler/
- This sounds like a Chrome-specific question, so let me cc @rsolomakhin.
- This sounds like a Stripe-specific question, so let me cc @asolove and @michelle
Finally you asked: "Do you recommend using Payment Request API in its current state for production use, if we intend to support multiple payment methods with single button?"
My answer to this would be: This is a great time to experiment. See, for instance, Shopify's recent blog post on their experiments: https://engineering.shopify.com/blogs/engineering/shaping-the-future-of-payments-in-the-browser
Their experiment (and, for example, JCrew's use on their production site) provide strong indicators that Payment Request API speeds up checkout, but that some additional tweaks to implementations and the specification may be necessary to ensure the best user experience. The Web Payments Working Group is doing more on visual identity, for example, to help users recognize this browser-based experience across the Web.
Browser deployments are stable but may change a bit as we close the final issues for "version 1" of the specification.
So I encourage you to experiment and would appreciate more feedback.
I welcome comments from others in the Web Payments Working Group as well!
If you want to chat about experimentation, please contact me at ij@w3.org.
Ian
Your response is consistent with how I understood the functionality of Stripe.js through this demo.
Hi @adimallikarjunareddy, as you point out, the reality of the world today doesn't match all of the long-term goals of Payment Request. There are lots of minor details about the state of different browser implementations, the rules of individual payment methods, etc., which make it currently impossible to ignore the details and just use one Payment Request API call everywhere. But, the group is making progress on some of these issues and there are already many cases where using Payment Request in a smart way (where available, subject to rules, etc.) can provide a better and higher-conversion experience than most online checkout pages.
I completely agree with the fact that this will improve the conversion rate and is one of the reasons why we implement for merchants :)
Let me reply to your four challenges and then at the bottom offer some summary thoughts on what merchants should think about:
- Apple Pay API and branding rules
There are two versions of the Apple Pay API, an older one that is not Payment Request based and a newer one that is Payment Request-based but does not have quite all of the same features. Apple Pay only ever works in Safari, and no other payment methods are available via Payment Request in Safari. (This may change in the future, but I don't believe Safari has any public plans to add other payment methods.) Apple's guidelines require you to use the official Apple Pay button even when using Payment Request-based API. But this isn't much of a problem since Apple Pay is the only method that works via Payment Request in Safari anyways.
- Payment Request on Chrome + Google Pay
Chrome's Payment Request implementation supports basic-card and custom url payment methods, of which Google Pay is one option. The basic-card method also works in some other browsers (including MS Edge).
As you mention, Google has a pay.js library which will let you access Google Pay cards from other browsers, though it doesn't always use the Payment Request API (because of browser support) and prevents you from also requesting other types of payment methods through the same button.
- Various kinds of cards in Google Pay/Chrome
Rouslan answered this better than I can above.
- Stripe's Apple Pay / Payment Request button
Because Safari only supports Apple Pay, and Apple Pay is only supported in Safari, right now Stripe provides this integration option that will show the Apple Pay button in Safari and a generic Payment Request button in other browsers that support it. The Stripe.js code handles all the browser detection and meeting the Apple branding guidelines so that you don't have to worry about it. But you could implement the same strategy yourself without Stripe's library if you wanted to.
Yeah I liked this idea of implementation. 💯
What is a merchant to do?
The situation today is complicated, no mistake! It definitely isn't as smooth and wonderful as the ideal future of a single Payment Request button would be.
A few personal thoughts (this is wearing my "works on payment request" hat, rather than my "employee of Stripe" hat):
- Because of browser support not being universal, most merchants should continue to provide a regular checkout form where customers can type in their credit card details.
- That said, in browsers that support it, Apple Pay/Payment Request is a good experience and can lead to strong conversion rates. I'd suggest making it a clear alternative to your regular checkout form where available.
- How you integrate Payment Request currently depends a lot on your PCI compliance. If you do extra PCI compliance work and are allowed to handle raw card numbers directly on your website, you can do a direct Payment Request integration in lots of ways. (Some options below.) If you do not want to be subject to extra PCI burden, you will probably want to use a third-party library provided by your PSP (Stripe has one) or Google's pay.js, which can perform parts of payment request for you so your code never handles raw card numbers. You can also look forward to standardization and adoption of the tokenized-card payment method, which will allow you to receive network tokens for cards, which may not be subject to extra PCI compliance.
Because of browser-specific capabilities restrictions and payment method-specific rules, you should not expect to have a single universal Payment Request button UI.
- In Safari, you'll want to use the Apple Pay button.
- In Chrome, you might want a generic Payment Request button because it can support many payment methods, or you might want a branded "Google Pay" button because customers are more likely to understand what it means. (There is also work underway to have a standard visual identity for Payment Request, which may eventually lead to a button that customers recognize.)
- In other browsers, you may want to use Google's pay.js to get a "Google Pay" button that behaves similarly to Payment Request. You may want to do a generic Payment Request button and use feature detection so that it shows up only when that browser starts supporting Payment Request. A lot of these details depend on the audience of customers, devices, and browsers that you have and unfortunately there aren't enough case studies available to prove which strategy is best.
Looks like this is the only way to achieve more coverage of all payment methods across different browsers.
(Putting on my Stripe hat)
- For merchants who are already using or evaluating Stripe, consider using our ✨magic✨ Payment Request button. It handles the Apple Pay v. Payment Request UI details for you, and as time goes on, we'll add new payment methods and browser support as they become available so that your checkout form gets more powerful over time and you don't have to worry about the details.
- Even if you don't use Stripe, the bottom two checkout form examples on our Elements Examples page show ways to integrate a regular card input form with an Apple Pay/Payment Request button in a fairly non-intrusive way so that customers can use whichever one they prefer.
In general, even our implementation strategy is similar to what you have explained. We already offer regular checkout that collects credit card information (PCI complaint) and provides other buttons to accelerate checkout for better conversion.
One final thought: we're definitely always looking for help, and can use a business rather than browser perspective. Not sure if your employer is a w3c member yet, but if you're interested in helping make progress on this situation (or Payment Request-adjacent fun like Secure Customer Authentication requirements for merchants in Europe or tokenized card payments for security), you can could encourage them to join so you can come participate and vote on things in the Web Payments Working Group.
Thanks to everyone who responded to my queries patiently. I agree with everyone that this proposal is in the early stages of implementation and might change based on the interoperability of browsers in the future.
The key takeaways from this conversation are:
While Payment Request API is foolproof to handle all the supported methods, it is good to follow specific vendor implementations to take advantage of their branding and popularity (e.g. Google Pay and Apple Pay)
You will also take advantage of vendor implementation to support their payment method on a non supported browsers (e.g Google Pay.js implementation on Firefox)
You might end up doing different implementations for different payment providers and some may not be with Payment Request API (e.g. Google Pay/Apple Pay through their implementation whereas basic-cards, Samsung Pay and Microsoft Pay can be through Payment Request API)
@rsolomakhin wrote:
"For the latter case, you can check the user agent string to customize your button appearance accordingly."
I am not convinced browser sniffing is the right approach. Wouldn't canMakePayment() be more useful here?
@adimallikarjunareddy wrote:
"One example on why we need minimum information about the payment method supported on browsers. Apple Pay supports this extra event onmerchantvalidation which provides an URL to validate merchant on the fly. This does not return any merchant Id or any other details about the payment method that is invoking this event. One can say that this is specific to Apple Pay, but if someother payment method wants to follow the similar validation, we do not have a way to identify the payment method type which is requesting for validation."
Good question. Raised as a new issue: https://github.com/w3c/payment-request/issues/775
@rsolomakhin wrote:
"For the latter case, you can check the user agent string to customize your button appearance accordingly."
I am not convinced browser sniffing is the right approach. Wouldn't canMakePayment() be more useful here?
because the current implementation of canMakePayment responds with boolean value and has no reference to payment method or vendor name.
Colleagues from Apple pointed me to their post [1] that shows one way to do this (for Apple Pay):
if (window.ApplePaySession && ApplePaySession.canMakePayments()) // Show Apple Pay button.
However, this may be a good area of discussion for the Working Group at its October face-to-face meeting.
[1] https://webkit.org/blog/8182/introducing-the-payment-request-api-for-apple-pay/
Agreed, then we are not using Payment Request API in that case.
One example on why we need minimum information about the payment method supported on browsers. Apple Pay supports this extra event onmerchantvalidation which provides an URL to validate merchant on the fly. This does not return any merchant Id or any other details about the payment method that is invoking this event. One can say that this is specific to Apple Pay, but if someother payment method wants to follow the similar validation, we do not have a way to identify the payment method type which is requesting for validation.
I think this is a good point. Seems like we should have a methodName
attribute on MerchantValidationEvent
. @marcoscaceres what do you think?
@aestes, raised as: https://github.com/w3c/payment-request/issues/775
Agreed, then we are not using Payment Request API in that case.
WebKit is looking at changing our implementation of canMakePayment() to resolve to true in all the situations where ApplePaySession.canMakePayments() would return true.
We're tracking that with https://webkit.org/b/189529.
@adimallikarjunareddy wrote:
"the current implementation of canMakePayment responds with boolean value and has no reference to payment method or vendor name."
I think an approach would be to construct a series of PaymentRequest objects, each one accepting a single payment method. Then use canMakePayment().
As I mentioned, I think this is a good topic for the group's upcoming face-to-face meeting.
Ian
@ianbjacobs I don't think that will work since browsers rate-limit to prevent one site from making multiple requests with different lists of payment methods to sniff which methods the user has.
In practice, I think it's unavoidable that merchants currently need to know via some method external to the API which methods are possibly supported in one browser if they want to customize the UI.
@adimallikarjunareddy thanks again for raising these questions. I would appreciate the opportunity to chat further with you if possible; I am at ij@w3.org. Thanks!
Hi all, I'm working on developer resources to tell how a merchant can provide best possible payment UX. Let me explain my hypothetical best practice - "branded button" approach:
Given gaps between maturity of Payment Request API implementation status between browsers and payment app availabilities between platforms, we must say providing multiple payment method through single checkout button is almost impossible.
So the approach I would recommend is to use branded buttons where it utilizes Payment Request API and aim long term goal of unifying those payment methods into a single generic checkout button.
See this demo website. It looks very similar to what you might have seen in the past, but a different version using the branded button approach with multiple payment methods.
I haven't completed the demo implementation yet but you should see the idea for some extent. The points are:
PaymentRequest
, you can directly launch the payment app skipping Payment Request UI (at least in Chrome).There are payment method specific best practices as well:
canMakePayment()
to determine if you should use Payment Request API (I'm expecting this is where we can use our upcoming visual identity can be used) or a HTML form as a fallback. (note that Chrome still serves cards saved to Google through forms).if (window.ApplePaySession && ApplePaySession.canMakePayments())
// Show Apple Pay button.
In summary, it's critical for us to have all browsers implement both Payment Request API and Payment Handler API, in order to get this "single generic checkout button" idea to start rolling. But as a short term workaround, branded approach seems reasonable to me.
It's been a long due, but I'm working on an article summarizing the stuff described above. Let me know your thoughts and ideas.
Hi @agektmr,
Thank you for the write-up. I have one small suggestion for your table: my understanding is that Mozilla and Samsung intend to support Payment Handler. Maybe there is a way to add that to the table (even if the phrase "coming soon" may not be correct).
For the issues around buttons and PR API, I've raised a new issue (with a proposal): https://github.com/w3c/payment-request/issues/777
I've written a quick gist of browser compatibility here: http://bit.ly/IsWebPaymentsReady
@adimallikarjunareddy
Payment Request API is vendor agnostic - this means I should be able to use Google Pay and Apple Pay at the same time on Firefox browser (is that futuristic?)
In case this was an actual question about Firefox (and not just browsers in general) - and to avoid possible confusion - the answer is no for Firefox: We currently don't plan to support Google Pay and Apple Pay.
@adimallikarjunareddy, we've added a methodName
attribute to MerchantValidationEvent
. It's now in the spec, and looks like everyone is onboard to implement it. Thanks for pointing that out!
@agektmr I'm worried about having multiple sources of truth about "API readiness". We already have caniuse, the MDN's data, and the (canonical) implementation report.
The implementation report is not great at the moment... but the data from it should be the source of truth, and it represents the most accurate representation of conformance/readiness.
If we want to build a more developer friendly "IsWebPaymentsReady", we should base it off the data that powers the implementation report
@adimallikarjunareddy, thanks to your review it seems the browser folks already addressed one of your issues regarding methodName as part of MerchantValidationEvent: https://github.com/w3c/payment-request/issues/775
Many thanks @marcoscaceres, @aestes, @domenic, @rsolomakhin, and @romandev!
Ian
I believe all actionable things from this discussion were completed, so closing.
We are in the early state of adopting Payment Request API to support payments in the checkout.
Our assumptions or understanding of Payment Request API:
Payment Request API is vendor agnostic - this means I should be able to use Google Pay and Apple Pay at the same time on Firefox browser (is that futuristic?)
There will be one button that is displayed to the end user and Payment Request API takes care of showing all the available methods (Google Pay, Apple Pay, Microsoft Pay and more) and the user can choose what payment methods to use
As a privacy concern, Payment Request API will not let the client (browser) know what payment methods user has or browser supports. All it returns is true or false when canMakePayments() is called
Here are some of the things that do not go well with the above assumptions
Currently, Apple has strict brand guidelines on how we can use their Apple Pay Button, this means I do not have the flexibility to show a generic button that supports all other payment methods. Apple claims that they support Payment Request API on all latest Safari browser. I think this may be true with all other payment methods who have their own brand guidelines
PaymentRequest API on Google Chrome browser brings up both local cards (basic-cards) and google account cards in the same Payment Sheet (which is good), but it does not work on Firefox or Safari.
Google Pay with PaymentRequest API distinguishes between cards that are added in Android devices and cards added directly to Google Pay Account. Some times it does not show the cards added through Google Pay Account
Stripe document says
This is again conflicting on why would we distinguise Apple Pay from Payment Request API.
All in all, do you recommend using Payment Request API in its current state for production use, if we intend to support multiple payment methods with single button?