Challenge Flow
The purpose of the 3‑D Secure (3DS) process is to ensure that the actual cardholder is the one participating in the transaction authorization.
The Challenge Flow is used when additional verification of the cardholder is required — this could involve methods like a one‑time password (OTP) or identity verification through a federated identity provider.
Browser Challenge
A browser‑based challenge is handled either inside an iframe or in the full browser window.
Starting a Challenge
To begin the challenge flow:
- Create a Challenge Request (CReq) object using the transaction IDs received from the authentication response (
threeDSServerTransIDandacsTransID). - Render an iframe in the browser (can be done with static HTML or JavaScript).
- Add an HTML form that includes:
- A hidden field named
creqcontaining the CReq data. - A hidden field named
threeDSSessionDataif you want to maintain session information during the challenge.
- Submit the form to the ACS URL provided in the authentication response.
Example: Adding an Iframe
let displayBox = document.getElementById('displayBox');
let iframe = document.createElement('iframe');
iframe.name = "challengeIframe";
displayBox.appendChild(iframe);
Example: Challenge Form
<form id="challengeForm">
<input
type="hidden"
name="creq"
id="creq"
/>
<!-- This field can carry up to 1024 Base64‑URL encoded characters -->
<input
type="hidden"
name="threeDSSessionData"
id="threeDSSessionData"
/>
</form>
Example: Submitting the Challenge
// Create the CReq data object
let creq = JSON.stringify({
threeDSServerTransID: "ce2809be-b5ee-425b-9382-76a72a4f495b",
acsTransID: "7b26d24f-4275-4044-97ee-4564c1b88fde",
messageVersion: "2.1.0",
messageType: "CReq",
challengeWindowSize: "01"
});
// Get a reference to the form
let form = document.getElementById('challengeForm');
// Base64‑URL encode the data (must not be padded with '=')
document.getElementById('creq').value = base64url(creq);
// Configure and submit the form to the ACS URL
form.action = '<acsURL>'; // URL from the ARes message
form.target = 'challengeIframe';
form.method = 'post';
form.submit();
// Note: Implement base64url() in your code to handle encoding.
Receiving Challenge Results
When the challenge is completed, the iframe will send an HTTP POST request to your configured notification URL.
The POST body includes the threeDSSessionData (from your original request) and the challenge result, labeled as CRes.
Example CRes (Decoded)
{
"acsTransID": "87791cee-2514-436c-bed8-a63a87bbdf01",
"challengeCompletionInd": "Y",
"messageType": "CRes",
"messageVersion": "2.1.0",
"threeDSServerTransID": "d41f6200-0435-49ee-aa11-f366f0661c6f",
"transStatus": "Y"
}
Example Encoded POST Body
cres=eyJhY3NUcmFuc0lEIjoiODc3OTFjZWUtMjUxNC00MzZjLWJlZDgtYTYzYTg3YmJkZjAxIiwiY2hhbGxlbmdlQ29tcGxldGlvbkluZCI6IlkiLCJtZXNzYWdlVHlwZSI6IkNSZXMiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiJkNDFmNjIwMC0wNDM1LTQ5ZWUtYWExMS1mMzY2ZjA2NjFjNmYiLCJ0cmFuc1N0YXR1cyI6IlkifQ
The cres field is Base64‑URL encoded, and your implementation must be able to handle values with or without padding.
The property transStatus indicates the result of the challenge:
"Y"— Challenge successful"N"— Challenge failed or rejected
You can then continue by performing the post‑authentication flow to finalize the transaction result.
Handling Timeouts
- You must start the challenge within 30 seconds after receiving the authentication response.
- Each interaction within the challenge window has a 10‑minute timeout, allowing sufficient time for the cardholder to complete the challenge.