Skip to content

Authentication flows ​

Every authentication starts the same way: the Directory Server sends the ACS an authentication request, and the ACS assesses risk. What happens next falls into one of three shapes.

Frictionless ​

The ACS approves without involving the cardholder. Your platform is never called — there is no /step_up, and nothing for you to implement.

This is the majority of traffic in a healthy portfolio, and it is the outcome to optimise for.

OTP challenge ​

The cardholder enters a one-time code. The ACS generates and validates the code; your platform only delivers it.

sequenceDiagram
    participant DS as Directory Server
    participant ACS as Cake ACS
    participant You as Your platform
    participant CH as Cardholder

    DS->>ACS: AReq
    ACS->>You: POST /step_up
    You-->>ACS: SUCCESS, StepupType OTP
    ACS-->>DS: ARes — challenge
    DS->>ACS: CReq (challenge window opens)
    ACS->>You: POST /initiate_action (VerificationToken)
    You->>CH: Deliver the code
    CH->>ACS: Enters the code
    ACS->>DS: RReq — authenticated

The code arrives in /initiate_action as VerificationToken. Deliver that exact value. If your platform generates its own code instead, the cardholder receives one code while the ACS is checking against another, and every attempt fails.

Out-of-band challenge ​

The cardholder approves in your app. The ACS renders a waiting page and learns the outcome one of two ways.

sequenceDiagram
    participant ACS as Cake ACS
    participant You as Your platform
    participant CH as Cardholder

    ACS->>You: POST /initiate_action (OOBCallbackUrl)
    You->>CH: Push notification
    CH->>You: Approves in the app
    You->>ACS: OOB callback — SUCCESS
    Note over ACS,You: Or, if no callback arrives:
    ACS->>You: POST /validate
    You-->>ACS: SUCCESS / RETRY / REJECTED

The callback is a fast path, not a requirement. If it never arrives, the ACS polls /validate when the cardholder clicks Continue. Implementing the callback is still worth it — without it the cardholder waits for their own click to drive the check, instead of the page resolving as soon as they approve.

Resends ​

If the cardholder asks for a new code, the ACS calls /initiate_action again with the same StepupRequestId and StepupCounter incremented. Treat it as a redelivery of the same authentication session, not a new one.

Limits ​

All four end the authentication with transStatus N; they differ in the challenge cancellation indicator reported to the network.

LimitDefaultCancellation indicator
Failed attempts308
Challenge window opened (authentication response → first challenge request)30s05, with transStatusReason 14
Time between challenge rounds600s04
Total challenge lifetime, from creation30 min04

The per-round timers come from EMV 3-D Secure. The total lifetime does not — it exists because each per-round timer resets on the next response, so a client that keeps polling would otherwise hold a challenge open indefinitely, outliving the authentication session on your side.

Your platform does not need to enforce any of these; the ACS does. But your own session lifetime should be at least 30 minutes, or your session will expire under a cardholder the ACS still considers within limits.

Developers