Getnet DocsGetnet Docs

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_id and client_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_merchant object 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:

  1. Direct Authentication: The issuer authenticates the cardholder immediately (status: Authenticated or Attempt).
  2. 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.
  3. 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):


Implementation Steps

Step 1: Obtain Access Token and Tokenize Card

  1. Request an access token using your API credentials.
  2. 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_url value from the response.
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body: Include creq and threeDSSessionData.

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 rates array with the iva key. Send regional_regulation_code only when the transaction qualifies for a regional regulation or tax benefit. Each entry takes a code (17934 or 19210) and an optional invoice of up to 9 alphanumeric characters. When you omit the invoice, Getnet derives it from your order_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

FieldValue
Tenantsantander
CountryES
CurrencyEUR
3DS Protocol2.1.0
ACS ProviderRedsys (sis-d.redsys.es)

Required Headers

All requests in the Spain flow require the following additional headers:

HeaderValue
x-seller-idYour seller UUID
tenantsantander
countryES
x-operation-typecard

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 — Attempt status in Spain: Always proceed to Step 2 (Continue Enrollment) when you receive Attempt. Do not treat it as completed authentication. The Continue step may reveal a Pending Challenge or Authenticated state. Store the transaction_id; you need it for all subsequent steps.

The acs_redirect_form.creq value 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 both creq and threeDSSessionData.

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:

  1. Set order_id to the transaction_id returned by the 3DS enrollment process — not a custom order ID.
  2. Include the cres field in the payment object. For ES transactions, only cres is required for 3DS authorization — do not include xid, cavv, or eci.
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"
          }
        }
      }
    }
  }'

Next Steps