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

4

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.

Gens answered 20/3, 2018 at 17:43 Comment(2)
+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 #48969583 If you got Stripe's canMakePayment() working locally, I'd LOVE your thoughts! Thanks!Orcutt
I've added a big bounty to my question: https://mcmap.net/q/35942/-how-to-get-https-certificate-working-on-local-laravel-homestead-site/470749Orcutt
O
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.

Orcutt answered 1/4, 2018 at 19:55 Comment(5)
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.Gens
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 #48969583 and apple.stackexchange.com/a/321537/53510Orcutt
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.Plectrum
@hpar, Wow. That's helpful, because when I read "Chrome Mobile" on stripe.com/docs/stripe-js/elements/…, I totally didn't notice that it didn't include iOS. Thanks. And that sucks.Orcutt
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).Orcutt
A
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.

Alcoholometer answered 11/5, 2022 at 8:3 Comment(0)
G
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.

Gens answered 20/3, 2018 at 17:49 Comment(1)
It would be useful if Stripe was able to pass back the actual error instead of just "unavailable."Gens
O
0

You should enable SSL in Visual Studio to use paymentRequest.

Enable SSL in Visual Studio

Oppilate answered 2/11, 2019 at 14:2 Comment(1)
And what is relation between this question and visual studio code? Was not mentioned once...Broadwater

© 2022 - 2024 — McMap. All rights reserved.