22

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.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Freewalker
  • 6,329
  • 4
  • 51
  • 70
  • +1. GREAT question, @Luke. Have you figured out the solution? (Your answer below wasn't specific.) I too lack a green SSL verification and have been having trouble with https://stackoverflow.com/questions/48969083/err-cert-authority-invalid-using-laravel-homestead If you got Stripe's `canMakePayment()` working locally, I'd LOVE your thoughts! Thanks! – Ryan Mar 30 '18 at 21:28
  • I've added a big bounty to my question: https://stackoverflow.com/q/48969083/470749 – Ryan Mar 31 '18 at 23:01

4 Answers4

14

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.

Community
  • 1
  • 1
Ryan
  • 22,332
  • 31
  • 176
  • 357
  • 2
    Confirmed the same. Chrome will enable payment if EITHER you have a green check OR you're on localhost. However, Stripe adds an additional string check in the URL for "https" which defeats Google's decision to allow localhost. The only fix is either to modify that line in the Stripe lib (ugly) or get green check on localhost. I've requested Stripe fix this and trust Google's implementation of security protocol. – Freewalker Apr 02 '18 at 12:43
  • I'm now facing a really interesting case. On iOS (Chrome or Safari), visiting my local site (which has a green lock for https because I've installed the certificate to my phone), this `request.show()` code from above works, but Stripe's `paymentRequest.canMakePayment()` does *not*! It returns `null`. And I hoped I'd fixed everything with https://stackoverflow.com/questions/48969083/how-to-get-https-certificate-working-on-local-laravel-homestead-site?noredirect=1&lq=1#comment86322473_49612084 and https://apple.stackexchange.com/a/321537/53510 – Ryan Apr 05 '18 at 03:34
  • 3
    Stripe's PaymentRequest button implementation relies on PaymentRequest working inside iframes. However, due to a bug in Chrome iOS, PaymentRequest is not available inside the button's iframe and so cannot be used in that browser. – hpar Apr 06 '18 at 20:34
  • @hpar, Wow. That's helpful, because when I read "Chrome Mobile" on https://stripe.com/docs/stripe-js/elements/payment-request-button#testing, I totally didn't notice that it didn't include iOS. Thanks. And that sucks. – Ryan Apr 06 '18 at 21:14
  • By the way, to get Ngrok working, I needed to use Windows PowerShell as Admin: `PS C:\code> .\ngrok http -host-header=rewrite mysite.test:80` (and not use an xip.io domain with port 44300). – Ryan Nov 17 '18 at 00:54
1

I was experiencing the same issue, but paymentRequest.canMakePayment() was returning null on both development and production despite working fine previously in Chrome.

The issue is that Google have disabled the basic-card payment method in the PaymentRequest API, so browser-saved cards no longer work and the payment request button no longer appears in our checkout.

The solution was to:

After performing these two steps the Google Pay button appeared in our checkout, and on our development server the test cards appeared in the payment methods on the pay sheet.

There no longer appears to be a way of testing browser-saved cards, which is a bit of a pain when you're trying to test your integration and simulate things like failed payments.

Hopefully this will be helpful to others who encounter this issue.

billyonecan
  • 20,090
  • 8
  • 42
  • 64
0

Bypassing Stripe, I was able to verify that Chrome is reporting "basic-card" payment method is not supported.

This required setting up a PaymentRequest per Google's documentation and attempting a request.show() command.

I'm guessing this has to do with not having a green SSL verification, I'll try fixing that.

Freewalker
  • 6,329
  • 4
  • 51
  • 70
0

You should enable SSL in Visual Studio to use paymentRequest.

Enable SSL in Visual Studio

Leo
  • 398
  • 6
  • 11
  • And what is relation between this question and visual studio code? Was not mentioned once... – norr Jul 08 '21 at 18:10