Accept recurring payments with 3DS

For the security of your merchant, Kushki’s fraud prevention team might ask you to activate 3DS validation when saving a card for receiving future payments.

By having the 3DS validation service active, your customers will be asked to complete an extra verification step (hereinafter challenge) with the card issuer to complete certain transactions. This challenge usually consists of an OTP sent by the bank to your customer’s e-mail address or telephone number.

How does 3DS validation work?

Once the user completes the form and clicks on the pay button, Kushki will verify if 3DS validation is required for the transaction. Should such validation be required, your customer will be shown a challenge whose experience may vary depending on the brand and the issuing bank. When he/she completes the challenge, he/she will be able to finish the transaction.

The 3DS authentication flow with Kushki is as follows:

3DS Cargos recurrentes

3DS is available on:

  • Kushki.js
  • Smartlinks (It only applies for scheduled payments)

3DS supported brands

Marcas de tarjetas soportadas Perú - Débito

1. Set up your front end

Set up your front end according to your integration.


Follow our instructions for Kushki.js described in our guide to accepting recurring payments.

Now, before sending the data to the endpoint in your back end, we must perform the 3DS validation with the issuer.

When 3DS is enabled, the response obtained from the requestSubscriptionToken() method will be as shown below:

"token": "oaACBE1012310zYTjE239227yqFRA8r7",
"secureService": "3dsecure",
"secureId": "e356d68d-3f31-4134-a9a7-8cba46b3cdac",
"security": {
"acsURL": "\u00d2aa20412b0063aca652facd9g\u0034transactionId\u003dQhcf3XOjdZmjve336Vee2gb5rof1",
"authenticationTransactionId": "1d8cf7jg5Bfn8Nj73mn7",
"paReq": "eNpVUtluwjAQfPdXoH5A7DghtGixxFUViRt6iDfXGGJCDpykQL++doDSvu3sjtYzs4ZlqKXsLaQotWQwknnOt7Km1q2HyeIx6EW7w2dn09NjFXnxxn1gMG3P5YHBl9S5ShPmOsShgG8QmRVahDwpGHBx6AzGzKdXoH5A7DghtGixxpVUtluwjAQfPdXoH5A7DghtGixs4ZlqKXsLaQot0u4KqLQKRlUugzC4gP+AYQlHrPwqLImhgfj0cnKvMwUhnfprkj0hiwnSPAxn1gMG3P5YHBl9S5ShPmOsShOqLqJ7x73Gx2vVbgC0DwZoXklFCKXFpo0bcpu83qWht0u4KqLQKRlUugzC4gP+AYQlHrpfUGenfxtGEOl1jIRN0c3hECesjSRhmNC+62Nh7vy7otNVxQmtdkm3Ew/Jrv1Kp0X4elF8Pb6p/n2KH/k0skaqcyeVHfdaulqgoP20X4elF8Pb6p/n2KH/k0sv8\u003d",
"specificationVersion": "1.0.2",
"authRequired": true

These variables are described below:

authRequiredBooleanThis field indicates whether 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.
authenticationTransactionIdStringTransaction ID verified from brands.
paReqStringMeans 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 of testing in UAT environment, sandbox must be sent.

Once you receive the Token response with the above structure, you must send the security object to Kushki through the requestValidate3DS method:

var callback = function(response) {
} else {
console.error('Error: ',response.error, 'Code: ', response.code, 'Message: ',response.message);
secureId: "5e44449e-869b-4fed-bbca-e1bfa5af53c3",
security: {
acsURL: "\u00d2aa20412b0063aca652facd9g\u0034transactionId\u003dQhcf3XOjdZmjve336Vee2gb5rof1",
authenticationTransactionId: "1d8cf7jg5Bfn8Nj73mn7",
paReq: "eNpVUtluwjAQfPdXoH5A7DghtGixxFUViRt6iDfXGGJCDpykQL++doDSvu3sjtYzs4ZlqKXsLaQotWQwknnOt7Km1q2HyeIx6EW7w2dn09NjFXnxxn1gMG3P5YHBl9S5ShPmOsShgG8QmRVahDwpGHBx6AzGzKdXoH5A7DghtGixxpVUtluwjAQfPdXoH5A7DghtGixs4ZlqKXsLaQot0u4KqLQKRlUugzC4gP+AYQlHrPwqLImhgfj0cnKvMwUhnfprkj0hiwnSPAxn1gMG3P5YHBl9S5ShPmOsShOqLqJ7x73Gx2vVbgC0DwZoXklFCKXFpo0bcpu83qWht0u4KqLQKRlUugzC4gP+AYQlHrpfUGenfxtGEOl1jIRN0c3hECesjSRhmNC+62Nh7vy7otNVxQmtdkm3Ew/Jrv1Kp0X4elF8Pb6p/n2KH/k0skaqcyeVHfdaulqgoP20X4elF8Pb6p/n2KH/k0sv8\u003d",
specificationVersion: "1.0.2",
authRequired: true
}, callback);

If the value of the authRequired variable is set to true, the 3DS validation modal will be presented and your customer will then receive the value to enter by e-mail or text message.

If the value of the authRequired variable is set to false, the 3DS validation modal will not be presented.

The only response you will receive in the callback function will be:


If the transaction is declined for the authentication, its result will be included as part of the response of the charge with 322 and any of the subcodes specified in the Error codes guide.

2. Set up your back end

3. Test your integration

There are test cards that you can use in test mode to make sure your integration is ready. Use them with any CVV, 1234 as OTP code and future expiration date.

  • Transaction approved with 3DS authentication required: 4456528080389860
  • Transaction rejected with 3DS authentication required: 4456523340069956
  • Transaction approved without 3DS validation: 4456540000000064
  • Transaction rejected without 3DS authentication: 4456541249811088

3. Prepare your certification

Follow the guidelines described in our guide to accepting recurring card payments.