Skip to main content

3D Secure Authentication

Integrate 3D Secure into your payment flow to reduce fraud and comply with regulatory requirements.

What is 3D Secure?

3D Secure (3DS) is an authentication protocol that adds an extra layer of security to card transactions. When active, the issuing bank can ask the cardholder to authenticate themselves during the payment process.

Benefits:

  • Fraud reduction
  • Regulatory compliance
  • Customer trust

Authentication Flow

Not all transactions require 3DS

The system automatically evaluates each transaction. You will only receive the AUTHENTICATION_REQUIRED status when necessary.


Implementation

Step 1: First Request

Always send authenticationId: null in your first payment or subscription request.

{
"customer": {
"id": "customer112",
"name": "Carlos Dúran",
"email": "[email protected]",
"phoneNumber": "+50364331900"
},
"order": {
"id": "EPAY001",
"amount": 15.9,
"description": "insurance",
"name": "auto"
},
"cardId": "69167196381d34f25eb22e9d",
"authenticationId": null,
"locationCode": "N1C0CD001"
}

Step 2: Handle Response

If you receive the AUTHENTICATION_REQUIRED status, you must display the authentication iframe:

{
"status": "AUTHENTICATION_REQUIRED",
"message": "Payment requires 3DS authentication",
"error": null,
"authentication": {
"url": "https://front-3ds.h4b.dev/authentication/b574cee2-1ce7-4aa7-b176-8a6390e91081",
"id": "b574cee2-1ce7-4aa7-b176-8a6390e91081"
},
"order": null,
"createdAt": "2023-09-28T18:53:51.1070240Z"
}

Step 3: Render Iframe

Create an iframe to display the authentication interface:

const iframe = document.createElement('iframe');
iframe.src = authentication.url;
iframe.width = 600;
iframe.height = 400;

document.getElementById('authentication-container').appendChild(iframe);

Implementation Examples:

Step 4: Listen for PostMessage

The iframe will send a message when authentication is complete:

window.addEventListener('message', function(event) {
// Validate message origin
if (event.origin !== 'https://front-3ds.n1co.com') {
return;
}

const data = event.data;

// Handle different statuses
handleAuthenticationResult(data);
});

function handleAuthenticationResult(data) {
const { MessageType, Status, AuthenticationId } = data;

if (MessageType === 'authentication.complete' && Status === 'SUCCESS') {
// Proceed with the second request
completePayment(AuthenticationId);
} else if (MessageType === 'authentication.failed' || Status === 'FAILED') {
// Show error to the user
showError('Authentication failed. Please try another payment method.');
} else if (Status === 'EXPIRED') {
// Authentication expired
showError('Authentication has expired. Please try again.');
}
}

PostMessage Structure

FieldTypeDescription
MessageTypeStringauthentication.complete | authentication.failed
StatusStringPENDING | SUCCESS | FAILED | ERROR | EXPIRED
AuthenticationIdStringUnique authentication ID for the second request
OrderIdStringOrder ID
OrderAmountNumberOrder amount

Possible Statuses:

StatusDescriptionAction
SUCCESS✅ Successful authenticationProceed with the second request
FAILED❌ Failed to authenticate with the bankRequest another payment method
ERROR❌ Internal processor errorRetry or contact support
EXPIRED⏱️ Authentication session expiredRestart the process
PENDING⏳ Still processingContinue waiting

Step 5: Second Request

Once the message with MessageType = "authentication.complete" and Status = "SUCCESS" is received, make a new request including the authenticationId:

Successful Response

The response to this second request will have the status SUCCEEDED if the authentication was completed correctly.


Best Practices

✅ Do

  • Always send authenticationId: null in the first request
  • Validate the origin of PostMessage messages for security
  • Handle all possible statuses (SUCCESS, FAILED, ERROR, EXPIRED, PENDING)
  • Provide clear messages to the user during the process
  • Log events: For debugging and analysis
  • Design a responsive UI: The iframe should adapt to different devices

❌ Don't

  • ❌ Do not reuse authenticationId from previous transactions
  • ❌ Do not send authenticationId if you did not receive AUTHENTICATION_REQUIRED

Complete Flow Diagram


Additional Resources