OOB callback
The one endpoint where you are the client. Call it as soon as the cardholder approves or refuses an out-of-band challenge in your app, so the waiting page resolves immediately instead of waiting for them to click Continue.
The URL is sent to you on every out-of-band /initiate_action as OOBCallbackUrl. Use that value rather than hardcoding a path.
Optional, but worth implementing
Without the callback the flow still completes — the ACS falls back to polling /validate. The difference is the cardholder's experience: with the callback the page resolves the moment they approve; without it, nothing happens until they click Continue.
Request
POST /oob-callback HTTP/1.1
Content-Type: application/json
signature: <base64 HMAC-SHA256 of the raw body>
{
"TransactionId": "9f6b6a2e-6f4e-4d0a-9b6e-2f9d6c1a7e10",
"StepupRequestId": "b2b6c9a4-1d0e-4e3a-8c8b-5a1f2d3c4b5a",
"Status": "SUCCESS",
"Reason": {
"ReasonCode": "USER_APPROVED",
"ReasonDescription": "Approved in the app"
}
}| Field | Required | Description |
|---|---|---|
TransactionId | Yes | The value received in /initiate_action |
StepupRequestId | Yes | Must match the session, or the call is rejected |
Status | Yes | SUCCESS or FAILURE |
Reason | No | Recorded for troubleshooting; does not affect the outcome |
The signature header is mandatory in production — see Security for how to compute it.
Responses
| HTTP | Body Status | When |
|---|---|---|
200 | SUCCESS | Recorded. Also returned for a duplicate of an already-final result |
400 | ERROR | Malformed body, invalid Status, or the session is not out-of-band |
401 | ERROR | Missing or invalid signature |
404 | ERROR | Unknown TransactionId, or StepupRequestId does not match it |
405 | ERROR | Method other than POST |
500 | ERROR | The ACS could not read or persist the result — safe to retry |
Idempotency
Repeat calls are safe. Once a session is final, a duplicate callback is ignored and still answered 200 — so a retry after a network error will not corrupt an already-recorded result.
Retry on a 5xx or a timeout. Do not retry on 400, 401, or 404: those mean the request itself is wrong, and repeating it unchanged will fail the same way. A 404 in particular usually means the session already expired.
Ordering
Send the callback once you have a final answer from the cardholder. If it arrives after the ACS has already finalised the authentication through /validate, it is accepted and ignored — the first terminal result wins.