WooCommerce 3D Secure Not Triggering? Causes & Fix
If Stripe's 3D Secure step never appears at checkout, the payment stops dead: the PaymentIntent sits at requires_action, the charge never confirms, and the order fails. Here's how to find out why the modal isn't mounting.
Last updated: 16 Jul 2026 · ~6 min read
The most common cause is a JavaScript conflict that stops Stripe's 3D Secure modal from ever mounting — usually another plugin's script throwing an error, or an optimiser deferring and bundling Stripe.js. The PaymentIntent stays at requires_action and the charge never confirms. Open the browser console at checkout and look for the error, then exclude Stripe.js from JS optimisation.
What "3D Secure not triggering" actually means
When a card needs authentication, Stripe doesn't decline it — it parks the payment at requires_action and waits for your store to show the bank's 3D Secure challenge in an iframe. Stripe.js mounts that modal. If Stripe.js can't run, nothing is shown, nobody authenticates, and the PaymentIntent never advances.
The customer sees the Place order button spin and then a failure, or simply nothing at all. You see a failed or pending order, often with authentication_required attached. The money was never taken — this is a stalled payment, not a lost one.
The most common causes (most likely first)
- A JavaScript error stops the 3D Secure modal mountingAnother plugin or theme script throws before Stripe.js can open the iframe. Open the browser console at checkout — there's a red error at the moment you press Place order, and the PaymentIntent in Stripe stays at
requires_actionforever. - An optimisation plugin is deferring, combining or minifying Stripe.jsStripe.js has to load directly from
js.stripe.comand cannot be bundled, minified or deferred. Turn off JS combine/defer for the checkout page and retry — if the modal appears, this was it. - The iframe loads but is hiddenA theme
overfloworz-indexrule, a popup blocker, or a Content-Security-Policyframe-srcrule hides it. The console shows a CSP frame violation, or the modal element is in the DOM but not visible on screen. - The payment is being taken off-session, so there is no browser to show a modal inIt only fails on subscription renewals, admin-created orders or pay-links — never on a live checkout. That's where
authentication_requiredshows up as a decline: the card wanted authentication and no customer was present. - Nothing is broken — 3DS simply isn't being requestedStripe only triggers 3D Secure when the issuer or regional rules require it, or when a Radar rule asks for it. Look at the payment in the Stripe dashboard: if it went straight to
succeededwith norequires_actionstep, the card never needed authenticating. - You're testing with a card that doesn't require authentication
4242 4242 4242 4242never triggers 3DS. Use Stripe's authentication test card4000 0025 0000 3155instead.
Where to look first
- Open the payment in your Stripe dashboard. Stuck at
requires_actionand never advanced? That's the modal failing to mount — cause 1, 2 or 3. Straight tosucceededwith no authentication step? Nothing is broken (cause 5 or 6). - Open the browser console (F12 → Console), reload checkout and place a test order. A red JavaScript error the moment you click Place order points straight at cause 1 — the plugin named in the stack trace is your suspect.
- Turn off JS minify, combine and defer for the checkout page in your optimisation or caching plugin, purge the cache, and retry. Modal appears? Exclude
js.stripe.compermanently rather than leaving optimisation off. - Does it only fail on renewals or admin-created orders? That's cause 4 — the charge is off-session and needs the customer to authenticate via a payment link, not a modal.
- Still nothing with a clean console? Switch to a default theme and retry. If the modal appears, a theme rule is hiding the iframe (cause 3).
Losing sales to a modal nobody can see?
Chasing a 3D Secure modal that won't mount means bisecting plugins on a live checkout — slow, and every test costs you real traffic. DiagnosticIQ's free dashboard checks the checkout render chain, the Stripe key-mode integrity and the script path in one screen, and the AI names the concrete break rather than leaving you to guess. It keeps watching afterwards, so if the next plugin update knocks Stripe.js over again, you hear it from DiagnosticIQ before a customer tells you.
Get the free plugin →Made by Prima Digital — the team behind this guide. Free forever; no card to install.
How to know you fixed it
Place a test order with Stripe's authentication test card 4000 0025 0000 3155 — the 3D Secure modal should appear, and the Stripe log for that payment should read requires_action → succeeded.
Frequently asked
Was the customer charged?
No. A PaymentIntent stuck at requires_action never captures — there is nothing to refund. Check the Stripe dashboard to confirm no successful charge exists.
Will the payment go through later on its own?
No. Authentication has to happen in the browser while the customer is there. An unauthenticated PaymentIntent eventually expires and the order stays failed or pending.
What does authentication_required mean?
The card's bank wanted 3D Secure and didn't get it. On a live checkout that means the modal never mounted; on a renewal it means the charge was attempted with no customer present.
Can I just turn 3D Secure off?
Not if you sell into the UK or EEA — SCA rules make it mandatory for most in-person-absent card payments. Fix the modal rather than trying to bypass the step.