3D Secure Testing: 3DS1 vs 3DS2 and Test Cards That Trigger Each Flow
3D Secure (3DS) is the authentication layer that shifts fraud liability from merchants to issuers. It is also the part of checkout testing that breaks most often, because it involves redirects, iframes, mobile SDKs and asynchronous outcomes. This guide covers what to test, which test cards trigger which flow, and the bugs that consistently slip through.
3DS1 vs 3DS2 in one paragraph
3DS1 is the original browser-redirect flow: the customer leaves your page, authenticates on the issuer's page, and is redirected back with a result. 3DS2 replaces the redirect with an SDK or device fingerprinting: the issuer receives additional device and transaction data and can approve frictionlessly (no user interaction) or issue a challenge (an in-page modal, or a redirect fallback on browsers that cannot support the SDK). Most gateways still support 3DS1 for older integrations, so a real test plan covers both.
The three outcomes you must handle
Every 3DS transaction ends in one of three ways, and all three need explicit UI states:
- Frictionless success โ authentication succeeds without user interaction. The most common 3DS2 result.
- Challenge โ the customer is asked to authenticate (OTP, app approval). Handle both success and failure/cancel.
- Not enrolled / unsupported โ the card does not participate. Depending on your gateway configuration you proceed or fail the transaction.
The failure paths are where checkouts break: a cancelled challenge is not the same as a decline, and users who close the modal must be able to try again without rebuilding the whole cart.
Stripe test cards for 3DS flows
Stripe documents dedicated test numbers for authentication behaviour:
| Card number | What it triggers |
|---|---|
| 4000 0025 0000 3155 | Requires 3D Secure authentication |
| 4000 0027 6000 3184 | 3DS required for the payment to succeed |
| 4000 0000 0000 3055 | Supports 3D Secure 2 |
| 4000 0000 0000 3220 | 3DS2 โ must complete the challenge flow |
These are designed for sandbox use only. For other providers, Adyen documents 4917 6100 0000 0000 for 3DS1 scenarios, and the generic success cards (4242โฆ, 4111 1111 1111 1111) in their sandbox. Always re-check the current provider docs โ test card behaviour changes without notice.
A fuller list lives in our test card numbers reference.
Sandbox setup checklist
- Enable 3DS in the gateway dashboard, not just in the API call. Many gateways have a per-account toggle that silently disables authentication in test mode.
- Use the 3DS2 SDK where available, and test the redirect fallback separately.
- Whitelist return URLs for every environment, including local dev tunnels.
- Test on real mobile devices, not only desktop narrow viewports. In-app browsers (Instagram, TikTok, banking apps) behave differently from Safari and Chrome.
- Keep the challenge window responsive. A challenge rendered inside a fixed-height iframe is a classic conversion killer.
Bugs that slip through
- Losing the cart on redirect. Persist the order before starting authentication, not after.
- Not handling the user pressing back. Browsers restore the page from bfcache; your JS must re-query the payment state instead of assuming a fresh load.
- Double submission. Users click "Pay" twice while the challenge is open. Use idempotency keys on the authorization request.
- Assuming success after challenge. The authentication result is a separate signal; the authorization can still decline afterwards.
- Async webhooks ignored. Some 3DS2 flows complete asynchronously. If you only listen to the redirect, you will miss results.
- Wrong amount or currency. Authentication is bound to the payment intent; changing the cart between authentication and capture invalidates it.
How to test without real cards
You do not need a real card to exercise 3DS. Provider test cards plus generated data cover the full matrix:
- Use provider cards for authenticated success, failure and frictionless flows.
- Use our card generator to produce large volumes of structurally valid numbers for load, fuzzing and UI tests.
- Use the advanced generator when you need every combination of a specific pattern.
- Validate any test number with the Luhn validator.
Summary
3DS testing is mostly about covering the unhappy paths: cancelled challenges, failed authentication, asynchronous results and mobile browsers. Provider test cards trigger each flow deliberately, and a generated dataset fills the gaps. Treat authentication as a separate state machine from authorization and you will avoid the majority of production incidents.