3DS 2.0
The 3DS 2.0 authentication (3-D Secure Authentication 2.0) validates the cardholder's identity during purchase, increasing transaction security and approval rate. This authentication reduces fraud risk for the buyer and prevents chargeback losses for the seller.
Integrate 3DS
3DS authentication can be performed through two flows: with Challenge or without Challenge. The Challenge is an additional verification step that the buyer must complete to confirm their identity. The decision to require the Challenge or not depends on the card issuer and the transaction's risk profile.
For low-risk transactions, the information submitted at checkout is sufficient and the Challenge is not required. For high-risk transactions, the Challenge is required to verify the buyer's identity, increasing the approval rate.
To integrate 3DS 2.0 in Checkout API with the Orders API, follow the steps below.
The 3DS configuration is performed through the config.online.transaction_security node when creating the order. To create an order with 3DS, send a POST to the endpoint /v1/ordersAPI including your Test Access TokenPrivate test key of the application created in Mercado Pago and used in the backend. You can access it through Your integrations > Integration data > Tests > Test credentials.. The request must contain the required parameters listed below.
curl --request POST \
--url https://api.mercadopago.com/v1/orders \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Idempotency-Key: {{SOME_UNIQUE_VALUE}}' \
--data '{
"type": "online",
"external_reference": "3ds_test",
"processing_mode": "automatic",
"capture_mode": "automatic_async",
"total_amount": "150.00",
"config": {
"online": {
"transaction_security": {
"validation": "on_fraud_risk",
"liability_shift": "required"
}
}
},
"payer": {
"email": "test@testuser.com"
},
"transactions": {
"payments": [
{
"amount": "150.00",
"payment_method": {
"id": "master",
"type": "credit_card",
"token": "{{CARD_TOKEN}}",
"installments": 1
}
}
]
}
}'
| Attribute | Type | Description | Possible values | Requirement |
capture_mode | String | Defines the payment capture mode. | automatic_async: automatic asynchronous capture.manual: manual capture. | Optional |
config.online.transaction_security.validation | String | Defines when the 3DS flow should be executed. | on_fraud_risk: 3DS is required according to transaction risk. We recommend using this value to balance security and transaction approval.never: the 3DS flow and Challenge are never executed (this is the default value if the field is not sent). | Required for 3DS integrations. |
config.online.transaction_security.liability_shift | String | Defines financial responsibility in case of chargeback. | required: the financial responsibility in case of chargeback belongs to the card network. This is the only accepted value for 3DS. | Required for 3DS integrations. Must not be sent when validation is never. |
After creating the order, the response will indicate whether the Challenge is required. If it is not required, the status field will have the value processed, allowing you to proceed normally with the application flow. If the Challenge is required, the order will be returned with status: action_required, status_detail: pending_challenge, and the Challenge URL will be available in the payment_method.transaction_security.url field, as shown in the example below:
{
"id": "ORDTST01KBD0NXX289XWW91Q9NNJ26V3",
"type": "online",
"processing_mode": "automatic",
"external_reference": "ext_ref_3ds",
"total_amount": "150.00",
"total_paid_amount": "150.00",
"country_code": "ARG",
"user_id": "791690672",
"status": "action_required",
"status_detail": "pending_challenge",
"capture_mode": "automatic_async",
"currency": "ARS",
"created_date": "2025-12-01T13:12:23.202Z",
"last_updated_date": "2025-12-01T13:12:24.943Z",
"integration_data": {
"application_id": "8275829243271683"
},
"config": {
"online": {
"transaction_security": {
"validation": "on_fraud_risk",
"liability_shift": "required"
}
}
}
"transactions": {
"payments": [
{
"id": "PAY01KBD0NXX289XWW91Q9P1BF71Q",
"amount": "150.00",
"paid_amount": "150.00",
"reference_id": "0007aoefzk",
"status": "action_required",
"status_detail": "pending_challenge",
"payment_method": {
"id": "master",
"type": "credit_card",
"token": "adac6b95f1d22c51890499d1707f0f0a",
"installments": 1,
"transaction_security": {
"url": "https://www.mercadopago.com.ar/auth/card/validation/pages/remedies/019ada0a-fe1f-7a82-ba1a-1ccb4e0232e7?display_mode=self_hosted&guest_token=0661345a-e0e1-4c09-aff9-b7929ca9a24a",
"validation": "on_fraud_risk",
"liability_shift": "required"
}
}
}
]
}
}
To display the Challenge, create an iframe using the URL returned in transactions.payments[i].payment_method.transaction_security.url. This iframe should be embedded in the checkout page, allowing the buyer to authenticate without leaving the flow.
When the Challenge is initiated, at the moment the URL is created, the buyer has 40 minutes to complete it. If it is not completed within this period, the bank will decline the transaction and Mercado Pago will consider the payment expired. If less time is needed, it is possible to cancel the transaction before the default timeout.
The status update is not immediate and may take a few moments. Check the next step for more details on how to verify the status of each transaction.
A transaction with 3DS can have different statuses depending on the type of authentication performed, with or without Challenge. For payments without Challenge, the transaction status will be directly processed or failed. For payments with Challenge, the transaction returns action_required and status_detail: pending_challenge, initiating the authentication process with the bank. The final status will only be displayed after the Challenge is completed.
To verify the transaction result after the Challenge, you can configure Webhook notifications to receive automatic alerts and redirect the buyer to a confirmation screen. Another option, which we recommend, is to handle an iframe event by implementing a JavaScript listener to detect when the Challenge has been completed and check the order status.
To handle the iframe event, follow the steps below.
- Implement the listener to detect when the buyer has completed the Challenge:
window.addEventListener("message", (e) => {
if (e.data.status === "COMPLETE") {
// Challenge completed. Redirect to confirmation page
window.location.href = "confirmation.html";
}
});
- Use the code below to check the order's updated status and display it on the confirmation page:
document.addEventListener("DOMContentLoaded", async function (e) {
await checkOrderStatus();
});
async function checkOrderStatus() {
const orderId = localStorage.getItem("orderId");
try {
const response = await fetch("/get_order/" + orderId, {
method: "GET",
});
const result = await response.json();
if (result.status !== 200) {
throw new Error("Error querying order");
}
// Display result
document.getElementById("order-status").innerHTML =
`Order ${result.data.id} - Status: ${result.data.status}`;
} catch (error) {
alert("Unexpected error: " + JSON.stringify(error));
}
}
Check below the main possible statuses and their respective descriptions:
| Status | Status detail | Description |
processed | accredited | Transaction approved without authentication. |
failed | failed | Transaction declined without authentication. To verify the reasons, see the Transaction status documentation. |
action_required | pending_challenge | Transaction pending authentication. The Challenge has been initiated and the buyer has up to 40 minutes to complete it. |
failed | cc_rejected_3ds_challenge | Transaction declined due to Challenge failure. |
canceled | expired | Transaction expired. The 40-minute Challenge timeout has expired without the buyer completing it. A new order needs to be created. |
In addition to the transaction's status and status_detail, you can also check the specific 3DS authentication status in the transactions.payments[i].payment_method.transaction_security.status field returned in the endpoint GET /v1/orders/{id}API, where the possible values and their descriptions are available.
To validate the 3DS integration, create a test order by sending a POST to the endpoint /v1/ordersAPI including your Test Access TokenPrivate test key of the application created in Mercado Pago and used in the backend. You can access it through Your integrations > Integration data > Tests > Test credentials. and the required parameters, including the transaction_security node with validation: on_fraud_risk.
curl --request POST \
--url https://api.mercadopago.com/v1/orders \
--header 'Authorization: Bearer {{YOUR_TEST_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Idempotency-Key: {{SOME_UNIQUE_VALUE}}' \
--data '{
"type": "online",
"external_reference": "3ds_test",
"processing_mode": "automatic",
"total_amount": "150.00",
"config": {
"online": {
"transaction_security": {
"validation": "on_fraud_risk",
"liability_shift": "required"
}
}
},
"payer": {
"email": "test@testuser.com"
},
"transactions": {
"payments": [
{
"amount": "150.00",
"payment_method": {
"id": "master",
"type": "credit_card",
"token": "{{CARD_TOKEN}}",
"installments": 1
}
}
]
}
}'
To test the created payment, use a test card, entering one of the values below in the cardholder_name field to simulate different Challenge flows:
pending_challenge status will only be returned when using the values APRO-CHOK or OTHE-CHNO in the cardholder_name field. For the other values, the order will return directly with the final status (processed or failed), without going through the pending_challenge status.cardholder_name value | 3DS Status | Status | Status detail | Description |
APRO-AUTH | authenticated | processed | accredited | Successful Challenge with authentication. |
APRO-ATMT | attempted | processed | accredited | Challenge attempted. |
OTHE-NAUT | not_authenticated | failed | failed | No authentication. |
APRO-CHOK | authenticated | processed | accredited | Challenge authenticated. |
OTHE-CHNO | not_authenticated | failed | failed | Challenge not authenticated. |
APRO-foobar | not_authenticated | failed | failed | Any other value results in failure. |
In test flows with APRO-CHOK and OTHE-CHNO, the Challenge will be displayed inside the iframe:

The verification code displayed is illustrative. To complete the test, click Confirm and then check the possible statuses in the Verify transaction status step to check the result.
After completing the 3DS integration and finishing the tests, your application will be ready for production. Before continuing, check the requirements in the Go to production documentation to ensure the integration is ready to receive real transactions.