Short answer
Show the customer that the card could not be verified, and let them try again or enter another card on the same SetupIntent. Don’t save the payment method or start the subscription until the SetupIntent succeeds. In test mode, check the flow with the always-authenticate test card.
Rather not fix it yourself? Stripe Billing Fix and Setup handles it at a fixed price, agreed before work starts.
Why the card fails authentication, and the fix
01
The customer failed or closed the 3D Secure check
“The provided payment method has failed authentication. Provide a new payment method to attempt to fulfill this SetupIntent again.” Stripe, Error codes (setup_intent_authentication_failure)
A wrong code, a closed bank window or a timeout all end here. Keep the SetupIntent and confirm it again with a new payment method; the customer can re-enter the same card.
const { setupIntent, error } = await stripe.confirmSetup({ elements, confirmParams: { return_url: 'https://example.com/billing' }, }); if (error?.code === 'setup_intent_authentication_failure') { showMessage('Your bank could not verify this card. Try again or use another card.'); }02
The app treats the card as saved anyway
“Setup Intents use 3DS to authenticate a payment method without charging it, then create a mandate or agreement for future charges.” Stripe, How Payment Intents and Setup Intents work
If your code stores the payment method or marks the account active before checking the result, later charges fail. Check that the status is succeeded, or listen for setup_intent.succeeded on your webhook.
03
The 3D Secure window never opens
With a custom flow, an unhandled requires_action status leaves the customer without the bank page. Use confirmSetup or handleNextAction from Stripe.js so the challenge shows.
04
Testing with the wrong card
“This card requires authentication on all transactions, regardless of how the card is set up.” Stripe, Testing (3D Secure cards)
Also check: a card that never asks for 3D Secure can’t show this flow. Use the always-authenticate test card 4000002760003184 and fail the challenge on the test page.
Checked against the vendor’s docs on : Stripe docs: Error codes; Stripe docs: How Payment Intents and Setup Intents work; Stripe docs: Testing.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- $950Stripe Billing Fix and SetupSubscriptions, webhooks, customer portal and failed payments set up or fixed, tested in Stripe test mode.See scope and start
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Working with Simon makes everything run so smoothly and better than I could ask for it. Amazingly communicative, extremely knowledgeable of coding and the backend processes. I strongly recommend.”
Related: Stripe authentication_required · Stripe no default payment method · Stripe generic_decline · Stripe payment_intent_authentication_failure