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

Detecting payment method support #247

Closed
baloo opened this issue Sep 10, 2016 · 6 comments
Closed

Detecting payment method support #247

baloo opened this issue Sep 10, 2016 · 6 comments

Comments

@baloo
Copy link

baloo commented Sep 10, 2016

In the current draft, the spec doesn't allow a merchant to detect a user-agent has a payment method capability. For example, using the following code:

var payment = new PaymentRequest([{
        supportedMethods: ['https://android.com/pay'],
        data: {
          merchantName: 'merchantname',
          allowedCardNetworks: ['AMEX', 'MASTERCARD', 'VISA', 'DISCOVER'],
          merchantId: 'merchantid',
          paymentMethodTokenizationParameters: {
            tokenizationType: 'GATEWAY_TOKEN',
            parameters: {
              'gateway': 'stripe',
              'stripe:publishableKey': 'stripekey',
              'stripe:version': '2016-07-06'
            }
          }
        }
      }], {
    total: {label: 'Total', amount: {currency: 'USD', value: '0.50'}}
  }, {
      requestShipping: false,
      requestPayerPhone: false,
      requestPayerEmail: false
    });
p = payment.show();

On PaymentRequest instantiation no validation is required by the user-agent. It will only validate the PaymentMethodData is supported during the .show() and then the promise will failed with an error like: The payment method is not supported

This makes impossible for a merchant to detect a payment method is supported (like android pay) and show a "android pay" button only if supported. Right now on chrome 53, if we run this snippet of code, it will start showing up a payment window and then it disappears almost immediately. This make deceptive UX.

Would it be possible to add an extra method like validate() to ensure one of the PaymentMethodData is supported by user-agent? Or make the new PaymentRequest raise an error, but that would probably break the api.

This is a nice to have for incremental release of payment api, especially when merchant has already payment partners not supporting paymentrequest api.

@rsolomakhin
Copy link
Collaborator

+1. We should probably also make the 'validate()' function return a promise, so the browser can answer asynchronously.

@adrianhopebailie
Copy link
Collaborator

Right now on chrome 53, if we run this snippet of code, it will start showing up a payment window and then it disappears almost immediately. This make deceptive UX.

This sounds like a bug. The API should fail with no UI impact if the payment method is not supported.

The reason we don't currently have something akin to validate() is that we don't want merchants to use this API to farm information about their users.

Imagine you register a payment app from visit http://mikeshardware.com and install their payment app which supports a proprietary payment method for paying with loyalty points.

Now you visit http://bobshardware.com and they can test to see if you have that payment method supported?

Since we have agreed on using payment method manifests I'd suggest we have a set of allowed origins for validation as a way to resolve this but I'm sure there are some complex user consent issues we'll need to consider.

@adrianba
Copy link
Contributor

The current API is designed to avoid sites probing for what a user supports. Following a pattern used elsewhere, you commit to calling the API but if it turns out the API couldn't satisfy your goals then you revert to your fallback flow. This avoids the need for a validate method.

The flow should look something like this:

  1. When the user clicks "Checkout" you instantiate a PaymentRequest passing in all the information about the transaction and the payment methods you support.
  2. You call show() and wait for the promise that is returned to settle.
  3. If the browser can't satisfy the payment request, say because the user doesn't have any matching payment apps or instruments, then the promise is rejected with a NotSupportedError. When you see this result you redirect the user to the fallback flow.
  4. If the browser can satisfy the request then the payment request continues until either the user cancels or the promise resolves with the payment response.

If a user doesn't currently have the ability to pay using a supported method then the user agent may choose to offer to help the user install or configure that method. For example, if the site accepts basic-card but the user doesn't yet have any card details entered then the user agent can prompt the user to add one in order to complete the transaction. Since the next time the user sees such a site they will have a card entered the cost is only incurred infrequently. The normal flow is that the user does indeed have a payment method available to them.

For this reason I don't support adding a validate method or similar mechanism.

@baloo
Copy link
Author

baloo commented Sep 19, 2016

The problem with the fallback flow is we need to wait for user to click on something before calling the show() method. This makes two users have two interactions. A first one on "pay with payment request", then another one "sorry, we can't use payment request, do you want to try an alternative legacy method?". This looks pretty deceptive to me.

That being said, I totally agree with you, it sucks if a website can probe the payments methods supported by a user-agent.

@adrianba
Copy link
Contributor

adrianba commented Sep 19, 2016

The problem with the fallback flow is we need to wait for user to click on something before calling the show() method. This makes two users have two interactions. A first one on "pay with payment request", then another one "sorry, we can't use payment request, do you want to try an alternative legacy method?". This looks pretty deceptive to me.

I don't believe that is true. You don't currently ask if the user if they want to use the (only) legacy method before offering it to them. With PaymentRequest it should be as seamless. In step 3 above, you redirect without prompting the user anything. So they click the checkout button, and then see the legacy method. They may not know or care that in-between you checked with PaymentRequest. Alternatively, the user agent may have prompted them to install or populate a new payment method and when they declined they were redirected to the legacy flow. In either case it feels natural to the user.

@baloo
Copy link
Author

baloo commented Sep 19, 2016

Ok, I got your point. That's true, I didn't think about that.

@baloo baloo closed this as completed Sep 19, 2016
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants