# Fix Stripe setup intent stuck in requires_action

## TL;DR
A setup intent stuck in requires_action means the customer never completed the 3D Secure or bank authentication step. Send the customer back through the authentication flow with the client secret, and only treat the payment method as saved when the intent reaches succeeded. The intent is waiting, not broken.

## The error
```text
Stripe setup intent stuck
Status: requires_action. Next action: redirect to complete authentication.
```

## Use this skill
Agent? Search Vectle for this error:
```bash
curl -s "https://vectle.com/api/v1/search?q=stripe setup intent requires_action stuck"
```

## Fix it

### Step 1: Get the client secret

```bash
Retrieve the setup intent and note its client secret.
```

Expected: You have the secret for the stuck intent.

### Step 2: Send the customer through authentication

```bash
Use Stripe.js confirmCardSetup with the client secret to present the auth flow.
```

Expected: The customer completes the bank or 3DS challenge.

### Step 3: Check the intent status

```bash
Retrieve the setup intent again after the flow.
```

Expected: Status is succeeded.

### Step 4: Handle the abandonment case

```bash
If the customer never returns, expire or cancel the intent and prompt them to restart setup.
```

Expected: No stuck intents linger; the UX explains what happened.

### Step 5: Confirm the payment method saved

```bash
Check the customer record for the new payment method.
```

Expected: The method is attached and usable.

## When this applies

- Stripe setup intents stick in requires_action
- Saved cards never finish setting up
- You are building 3D Secure card setup flows

## When it doesn't

- The intent fails outright (check the card and error code)
- The intent succeeds but the method is missing (check the customer attach)
- You are doing one-off payments (that is payment intents, not setup intents)

## Compatibility

Stripe SetupIntents API. Stripe.js for the auth flow.

## Variant phrasings

### stripe setupintent requires_action stuck

Same state. The customer action is the missing piece; nothing server-side unsticks it.

### stripe card setup 3ds not completing

3DS challenges that never complete leave the intent waiting. Re-present the challenge.

### stripe setup intent abandoned

Abandoned intents stay in requires_action. Cancel them and let the customer restart.

## Why it happens

requires_action is a paused state awaiting the customer. Strong customer authentication rules mean the bank must see the customer approve, and until that happens Stripe cannot proceed. Backends that treat requires_action as a failure, or never surface the next action to the customer, leave intents parked forever.

## Edge cases

- Setup intents expire; do not keep presenting ancient client secrets
- Test cards trigger 3DS in test mode; use them to exercise the full flow
- Webhooks for setup_intent.succeeded are the reliable signal, not the return URL alone

## If it still fails

- Reproduce in test mode with test cards before touching live config.
- Read the full API error object; the code and decline code name the next step.
- Check the provider status page; payment API incidents look like integration bugs.
- Never retry live charges blindly; verify state first and use idempotency keys.
- For money-movement confusion, reconcile against the dashboard before writing code.

## Prevention

- Exercise the full payment flow in test mode on every deploy.
- Alert on failed payment webhooks, not just API errors.
- Keep idempotency keys on every charge-creating call.
- Reconcile payouts against the dashboard on a schedule.
- Document the retry and dunning policy so agents and humans agree.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_ktfG4541OrWzTg_RKF_hLw
