1. 3DS Authentication
Kushki Docs
English
  • Español
  • English
  • Home
  • Quick Start
    • Frequently Asked Questions
    • Moving to Production
    • Policy for Important API Changes
    • Test Data
    • Error Codes
    • Latest Features
  • Payment Glossary
    • Payments Glossary
  • One-time card payments (Online)
    • Supported card brands
    • Functionalities by business model
    • How do third party commissions work?
    • Integration guide Third Party Commissions
    • Network Tokens
    • One-step Payments
      • How do Card Payments Work?
      • Accept a Card Payment
      • Direct charge (without token)
      • Accept One-Time Payments with OTP
      • OTP Authentication Error Codes
      • Error codes for single card payments
    • Two-steps Payments
      • How do single payments with authorization and capture work?
      • Receive payments with authorization and capture
    • Refunds
      • Returns, cancellations, and refunds
    • 3DS Authentication
      • Introduction to 3DS
      • 3DS API integration
      • 3DS integration with kushki.js library
      • 3DS API integration plus kushki.js library
      • 3DS Error Codes
    • Apple Pay Payments
      • Apple Pay Configuration
      • Apple Pay Sandbox testing
  • Recurring Card Payments (Online)
    • Functionalities by business model
    • External subscriptions to Kushki
    • Authenticate your subscriptions with 3DS
    • Accept one-click payments with 3DS
    • Error codes in recurring charges
    • Apple Pay for Subscriptions
    • Scheduled payments
      • How do Credit or Debit Card Payment Recurring Charges Work?
      • Create a recurring charge
      • Manage your Scheduled Charges
    • OneClick Payments
      • Accepting One-Click Payments
      • How do OneClick payments with authorization and capture work?
      • Receive one-click payments with authorization and capture
  • Card-present payments
    • Card present payments
    • Accept card present payments
    • Test data
    • Webhooks for card present
    • Cloud Terminal API
      • Cloud terminal API overview
      • Take payments
      • Cancel a payment request
      • Check the status of a payment request
      • How to print a customized ticket?
    • App-to-app
      • App-to-app overview
      • Take payments
    • Terminal SDK
      • Terminal SDK Introduction
      • Take payments
    • Raw card-present API
      • Raw card-present API overview
      • Cryptographic key exchange
      • Sample script to encrypt information
      • Take Payments
      • Frequently Asked Questions
      • Error codes for card-present transactions
    • Transactions
      • Transactions
      • Cancel payments
    • Kushki One
      • First Steps
      • Autenticación y Cifrado de Requests
      • Accept payments with Kushki One
      • Amount Format
      • Async services and webhooks
      • Printing on SmartPOS terminal
      • Unified Error Catalog — Kushki ONE Connect
    • Kushki One Payment App
      • Overview
      • Process a payment
      • Split payment on the terminal
      • Refunds and PreAuth & Capture
      • Review Your Transactions
      • Terminal Setup
  • Wire Transfers
    • How do Payments by Wire Transfers Work?
    • Banks and transaction details for bank transfer payments
    • Receive Wire Transfers
    • Check the Status of a Transaction
  • Money Disbursement
    • Wire Transfer
      • How Does a Payment Distribution by Wire Transfer Work?
      • Payment Distribution to Bank Accounts
      • Error codes for transfer dispersions
  • Payment Links
    • Smartlinks
  • Plugins
    • Shopify
      • Shopify
      • Plugin Operation
    • VTEX
      • VTEX Integration Guide
  • Payment forms and buttons
    • Kajita
      • How Does it Work?
      • Payment Kajitas
    • Payment Button
      • Overview
      • Generate a payment button
  • Branch Offices Management
    • How to Onboard Submerchants via API
  • Notifications
    • Webhooks
    • Good Practices
    • Check your Webhooks
    • One-time Payments Webhooks
      • Webhook for One-Time Payments made with a card
      • Webhook for One-Time Payments by Wire Transfer
      • Webhook for One-Time Payments in Cash
    • Recurring Payments Webhooks
      • Webhook for Recurring Payments Made with Card
    • Payment Distribution Webhooks
      • Webhook for payment disbursement through wire transfer
    • Payment button Webhooks
      • Webhooks with Payment Button
    • Smartlinks Webhooks
      • Webhooks with Smartlinks
    • Refunds Webhooks
      • Webhook for Voids and Refunds
      • Chargeback Webhooks
HomeMexico 🇲🇽
Ecuador 🇪🇨Chile 🇨🇱Colombia 🇨🇴Peru 🇵🇪
HomeMexico 🇲🇽
Ecuador 🇪🇨Chile 🇨🇱Colombia 🇨🇴Peru 🇵🇪
Status
Soporte / Support
English
  • Español
  • English
  1. 3DS Authentication

3DS API integration plus kushki.js library

Important
This integration option requires PCI Compliance
If you have an API integration (backend) and need to authenticate payments using 3D Secure, it is necessary to implement any of the Kushki.js or Kushki.js Hosted Fields frontend libraries to initialize the 3D Secure service and display the authentication modal, if applicable.

Available transactions#

Available ✅Not available ⛔️
3DS authentication for one-time card charges
3DS authentication for preauthorizations

Step 1. Get a Json Web Token (JWT)#

It is necessary to implement the requestSecureInit() method from Kushki.js or Kushki.js Hosted Fields to obtain a Json Web Token (JWT), which will be necessary when generating a token.

Kushki.js#

Use Kushki.js if you need more control over the "look & feel" or appearance of your payment form.

Import Kushki.js#

You can import the Kushki.js library via CDN or as an NPM package.
Option 1 - CDN#
Use the following script tag at the end of the <body> of your payment page.
Option 2 - NPM#
Install the package from npm.
Then import it into your code using the following code.

Set up Kushki object#

Add the following code to your application

Collect the user information and send it to your back-end#

First, add the form to your payment page with the required fields. You can design it in any way you like.
For example:
Check the complete reference in our Kushki.js reference

Consumes the requestSecureInit() method#

Use the requestSecureInit() method sending the card number, to get the jwt.
If the request has been successful, a json object with the jwt will be returned:
{
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTQ2NTY4ODYsImlhdCI6MTY1NDY0OTY4NiwiaXNzIjoiNWVhMzJmZDJmZjQ2NDU2OTY3YjUyNDliIiwianRpIjoiMDFhZTQyYWUtYzMyZS00YWRjLWFmOWQtZWVhMmFlNjRkMDkxIiwiT3JnVW5pdElkIjoiNWVhMzJmZDJhZDA3ZDIxYTM2OTc4OGFlIiwiUmVmZXJlbmNlSWQiOiI3ZjY1NzM5NS0yMDIwLTQ1ZjEtOTY4Mi05MzJiNTU5YWYzMWIifQ.JUkk70Kg4KlUYW7eIvsW8LoDhxJeG8P00VrJH9oQipc"
}
Otherwise, it will give you the following error response:
{ 
  "mensaje" : "mensaje de error" , 
  "código" : "código de error" ,
  "error" : "mensaje de error" 
}

Kushki.js Hosted Fields#

With Hosted Fields, included in Kushki.js, you can securely collect customer payment information through fields stored on Kushki infrastructure. Returns a token which allows the payment flow to continue from the back-end.

Import Kushki.js Hosted Fields into your app#

Option 1 - CDN#
Import the Kushki.js Hosted Fields library into your application using a <script> tag inside the <body> tag. Once imported, you will be able to access the resources described below to create a payment flow with Kushki.
It is necessary to import the kushki.min.js library (which comes with the necessary code to store your merchant's credentials) and the antifraud.min.js library (which provides the necessary tools to perform security authentications).
Option 2 - NPM#
Install the Kushki.js Hosted Fields library as an npm package inside your application with the following code:
Option 3 - YARN#
Install the Kushki.js Hosted Fields library as a yarn package inside your application with the following code:

Create an instance of KushkiOptions#

To use the Kushki.js Hosted Fields library, it is necessary to create an instance of KushkiOptions which allows you to set the public key of the work environment (test or production) through the init() method.
Note: When you are ready to accept real payments, you need to replace the test key with the production key.
Add the following code to your application:
Check the reference for more information about the KushkiOptions instance.

Initialize the 3D Secure authentication service#

Consume the requestSecureInit() method by sending the card number to get a JWT.
If the request has been successful, a json object with the jwt will be returned:
{
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTQ2NTY4ODYsImlhdCI6MTY1NDY0OTY4NiwiaXNzIjoiNWVhMzJmZDJmZjQ2NDU2OTY3YjUyNDliIiwianRpIjoiMDFhZTQyYWUtYzMyZS00YWRjLWFmOWQtZWVhMmFlNjRkMDkxIiwiT3JnVW5pdElkIjoiNWVhMzJmZDJhZDA3ZDIxYTM2OTc4OGFlIiwiUmVmZXJlbmNlSWQiOiI3ZjY1NzM5NS0yMDIwLTQ1ZjEtOTY4Mi05MzJiNTU5YWYzMWIifQ.JUkk70Kg4KlUYW7eIvsW8LoDhxJeG8P00VrJH9oQipc"
}
Otherwise, it will give you one of the following errors:
CODEMESSAGEEXAMPLEDESCRIPTION
E004JWT request error{ code: "E004", message: "Error en solicitud de JWT" }If the merchant has a rule for 3DS enabled and there was an error requesting the JWT. Please try again; if the error persists, contact Kushki support.
E018Invalid card length{ code: "E018", message: "Longitud de tarjeta inválida" }Please verify that the card length is correct.
E019Merchant does not have active 3DS service{ code: "E019", message: "Comercio no tiene activo 3DS" }The merchant does not have the 3DS service active. To activate it, check out the guide fraud detection tools.

Step 2. Request a card token#

Request a card token by sending the JWT obtained in the previous step.
{
  "card": {
    "name": "John Doe",
    "number": "4000000000000002",
    "expiryMonth": "01",
    "expiryYear": "28",
    "cvv": "123"
  },
  "totalAmount": 59,
  "currency": "MXN",
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTQ2NTg0ODgsImlhdCI6MTY1NDY1MTI4OCwiaXNzIjoiNWVhMzJmZDJmZjQ2NDU2OTY3YjUyNDliIiwianRpIjoiZjc4NzQzNTctMmY2Zi00OTExLTg3MDctZDBmN2RlYTZlNTk4IiwiT3JnVW5pdElkIjoiNWVhMzJmZDJhZDA3ZDIxYTM2OTc4OGFlIiwiUmVmZXJlbmNlSWQiOiIyZDdhOTA2OS04MjhjLTQxNDItYWYwNC1hMjZjNWI4YzQ3MjMifQ.5nmFrf3sOAxKNIcJTzc5i2GNY5ALABpu42YsrHIibio"
}
If the merchant has active 3D Secure rules and 3D Secure was successfully initialized as described in step 1, in addition to the token, other properties will be returned that will be required in the next step.
If a transaction requires 3D Secure authentication by the cardholder, the authRequired property within the security object will be returned as true (security.authRequired).
ParameterTypeDescription
authRequiredBooleanaThis field indicates whether or not a 3DS challenge is required.
acsURLURLRefers to the URL of the challenge page that the user must pass (Access Control System).
specificationVersionStringRefers to the applicable 3DS version.
authenticationTransactionIdStringVerified transaction ID from brands
paReqStringStands for Payer Authentication Request. It is a base64 encoded field containing your merchant and cardholder information that is sent to the issuer for authentication
Note: in case you are testing in a UAT environment, you must send sandbox.

Examples#

Response object with 3D Secure authentication required#

{
  "token": "g9m2XG100000uut73n085881SMOP3bP1",
  "secureService": "3dsecure",
  "secureId": "61efd064-b9df-4c0c-81fb-5b39a5d0cf9f",
  "security": {
    "acsURL": "https://merchantacsstag.cardinalcommerce.com/MerchantACSWeb/pareq.jsp?vaa=b&gold=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "authenticationTransactionId": "uvvZn0ND0ukTOJIfhfi0",
    "authRequired": true,
    "paReq": "eNpVUstuwjAQvPsrItRTD7HjhAjQYokWqQVUSksqKm5RYkiU5oFjE/j72iFAK/mws7Nr78wagkRwPl3zSAnO4I3XdbjnVhqPe+p43BZkOSUqC97ns12yS0mPwWryyQ8MjlzUaVkwxyY2BXyFSF8hoiQsJIMwOjzNlszzh9TxAXcQQc7FbMr6nksdAviCEBRhztlivXh8ScpaWitRxiqSpRXwWqYF4JZHEJWqkOLMfOIBvgIESvywRMpqhHHTNHam6iRLq3Bf1nZU5oANjwDfh1spE9Va8ymNWfy9pZvca4Lso4k38isg1XybJ3kYTMaATQWCOJScUUIp8cnAIu5IH1cP0eYRhLkZhj30hzbRsjqIoDIPTS6oPzTU34wWpITgRXRmA09zN4SAn6qy4LpG23uLtYb75M+vxuRIGjd9z3UpNS63uG1PtTXUJ07bn7Y+YdODux3ibt06+vcNfgHbNq5L",
    "specificationVersion": "2.2.0"
  }
}

Response object with 3D Secure authentication not required#

{
  "token": "URkTD3100000aSfrJk085881gtsxGts6",
  "secureService": "3dsecure",
  "secureId": "9903cc36-6e9c-42b0-bb76-34c9c4dbaff5",
  "security": {
    "acsURL": "",
    "authenticationTransactionId": "",
    "authRequired": false,
    "paReq": "",
    "specificationVersion": "2.2.0"
  }
}

Response object without 3D Secure#

{
  "token": "3c1518cf6f844e248880aad6187cf8d7"
}
Learn more about request a card token.

Step 3. Authenticate through 3D Secure.#

In case the security.authRequired property obtained in the previous step comes with the value of true, it will be necessary to perform authentication through 3D Secure. To perform 3D Secure authentication, you must call the requestValidate3DS method in Kushki.js or Kushki.js Hosted Fields, sending the response object from the previous step.

Kushki.js#

If the value of the authRequired property is equal to true, the 3DS validation modal will be displayed and your client will then receive the value to be entered via email or text message.
If the value of the authRequired property is equal to false, the modal will not be presented for 3DS validation.
The response you will receive in the callback function will be:
{
 "code":"3DS000",
 "message":"ok"
}
In case of error, the callback function's response will be something like:
{
 "message":"error-message",
 "code":"error-code",
 "error": "error-message"
}
You will receive the authentication response in the charge. If the authentication is declined, you will receive a K322 code and any of the other subcodes specified in the Error codes guide.

Kushki.js Hosted Fields#

Product in beta version 🔐

We are working on our beta version. Stay tuned for its official release! You can also contact your account manager for more information.
The requestValidate3DS() method receives as a parameter the object obtained in the response from the previous step.
import { init, IKushki } from "@kushki/js-sdk";
import { CardTokenResponse, requestValidate3DS, TokenResponse } from "@kushki/js-sdk/Antifraud";

const on3DSValidation = async () => {
  try {
    const kushkiInstance = await init({
      inTest: true,
      publicCredentialId: merchantId
    });

    const cardTokenResponse: CardTokenResponse = {
      secureId: "secure_id",
      secureService: "secure_service",
      security: {
        acsURL: "https://kushki.com",
        authenticationTransactionId: "transaction_id",
        authRequired: true,
        paReq: "jwt",
        specificationVersion: "2.0.1"
      },
      token: "token"
    };

    const response: TokenResponse = await requestValidate3DS(kushkiInstance, cardTokenResponse);

    console.log(response);
  } catch (error: any) {
    console.log(error)
  }
};
PROPERTYTYPEREQUIREDDESCRIPTION
kushkiInstanceIKushkiYESObject with public merchant id and work environment
secureInitRequestSecureInitRequestYESYou must define this object in order to request the initialization of 3DS.
If the 3D Secure authentication has been successful, the same token from step 2 will be returned with the corresponding validations to continue with the payment flow.
{
  "token": "3c1518cf6f844e248880aad6187cf8d7"
}
In case of an error during authentication, one of the following messages will be returned:
CODEMESSAGEEXAMPLEDESCRIPTION
E005Campos 3DS inválidos (Invalid 3DS fields){ code: "E005", message: "Campos 3DS inválidos" }If the merchant has a 3DS rule enabled and there was an error in the 3DS authentication, error code E005 will be returned. Please try again making sure to enter the data correctly for the 3DS validation.
E006Error en solicitud de validación de token (Token validation request error){ code: "E006", message: "Error en solicitud de validación de token" }If the merchant has a 3DS rule enabled and there was an error in the 3DS authentication, error code E005 will be returned. Please try again making sure to enter the data correctly for the 3DS validation.
Learn more about the requestValidate3DS() method.
The cardholder will have up to a maximum of 3 retries to complete 3DS authentication.

Step 4. Make a one-time payment or a recurring charge#

Continue with the payment flow by generating a one-time payment or a recurring charge with the token validated in the previous step.
{
  "token": "f5c64f7ac8ea42d5a58dcdc74de973dc",
  "amount": {
    "subtotalIva": 0,
    "subtotalIva0": 16.98,
    "ice": 0,
    "iva": 0,
    "currency": "MXN"
  },
  "metadata": {
    "Referencia": "987654"
  },
  "contactDetails": {
    "documentType": "CC",
    "documentNumber": "1234567890",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "phoneNumber": "+593912345678"
  },
  "orderDetails": {
    "siteDomain": "example.com",
    "shippingDetails": {
      "name": "John Doe",
      "phone": "+593912345678",
      "address1": "Eloy Alfaro 139 y Catalina Aldaz",
      "address2": "centro 123",
      "city": "Quito",
      "region": "Pichincha",
      "country": "Ecuador"
    },
    "billingDetails": {
      "name": "John Doe",
      "phone": "+593912345678",
      "address1": "Eloy Alfaro 139 y Catalina Aldaz",
      "address2": "centro 123",
      "city": "Quito",
      "region": "Pichincha",
      "country": "Ecuador"
    }
  },
  "productDetails": {
    "product": [
      {
        "id": "198952AB",
        "title": "eBook Digital Services",
        "price": 10000,
        "sku": "10101042",
        "quantity": 1
      },
      {
        "id": "198953AB",
        "title": "eBook Virtual Selling",
        "price": 6980,
        "sku": "004834GQ",
        "quantity": 1
      }
    ]
  },
  "fullResponse": "v2"
}
This is what a payment with 3DS authentication will look like:
3DS Overview

Test your integration#

We have test cards that you can use during the test mode to ensure that your integration is ready. You can use them with any CVV, 1234 as OTP code and future expiration date.
Transaction approved with 3DS authentication required::
4456528080389860
4456529267234200
4456529165328302
4456524869770255
4456523340069956
Transaction approved without 3DS validation:
4456540000000063
4456543371713314
4456541982068615
4456541249811088
To enable 3DS in test mode in your merchant, an additional configuration by Kushki is required.
Modificado en 2026-10-20 14:57:14
Anterior
3DS integration with kushki.js library
Siguiente
3DS Error Codes
Built with