ProductAugust 26, 20266 min read

Stripe SCA Delay: Why Subscription Payments Sit in Limbo and How to Unstick Them

A Stripe renewal stuck in requires_action is SCA doing its job at the worst time. Why it happens and how to unstick the payment fast.

Diagram of an SCA delay: renewal attempted, bank demands 3DS authentication, a 7-day clock runs in silence, and one email with the auth link clears it
Requires_action isn't a decline. It's a question nobody answered yet.

What an SCA delay actually is

An SCA delay is a subscription payment sitting in requires_action: Stripe tried to charge a saved card, the bank demanded Strong Customer Authentication, usually a 3D Secure prompt, and the payment froze because the customer isn't there to approve it. No money moved, no failure yet, just limbo.

If you've seen a renewal invoice stuck open with no clear error, this is usually why. The charge didn't decline. It's waiting on a human who doesn't know they need to do anything.

A 60-second SCA primer

Strong Customer Authentication comes from Europe's PSD2 regulation, and the UK has its own version. It requires two independent proofs of identity for most electronic payments: something the customer has, knows, or is. In card terms, that usually means a 3D Secure challenge, the bank page or app prompt where the customer approves the charge.

The regulation was written for a world where the customer is sitting at the checkout. Subscriptions break that assumption: the charge happens later, automatically, with nobody present. The rules accommodate this through merchant-initiated transaction exemptions, but the exemption is a request, not a guarantee. Banks decide, charge by charge, whether to insist on authentication anyway.

Why a renewal triggers authentication at all

SCA is an EU and UK regulation requiring two-factor approval for customer payments. It was designed for someone actively checking out, not for a subscription renewing at 3am while the customer sleeps. Renewals are supposed to slip through as merchant-initiated transactions, a category that normally qualifies for exemption.

Usually that works. When it doesn't, it's one of these: the original mandate wasn't set up with the right flags, the bank's risk engine decided this charge looks odd, the amount jumped well above the usual renewal, or the card network or issuer simply isn't playing along. Banks have final say, and some of them demand authentication far more often than they should.

What limbo looks like in your stack

A worked example, because the dashboard view confuses everyone the first time. Renewal day arrives for a customer in Germany. Stripe creates the invoice, attempts the charge, and the bank responds with an authentication requirement. The payment intent flips to requires_action. The invoice stays open. The subscription, depending on your settings, may flip to past_due, which makes it look exactly like a failed payment in most dashboards.

The customer, meanwhile, got an email they didn't read. Seven days pass, the payment intent expires, and now the invoice genuinely is uncollectible without a new attempt. From the outside it looks like churn. From the inside it was a notification problem. Knowing the difference is the entire game here.

The payment intent sits in requires_action. The invoice stays open. No invoice.payment_failed webhook fires, because nothing failed, which means naive dunning setups never notice. Your customer still has access, you have no revenue, and days pass.

If the customer never authenticates, the attempt eventually expires and then you get a failed payment, days after the original charge date, with the recovery clock starting late. That delay is the real damage. Recovery odds drop every day the customer doesn't hear from you, and SCA limbo eats those days silently.

How to unstick the payment

  • Send the customer a link to the hosted invoice page. Stripe's hosted page runs the full 3DS flow, and authentication takes under a minute. Speed matters here, same day if you can.
  • Watch for requires_action, not just payment_failed. If your webhook handling only listens for failures, add a check for open invoices with a payment intent awaiting action. That's your early warning.
  • Write the email like a human. This isn't a payment failed message. It's a quick heads-up: your bank wants you to confirm this charge, here's the link, takes a minute.
  • Follow up once before it expires. One reminder while the window is still open beats a dunning sequence after it closes.

What the customer actually sees (and why they ignore it)

Stripe can email the customer about the required action automatically, pointing them at the hosted invoice page. The problem is the usual one: it's a system notification, it looks like every other system notification, and the customer files it under 'later.' Later becomes the payment expiring. This is why a short personal note from you, sent the same day, outperforms waiting on automation: 'Hey, your bank wants you to confirm this charge, here's the link, takes a minute' gets clicks because it reads like a person.

How to reduce how often it happens

You can't eliminate bank behavior, but you can stack the deck. Make sure subscriptions are created with proper off-session setup so renewals get flagged as merchant-initiated from day one. Keep renewal amounts consistent where possible, since big jumps attract risk checks. And if a specific customer hits authentication repeatedly, their bank is the pattern, so a card on file from a different issuer often ends the saga.

We cover the exemption mechanics in detail in the SCA exemptions post, and the authentication-failure side in the 3DS post. This one's about the limbo in between.

Monitoring, so limbo never surprises you again

The operational fix is one report or one alert: any invoice still open with a payment intent in requires_action after 24 hours gets flagged to you. That's it. You don't need a dashboard full of charts. You need to know, today, which renewals are waiting on a human, so a human, you, can nudge them before the window closes.

If you want to handle this programmatically instead of by hand, the shape is simple. Listen for invoices stuck in open with a payment intent in requires_action, wait 24 hours to give the customer a chance to act on their own, then send one personal email with the hosted invoice link. That link takes them straight to the authentication step, no login to your app required. One email, one link, and most limbo payments clear within a day of it landing.

Whatever you do, don't let your access control treat requires_action as a decline. The customer hasn't failed anything. Their bank asked a question and nobody answered yet. Suspending access during the authentication window punishes a customer for their bank's caution, and it converts a delay into a cancellation. Past_due grace periods exist for exactly this scenario. Set the grace window deliberately too: 7 days is a sane default, long enough for a distracted customer to notice three reminders, short enough that limbo can't become permanent free access. After the window, the standard dunning flow takes over and the payment behaves like any other failure. Once it's in the normal flow, everything you already built for declines applies, and no special casing is needed beyond the grace window itself. Simple, boring, and it works reliably every single time.

The takeaway for your dunning setup

Most failed-payment systems are blind to SCA delays because they only react to failures. A payment stuck in requires_action is a failure in slow motion. The fix is one extra listener and one fast, personal email. Do that and a chunk of your future failed payments simply never become failures.

"An SCA delay is a failed payment on a timer. Catch it during the delay and it never has to become one."

FAQ

Why is a Stripe subscription payment stuck on requires_action?

The bank is demanding SCA authentication, usually 3D Secure, for a charge the customer isn't present for. The payment waits until the customer completes authentication or the attempt expires.

How long can a Stripe payment sit in requires_action?

The customer typically has a limited window, often hours to days depending on the payment method, to authenticate. If they don't, the attempt fails and the invoice follows your dunning settings.

Do subscription renewals require SCA every time?

They shouldn't. Merchant-initiated transactions on a saved card, set up correctly, usually qualify for exemption. Banks can still demand authentication, but well-flagged renewals rarely trigger it.

How do I get a customer to complete a delayed SCA payment?

Stripe's hosted invoice page handles the 3DS flow. Email the customer a direct link to that page quickly, while they still remember the charge, and the authentication takes under a minute.

R

Robert

Founder at StayPaid

Want to recover failed payments like a founder?

Start Free — First 3 recoveries