3-D Secure moves the fraud liability from the merchant to the issuer and, since PSD2, is mandatory for most consumer card payments in the European Economic Area and the UK. It is also the part of a checkout most likely to be under-tested, because it involves a redirect or an iframe, an issuer-controlled screen, and a set of outcomes that a happy-path test never reaches.

What 3-D Secure actually does

It asks the issuing bank to confirm that the person paying is the cardholder, through a step the bank controls rather than one you build.

The commercial reason to adopt it is the liability shift. On an authenticated transaction, a later fraud-related chargeback is the issuer’s loss rather than yours. That is the trade every merchant is actually making: some friction at checkout in exchange for not carrying fraud losses.

Four parties are involved. Your server or gateway acts as the 3DS Server, sending the authentication request to a Directory Server run by the card network, which routes it to the Access Control Server operated by the issuer. The ACS decides what happens next, and your code’s job is to handle every answer it can give.

3DS1 redirected everyone to an issuer page asking for a static password. It worked and it cost conversions. 3DS2 — EMV 3-D Secure — sends around 150 data points about the device, session and transaction so the issuer can make a risk decision without interrupting anyone.

Frictionless and challenge

Two outcomes, and you must test both.

Frictionless. The issuer judges the risk acceptable from the data alone and authenticates without showing the customer anything. This is the majority of 3DS2 traffic in production, which is exactly why it is a trap: a team that tests 3DS by making a payment and seeing it succeed has usually tested only this path.

Challenge. The issuer wants more: a one-time code, an approval in the banking app, a biometric prompt. The customer leaves your interface for a screen you do not control, and comes back — or does not.

Everything difficult about 3DS lives in the second flow. It is where the layout breaks on mobile, where the customer abandons, where the back button produces an undefined state, and where the webhook race condition below appears.

PSD2 and SCA

Strong Customer Authentication requires two factors from different categories: something the customer knows, something they have, something they are. It applies in the EEA and the UK when both the cardholder’s issuer and the merchant’s acquirer are in the region — the European Banking Authority publishes the regulatory technical standards behind it.

The exemptions are what make SCA workable, and each is a scenario worth testing:

ExemptionCondition
Low valueUnder €30, subject to cumulative counters — five consecutive or €100 total since the last authentication
Transaction Risk AnalysisAvailable when the acquirer’s fraud rate is below defined thresholds, with the ceiling depending on the rate
Trusted beneficiaryThe cardholder has added the merchant to a list held by their issuer
Recurring, fixed amountSame amount, same merchant — authentication on the first payment only
Merchant-initiated transactionOut of scope entirely, given prior agreement with the cardholder
Corporate cardsPayments made through secure corporate processes

One property matters more than any individual row: an exemption is a request, not a decision. You flag the transaction as exempt, and the issuer may honour it or may authenticate anyway. Code that assumes an exemption request means no authentication will break the first time an issuer disagrees, which is a routine occurrence rather than an exceptional one.

Soft declines

When an issuer refuses a payment specifically because it was not authenticated, that is a soft decline. It commonly follows an exemption request the issuer chose not to honour.

The correct response is to retry the same payment with full authentication. The customer sees a challenge and the payment completes. What a surprising number of checkouts do instead is treat the response as an ordinary decline, show “your card was declined”, and lose a sale the issuer was willing to approve.

This is the single most valuable path on this page to test deliberately, because it is invisible in every happy-path test and it costs money on every occurrence. Not every decline means the card cannot pay, and distinguishing the categories is what separates a checkout that recovers from one that does not.

Testing 3DS by gateway

Every provider triggers authentication with its own cards, and the mechanics differ enough that experience with one does not transfer.

Stripe publishes a full matrix, and these are reproduced from its authentication flow documentation:

Card numberBehaviour
4000 0000 0000 3220Always requires a 3DS2 challenge, then succeeds
4000 0027 6000 3184Requires authentication on every transaction
4000 0084 0000 1629Requires authentication, then declines afterwards
4000 0025 0000 3155Requires authentication unless set up for off-session use
4000 0000 0000 3055Supports authentication but does not require it
4242 4242 4242 4242Supports 3DS but is not enrolled — no challenge appears

4000 0084 0000 1629 is the one to keep. It authenticates successfully and then declines, which breaks any code treating a completed challenge as a completed payment. The full Stripe reference has the rest of its set.

For the other providers, use their own documentation rather than a number copied from anywhere else — including here. Their 3DS card sets could not be verified against the providers’ published pages while writing this, so reproducing them would be guesswork:

What does not work anywhere is a generated number. The generator produces structurally valid cards with no issuer behind them, and authentication requires a real issuer directory to route to — the request has nowhere to go. The test card reference collects the published sets across processors.

The full test matrix

Success paths

  • Frictionless authentication succeeds
  • Challenge is presented and the customer answers correctly
  • An exemption is requested and honoured
  • A previously authenticated card is charged off-session without a new challenge

Failure paths

  • The customer cancels the challenge
  • The customer enters an incorrect code
  • The challenge times out
  • The ACS is unreachable — the issuer’s system is down
  • An exemption is requested and refused, producing a soft decline that must be retried with authentication
  • The card does not support 3DS at all
  • Authentication succeeds and the authorisation is declined anyway

Interface and infrastructure

  • The challenge iframe renders correctly on a mobile viewport
  • The cart survives a redirect and a return
  • The browser back button during a challenge leaves a defined state
  • Closing the tab mid-challenge does not orphan the order
  • The webhook arriving before the customer’s browser returns is handled
  • Double capture is prevented by an idempotency key

Sixteen cases, of which most teams test two. The mobile viewport item is worth singling out: the challenge is rendered by the issuer inside an iframe you do not control, and a fixed height that works on a desktop can clip the submit button on a phone — where most of your customers are.

The webhook race condition

This one deserves its own section because it produces bug reports that read as impossible.

The customer completes the challenge. The issuer notifies your gateway, which fires a webhook to your server. Meanwhile the customer’s browser is being redirected back to your success page. These two things race, and the webhook usually wins.

Two failure modes follow. If your success page reads order status from your own database and the webhook has not been processed yet, the customer sees “pending” or an error for a payment that has actually succeeded. If instead your success page trusts a parameter the browser brought back, you have a security hole — that parameter is attacker-controlled.

The correct pattern:

  1. The webhook is the source of truth for fulfilment. Nothing ships because a browser said so.
  2. The success page polls or subscribes for the order’s status rather than asserting it.
  3. Show a brief confirming state — a spinner and “confirming your payment” — instead of a premature success or failure.
  4. Make the webhook handler idempotent, because the same event will arrive more than once.

Test it by deliberately delaying your webhook processing and confirming the success page degrades into the confirming state rather than into an error. Then test the opposite ordering, where the browser returns first and the webhook is slow, since both orderings occur in production and only one of them is the one you happened to observe while developing.

Common mistakes

  1. Testing only the frictionless flow, because it is the one that happens by default.
  2. Never testing the soft decline retry, and losing recoverable sales silently.
  3. Not testing the challenge on a mobile viewport.
  4. Trusting a client-side result rather than the webhook.
  5. Ignoring the race condition and shipping a success page that lies in either direction.
  6. Requesting no exemptions at all, adding friction — and losing conversion — for nothing.
  7. Assuming a requested exemption will be granted.
  8. Flagging merchant-initiated transactions incorrectly, so recurring charges are challenged when nobody is there to answer.

Measuring the impact

3DS affects conversion, and a challenge always costs some abandonment. The numbers worth tracking:

  • Challenge rate — what share of authentications interrupt the customer
  • Challenge completion rate — how many who see one get through it
  • Post-3DS authorisation rate — authentication is not approval
  • Exemption acceptance rate — how often issuers honour your requests

The tension is straightforward: fewer challenges means better conversion and more chargeback exposure, and the balance depends on your fraud rate and your margin. What you should not do is guess. Measure the four rates above, change one thing, and watch them — the payment form checklist covers the layers below this one, which need to be solid before any of these numbers mean anything.

The Stripe card numbers and gateway references above were last checked against provider documentation on . Providers do change what they publish — the official link beside each claim is authoritative.

Frequently Asked Questions

An authentication step run by the card issuer during an online payment, to establish that the person paying is the cardholder. Its commercial point is the liability shift: when a payment is authenticated successfully, responsibility for a fraudulent-transaction chargeback moves from the merchant to the issuer. That shift, rather than the security itself, is why most merchants adopt it.
3DS1 redirected every customer to an issuer-hosted page and asked for a static password, which was slow and cost conversions. 3DS2 sends around 150 data points about the device, the transaction and the customer’s history, letting the issuer approve low-risk payments without showing anything at all. Most 3DS2 authentications are now invisible to the customer.
In the European Economic Area and the UK, strong customer authentication is required for most consumer card payments where both the cardholder’s bank and the merchant’s acquirer are in the region, and 3DS is how card payments satisfy it. Elsewhere it is optional, and merchants weigh the liability shift against the conversion cost of a challenge.
An authentication the customer never sees. The 3DS2 data is sent to the issuer, the issuer judges the risk low enough, and the payment is authenticated with no challenge screen. It is the common case in production, which is exactly why testing only the frictionless path leaves the challenge flow unexercised.
An issuer refusing a payment specifically because it was not authenticated, rather than because the account cannot pay. It typically follows an exemption request the issuer declined to honour. The correct response is to retry the same payment with authentication, not to show the customer a failure — and a checkout that treats a soft decline as a hard one loses a sale it had already won.
With your gateway’s own 3DS test cards, which trigger frictionless, challenge, failed-authentication and error paths deliberately. Generated card numbers cannot produce any of it, because authentication involves a real issuer directory. Test the challenge on a mobile viewport as well as a desktop one — the challenge is an issuer-controlled iframe and it is where layout problems hide.