Search code examples
javascriptiossafaristripe-payments

Stripe Checkout popup blocked on iOS Safari


I'm encountering an issue with Stripe Checkout integration in my web application specifically on iOS Safari. Here's the scenario:

  • I generate a Stripe Checkout link on the backend.
  • I send this link to the frontend, where it's supposed to open in a new URL.

However, on iOS devices, Safari blocks the popup, preventing the Checkout from opening.

Here is the code I use to open in a new tab:

export function openInNewTab(url,filename = "") {
let a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = (filename?filename:url);
a.target =  '_blank';
a.click();
document.body.removeChild(a);   }

I've explored various solutions, like trying different JavaScript methods to open the link in a new tab or window.

I'm even considering detecting iOS devices and adjusting the payment flow accordingly, possibly opening the Checkout in the same tab. But I prefer to avoid doing this.

I cannot rely on users to adjust their Safari settings, and direct integration with Stripe Elements isn't feasible for my use case.

Does anyone have insights or recommendations on how to resolve this issue and ensure a smooth Stripe Checkout experience on iOS Safari ?

I also the same issue when trying to download files with the same function.

Thanks in advance for your help!


Solution

  • It's best practice to redirect customers to Checkout as a result of clicking on a button/link. That's when you can open a new tab. It's best if that new tab points at an endpoint in your own server, which creates a Checkout Session on the fly and, in turn, redirects the customer to the Checkout Session. You don't actually need to pass the Checkout URL to the frontend. This way you can also avoid creating an <a> element dynamically, which might cause your problem.

    On another note, it's best to open the Checkout Session in the same tab. You can then redirect the customer back to your site with success_url property. This way the flow is linear.