Create a 3DS Authenticated Payment
Add an extra layer of security to your transactions and reduce fraud risk by implementing 3D Secure (3DS) authentication. This guide demonstrates how to use the GetNet Global API to verify a cardholder’s identity before processing their payment.
Requirements
Before starting the integration, complete the following:
- API Credentials: Contact the Integration Support Team to obtain your
client_idandclient_secret. - Access Token: Generate a Bearer token using your credentials via the Access Token endpoint.
- Card Brand Support: Verify the card brand is Mastercard or Visa. These are currently supported for 3DS in Argentina, Chile, Mexico, Spain, Brazil and Uruguay.
Mandatory for Europe: Transactions within the European Economic Area (EEA) require 3DS authentication to comply with PSD2 and Strong Customer Authentication (SCA). Refer to the Taxes and Regulations documentation for exemption details.
Payment facilitators: When Getnet enables your credential as a payment facilitator, you must also send the
data.sub_merchantobject when you create the payment. See Payment Facilitators.
Understanding the 3DS Authentication Process
The card issuer dynamically determines the authentication flow based on risk assessment, card brand, and issuer capabilities. After you initiate enrollment, the API returns a status field that dictates your next action.
Handle the three possible scenarios:
- Direct Authentication: The issuer authenticates the cardholder immediately (status:
AuthenticatedorAttempt). - Challenge Required: The issuer requires interactive cardholder verification (status:
Pending Challenge). Choose between rendering an HTML template or performing a manual POST using the ACS Direct Form data. - Pending Enrollment Continue: The issuer requires additional processing before reaching a final state (status:
Pending Enrollment Continue). This step may ultimately result in authentication or a challenge.
Quick Reference: Decision Flow
Follow this decision logic based on the status returned by the API:
After Step 2 (Initiate Enrollment):
AuthenticatedorAttempt: Proceed to Step 4: Create the Payment.Pending Challenge: Redirect the customer using eitherredirect_html_templateoracs_redirect_form. After the challenge completes, proceed to Step 3B: Validate Authentication, then Step 4: Create the Payment.Pending Enrollment Continue: Proceed to Step 3C: Continue Enrollment.
Implementation Steps
Step 1: Obtain Access Token and Tokenize Card
- Request an access token using your API credentials.
- Tokenize the card information using the token endpoint.
Step 2: Initiate Enrollment
Call the 3DS - Init Authentication endpoint. Include the extra_fields object with billing address, shipping address, browser details, and customer information to support accurate risk scoring.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/enrolments-initial \
--header 'authorization: Bearer ' \
--header 'content-type: application/json' \
--data '{
"currency": "CLP",
"md": "NmQyZTQzODAtZDhhMy00Y2NiLTkxMzgtYzI4OTE4MjgxOGE0",
"term_url": "123",
"amount": 1,
"payment_method": {
"expiration_month": "05",
"expiration_year": "25",
"security_code": "282",
"number_token": "4292b573ea94b257dcb132afe242b4a15c9866d16e2d4d64d8e571c877af0540c3946b8bddaf37c2c75a1810863fc6b0fe0e841ebbc752c1d23ccfb5fdaac3d1"
},
"description": "TEST",
"operation": "CREDIT",
"extra_fields": {
"billing_address": {
"street": "Av. Brasil",
"number": "1000",
"complement": "Sala 1",
"district": "São Geraldo",
"city": "Porto Alegre",
"state": "RS",
"country": "BR",
"postal_code": "90230060",
"reference": "Near the hospital"
},
"shipping_address": {
"street": "Av. Brasil",
"number": "1000",
"complement": "Sala 1",
"district": "São Geraldo",
"city": "Porto Alegre",
"state": "RS",
"country": "BR",
"postal_code": "90230060",
"reference": "Near the hospital"
}
}
}'Response example (Pending Challenge):
{
"transaction_id": "84c05897-fbf1-4a91-90e8-d292a0fda1c8",
"status": "Pending Challenge",
"protocol": "3DS2.3.1",
"redirect_html_template": "<html>...</html>",
"acs_redirect_form": {
"action_url": "https://3ds-acs.test.modirum.com/mdpayacs/creq;token=368800071.1773147207.lksz3Q5MLGPuP5RsNmoU_8831PDCBLY_ABFB5xq0wtc",
"method": "POST",
"creq": "ewogICAgImFjc1RyYW5zSUQiOiAiNjVhMWUxN2MtZWVmYS00NGU1LTgyMDEtMDI4MjM5ZTVmOTA3IiwKICAgICJjaGFsbGVuZ2VXaW5kb3dTaXplIjogIjAzIiwKICAgICJtZXNzYWdlVHlwZSI6ICJDUmVxIiwKICAgICJtZXNzYWdlVmVyc2lvbiI6ICIyLjMuMSIsCiAgICAidGhyZWVEU1NlcnZlclRyYW5zSUQiOiAiZjI0ZmZhMWItMWY5MC01ZjMxLTgwMDAtMDAwMDAyYmY4Yjc3Igp9",
"threeDSSessionData": "NmQyZTQzODAtZDhhMy00Y2NiLTkxMzgtYzI4OTE4MjgxOGE0"
}
}
Step 3: Check Status and Follow the Appropriate Scenario
Status: Authenticated or Attempt
Extract the authentication data (xid, eci, cavv, ds_trans_id) and proceed to Step 4: Create the Payment.
Status: Pending Challenge
Redirect the customer to their bank for authentication. Select one of the following redirection methods:
Option A: HTML Template
Extract and render the redirect_html_template directly in your application. The template contains a self-submitting form that automatically redirects the customer to their bank’s authentication page.
Example — rendering the HTML template on the client side:
<!-- In your frontend application -->
<div id="challenge-container"></div>
<script>
// Receive the redirect_html_template from your backend
const redirectHtmlTemplate = response.redirect_html_template;
// Inject the HTML into your page
document.getElementById('challenge-container').innerHTML = redirectHtmlTemplate;
// The template contains a form that will automatically submit and redirect
// the customer to their bank's authentication page
</script>Example — rendering the HTML template on the server side:
// Node.js/Express example
app.post('/initiate-3ds', async (req, res) => {
const enrollmentResponse = await fetch('https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/enrolments-initial', {
// ... request configuration
});
const data = await enrollmentResponse.json();
if (data.status === 'Pending Challenge') {
// Send the HTML template directly to the browser
res.send(data.redirect_html_template);
}
});Option B: ACS Direct Form
Use the acs_redirect_form object to perform a manual POST request from the customer’s browser. This method is preferred because it avoids third-party scripts and allows you to display a custom loading UI during the redirect.
Required POST details:
- URL: Use the
action_urlvalue from the response. - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body: Include
creqandthreeDSSessionData.
Example — manual POST redirection:
<div id="loader">Redirecting to secure bank authentication...</div>
<form id="acs-direct-form" method="POST" action="https://3ds-acs.test.modirum.com/mdpayacs/creq;token=368800071.1773147207.lksz3Q5MLGPuP5RsNmoU_8831PDCBLY_ABFB5xq0wtc">
<input type="hidden" name="creq" value="ewogICAgImFjc1RyYW5zSUQiOiAiNjVhMWUxN2MtZWVmYS00NGU1LTgyMDEtMDI4MjM5ZTVmOTA3IiwKICAgICJjaGFsbGVuZ2VXaW5kb3dTaXplIjogIjAzIiwKICAgICJtZXNzYWdlVHlwZSI6ICJDUmVxIiwKICAgICJtZXNzYWdlVmVyc2lvbiI6ICIyLjMuMSIsCiAgICAidGhyZWVEU1NlcnZlclRyYW5zSUQiOiAiZjI0ZmZhMWItMWY5MC01ZjMxLTgwMDAtMDAwMDAyYmY4Yjc3Igp9" />
<input type="hidden" name="threeDSSessionData" value="NmQyZTQzODAtZDhhMy00Y2NiLTkxMzgtYzI4OTE4MjgxOGE0" />
</form>
<script>
// Programmatically submit the form
document.getElementById('acs-direct-form').submit();
</script>
Status: Pending Enrollment Continue
Proceed to Step 3C: Continue Enrollment before handling any subsequent status.
Step 3B: Validate Authentication
After the customer completes the challenge and the browser redirects back to your site, capture the CRES token from the callback and call the 3DS - Validate Authentication endpoint. Pass the token along with the transaction_id and xid from the enrollment response.
Request example:
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/validations \
--header 'authorization: Bearer <your-token>' \
--header 'content-type: application/json' \
--data '{
"transaction_id": "502040201060404060506040",
"xid": "VDdnR0kyU1g4ZXlxMkhWTlp0VnA=",
"token": "<cres-token-from-challenge-callback>"
}'Step 3C: Continue Enrollment
If the initial enrollment returns Pending Enrollment Continue, call the 3DS - Continue Enrollment endpoint with the transaction_id from Step 2. The response follows the same status logic as the initial enrollment and may return Pending Challenge or Authenticated.
If the response returns Pending Challenge, redirect the customer using Option A or Option B, then call Step 3B: Validate Authentication.
Response example (Pending Challenge status):
{
"transaction_id": "84c05897-fbf1-4a91-90e8-d292a0fda1c8",
"status": "Pending Challenge",
"protocol": "3DS2.3.1",
"acs_redirect_form": {
"action_url": "https://3ds-acs.test.modirum.com/mdpayacs/creq;token=368800071.1773147207.lksz3Q5MLGPuP5RsNmoU_8831PDCBLY_ABFB5xq0wtc",
"method": "POST",
"creq": "ewogICAgImFjc1RyYW5zSUQiOiAiNjVhMWUxN2MtZWVmYS00NGU1LTgyMDEtMDI4MjM5ZTVmOTA3IiwKICAgICJjaGFsbGVuZ2VXaW5kb3dTaXplIjogIjAzIiwKICAgICJtZXNzYWdlVHlwZSI6ICJDUmVxIiwKICAgICJtZXNzYWdlVmVyc2lvbiI6ICIyLjMuMSIsCiAgICAidGhyZWVEU1NlcnZlclRyYW5zSUQiOiAiZjI0ZmZhMWItMWY5MC01ZjMxLTgwMDAtMDAwMDAyYmY4Yjc3Igp9",
"threeDSSessionData": "NmQyZTQzODAtZDhhMy00Y2NiLTkxMzgtYzI4OTE4MjgxOGE0"
}
}
Step 4: Create the Payment
Once authentication completes (Authenticated or Attempt), call the Create - Authorize endpoint. Include the authentication data (xid, eci, cavv, ds_trans_id) in the payment object.
Country-specific requirements: Some markets may require additional mandatory fields. In Uruguay you must include a
ratesarray with theivakey. Sendregional_regulation_codeonly when the transaction qualifies for a regional regulation or tax benefit. Each entry takes acode(17934or19210) and an optionalinvoiceof up to 9 alphanumeric characters. When you omit theinvoice, Getnet derives it from yourorder_id. Review the Taxes and Regulations reference for more information.
Request example:
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments \
--header 'authorization: Bearer '\
--header 'content-type: application/json' \
--header 'x-seller-id: 54f88e68-7764-4e87-8830-756b1e2c02f8' \
--data '{
"order_id": "123order",
"data": {
"amount": 118708,
"currency": "CLP",
"payment": {
"payment_method": "CREDIT_AUTHORIZATION",
"xid": "VDdnR0kyU1g4ZXlxMkhWTlp0VnA=",
"eci": "24",
"ds_trans_id": "f7e5f76e-6388-43e6-b8cd-49b251a1f89c",
"card": { ... }
}
}
}'Europe Integration
The 3DS flow for the santander tenant with country: ES follows the same lifecycle as the generic flow, but with specific behaviors at each stage. This section documents the complete linear flow.
Key Identifiers
| Field | Value |
|---|---|
| Tenant | santander |
| Country | ES |
| Currency | EUR |
| 3DS Protocol | 2.1.0 |
| ACS Provider | Redsys (sis-d.redsys.es) |
Required Headers
All requests in the Spain flow require the following additional headers:
| Header | Value |
|---|---|
x-seller-id | Your seller UUID |
tenant | santander |
country | ES |
x-operation-type | card |
Step 1: Initiate Enrollment
Call POST /v2/enrolments-initial with the Spain-specific headers. Include the extra_fields object with customer, billing, shipping, and browser details.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/enrolments-initial \
--header 'accept: application/json' \
--header 'authorization: Bearer <your-token>' \
--header 'x-seller-id: <your-seller-id>' \
--header 'tenant: santander' \
--header 'country: ES' \
--header 'content-type: application/json' \
--header 'x-operation-type: card' \
--data '{
"currency": "EUR",
"amount": 400,
"term_url": "https://your-domain.com/3ds/callback",
"payment_method": {
"number": "4548814479727229",
"security_code": "123",
"expiration_month": "12",
"expiration_year": "49",
"payment_method": "CREDIT",
"credentials_on_file_type": "ONE_CLICK"
},
"description": "3ds unified",
"extra_fields": {
"customer": {
"email": "carmen.lopez@ejemplo.es",
"document_number": "12345678Z",
"document_type": "dni",
"name": "Sra. Carmen López",
"phone_number": "34612345678"
},
"billing_address": {
"street": "Calle Gran Vía",
"number": "28",
"complement": "Piso 3, Puerta A",
"district": "Centro",
"city": "Madrid",
"state": "Madrid",
"country": "ES",
"postal_code": "28013",
"reference": "Near Callao metro station"
},
"shipping_address": {
"street": "Calle Gran Vía",
"number": "28",
"complement": "Piso 3, Puerta A",
"district": "Centro",
"city": "Madrid",
"state": "Madrid",
"country": "ES",
"postal_code": "28013",
"reference": "Near Callao metro station"
},
"browser_details": {
"ip": "1.1.1.1",
"accept_header": "application/json,application/x-www-form-urlencoded",
"java_enabled": "false",
"java_script_enabled": "true",
"language": "es",
"color_depth": "24",
"screen_height": "600",
"screen_width": "800",
"time_zone": "52",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
}'Response example (Attempt):
{
"transaction_id": "526618589740",
"protocol": "2.1.0",
"status": "Attempt",
"eci": 0,
"acs_redirect_form": {
"method": "POST",
"creq": "11cf1933-8798-4280-bd92-e8120fe1944e"
}
}Important —
Attemptstatus in Spain: Always proceed to Step 2 (Continue Enrollment) when you receiveAttempt. Do not treat it as completed authentication. The Continue step may reveal aPending ChallengeorAuthenticatedstate. Store thetransaction_id; you need it for all subsequent steps.The
acs_redirect_form.creqvalue in this response is a server transaction reference used internally for flow continuation. Do not use it to redirect the customer — the actual ACS redirect data is returned in the Continue Enrollment response.
The response may also return Pending Enrollment Continue or Authenticated directly.
Step 2: Continue Enrollment
Send the transaction_id from Step 1 to POST /v2/enrolments-continue. Include the same Spain-specific headers. The response follows the same status logic as the generic flow and may return Pending Challenge or Authenticated.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/enrolments-continue \
--header 'accept: application/json' \
--header 'authorization: Bearer <your-token>' \
--header 'x-seller-id: <your-seller-id>' \
--header 'tenant: santander' \
--header 'country: ES' \
--header 'content-type: application/json' \
--data '{
"transaction_id": "526618589740"
}'Response example (Pending Challenge):
{
"status": "Pending Challenge",
"redirect_html_template": "<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">...</html>",
"eci": 0,
"acs_redirect_form": {
"action_url": "https://sis-d.redsys.es/sis-simulador-web/authenticationRequest.jsp",
"method": "POST",
"creq": "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjExY2YxOTMzLTg3OTgtNDI4MC1iZDkyLWU4MTIwZmUxOTQ0ZSIsImFjc1RyYW5zSUQiOiI1Zjg1YjVmZi04Y2Q5LTQwOWQtOWZlOS1iNjMwZDllMzYwMjYiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjA1In0"
}
}Redirect the customer to the ACS using either method:
Option A: HTML Template — Inject the redirect_html_template into your page. The template is a self-submitting form that redirects the customer to the Redsys challenge page automatically.
Option B: ACS Direct Form — Build a POST form using the acs_redirect_form data. The form requires only the creq field — do not include threeDSSessionData.
<div id="loader">Redirecting to Redsys secure authentication...</div>
<form id="acs-direct-form" method="POST" action="https://sis-d.redsys.es/sis-simulador-web/authenticationRequest.jsp" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="creq" value="eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjExY2YxOTMzLTg3OTgtNDI4MC1iZDkyLWU4MTIwZmUxOTQ0ZSIsImFjc1RyYW5zSUQiOiI1Zjg1YjVmZi04Y2Q5LTQwOWQtOWZlOS1iNjMwZDllMzYwMjYiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjA1In0" />
</form>
<script>
document.getElementById('acs-direct-form').submit();
</script>Key difference from the generic flow: The ACS form requires only
creq. The generic flow requires bothcreqandthreeDSSessionData.
Step 3: Validate Authentication
After the customer completes the challenge, the ACS redirects back to your term_url with a CRES token. Capture this token and call POST /v2/validations. Pass the CRES in the token field.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/security-gwproxy/v2/validations \
--header 'accept: application/json' \
--header 'authorization: Bearer <your-token>' \
--header 'x-seller-id: <your-seller-id>' \
--header 'tenant: santander' \
--header 'country: ES' \
--header 'content-type: application/json' \
--header 'x-operation-type: card' \
--data '{
"token": "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImU5MGVhYzlmLWM2OWYtNDAyNS05MzE2LTQ4ZGI5YzcwNzY0MyIsImFjc1RyYW5zSUQiOiJlODY0NzNlYS1iMGRmLTRkNzktOTdmZi0xN2E1NmY1YWM1MDAiLCJtZXNzYWdlVHlwZSI6IkNSZXMiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidHJhbnNTdGF0dXMiOiJZIn0="
}'Response example (Authenticated):
{
"tx_id": "e86473ea-b0df-4d79-97ff-17a56f5ac500",
"status": "Authenticated",
"ds_trans_id": "e90eac9f-c69f-4025-9316-48db9c707643"
}The validation response returns tx_id, status, and ds_trans_id. It does not include all fields present in the generic response (such as xid or cavv), but the status values follow the same convention.
Step 4: Create the Payment
Once the 3DS flow reaches Authenticated, call POST /v2/payments to charge the card.
Spain-specific requirements:
- Set
order_idto thetransaction_idreturned by the 3DS enrollment process — not a custom order ID. - Include the
cresfield in thepaymentobject. For ES transactions, onlycresis required for 3DS authorization — do not includexid,cavv, oreci.
curl --request POST \
--url https://api-sbx.globalgetnet.com/dpm/payments-gwproxy/v2/payments \
--header 'content-type: application/json' \
--header 'authorization: Bearer <your-token>' \
--header 'x-seller-id: <your-seller-id>' \
--header 'country: ES' \
--header 'tenant: santander' \
--data '{
"idempotency_key": "91d5f349-8256-4929-a468-7a2c97e68978",
"request_id": "cf779372-082f-4d13-ad74-35ad0b93d9c5",
"order_id": "526618589740",
"data": {
"amount": 400,
"currency": "EUR",
"customer_id": "913f3f9d-7060-4639-af6d-331b658668d4",
"payment": {
"payment_id": "6456ef10-55ce-415f-aa82-39336a5d572d",
"payment_method": "CREDIT",
"save_card_data": false,
"transaction_type": "FULL",
"number_installments": 1,
"dynamic_mcc": "1234",
"credentials_on_file_type": "ONE_CLICK",
"cres": "<cres-token-from-redsys-callback>",
"card": {
"number": "4548810000000003",
"expiration_month": "12",
"expiration_year": "49",
"cardholder_name": "Sra. Carmen López",
"security_code": "123"
}
},
"additional_data": {
"order": {
"items": [
{
"name": "Producto Electrónico",
"quantity": 1,
"sku": "SKU-ES-001",
"price": 400.00
}
]
},
"customer": {
"email": "carmen.lopez@ejemplo.es",
"document_number": "12345678Z",
"document_type": "dni",
"name": "Sra. Carmen López",
"phone_number": "34612345678",
"billing_address": {
"street": "Calle Gran Vía",
"number": "28",
"complement": "Piso 3, Puerta A",
"district": "Centro",
"city": "Madrid",
"state": "Madrid",
"country": "ES",
"postal_code": "28013",
"reference": "Near Callao metro station"
},
"shippings": {
"address": {
"street": "Calle Gran Vía",
"number": "28",
"complement": "Piso 3, Puerta A",
"district": "Centro",
"city": "Madrid",
"state": "Madrid",
"country": "ES",
"postal_code": "28013",
"reference": "Near Callao metro station"
},
"name": "Sra. Carmen López",
"phone_number": "34612345678"
}
}
}
}
}'