Why would Stripe paymentRequest.canMakePayment() fail on Localhost?

Freewalker picture Freewalker · Mar 20, 2018 · Viewed 7.4k times · Source

I'm getting this to work on my production server, but on localhost canMakePayment() returns null.

I've traced this through the minified Stripe code but hit a wall with function ko which just sends an action called CAN_MAKE_PAYMENT to some message queue, at which point execution becomes asynchronous and I can't track further until the request is resolved with e.available === false with no further information.

I've verified the API is indeed available in Chrome on localhost (window.PaymentRequest is available). I'm also running on local https (though without a green check).

How can I trace what is causing Stripe to report that PaymentRequest is unavailable? Will Chrome reject PaymentRequest calls if I don't have a green SSL check? If so, how would I test this? Chrome documentation just says if PaymentRequest is available then you can call the API.

If I know where the message queue is getting processed I could debug further.

Answer

Ryan picture Ryan · Apr 1, 2018

Stripe's support team confirmed to me that a green SSL verification is required.

"One of the prerequisites for the payment request button is that the page the payment request is located on will have to be served as secure with a valid certificate. This is a requirement for both production and development."

Here is an experiment. Browse to a site in Chrome where the URL says "Secure https:" in green, such as https://stackoverflow.com. Open the developer console, and paste in these commands (from here) and press Enter:

const supportedPaymentMethods = [
  {
    supportedMethods: 'basic-card',
  }
];
const paymentDetails = {
  total: {
    label: 'Total',
    amount:{
      currency: 'USD',
      value: 0
    }
  }
};
const options = {};
const request = new PaymentRequest(
  supportedPaymentMethods,
  paymentDetails,
  options
);
request.show();

You'll then see a payment request modal pop up.

But if you browse to your own local site that where the address bar says in red "Not secure" (and "https" is crossed out), and if you try to run that same code in the console, no payment request modal will pop up (even if you've added a security exception for the domain).

So, apparently Chrome (and probably other browsers) prevent Stripe (and other tools like Stripe) from accessing that browser functionality when the connection isn't fully secure.

UPDATE from Stripe:

While Chrome iOS does include a PaymentRequest implementation, it does not allow PaymentRequest to be used from an iframe which prevents Stripe's payment request button element from working. We're working with the Chrome team to get this resolved in a future release.

In order for Apple Pay to work in the iOS Simulator or on a test device the domain must be publicly accessible and registered through the Stripe dashboard (https://dashboard.stripe.com/account/apple_pay) or API. https://stripe.com/docs/stripe-js/elements/payment-request-button#verifying-your-domain-with-apple-pay We recommend using a tool like ngrok (ngrok.com) to create a public-facing domain with a valid HTTPS certificate that tunnels to your local environment.