Skip to main content

Run 3DS Authentication

The 3DS authentication step runs entirely in the browser through the ZendrySDKThreeds SDK. The SDK manages the full authentication lifecycle: creates the 3DS session, runs the authentication flow (with or without challenge) directly in the cardholder's browser, and returns the data needed to finalize the payment with 3DS.

Authentication Types

The 3DS flow can occur with challenge or without challenge/friction (frictionless). In the challenge flow, additional cardholder confirmation is required, such as validation via banking app or selfie, for example — this step is the issuer's responsibility. The frictionless flow authenticates the user without requiring a challenge, directly returning the authentication data.

The SDK manages both scenarios automatically, displaying the challenge iframe when needed or completing authentication transparently when the flow is frictionless.

Summary Flow

  1. The client generates the access_token in the backend via Access Token Generation.
  2. The client calls ZendrySDKThreeds.init_threeds() with token, amount, and payment_form.
  3. The client receives the SDK result, which contains the operation_session_id.
  4. After authentication finishes, the client must use the operation_session_id to make a request to 3DS Challenge Response and obtain the result to finalize the payment.

How to Use the SDK in the Browser

1. Load the SDK

 https://cdn.zendry.com/v1/zendry-sdk-threeds.min.js

2. Start authentication

<script>
const result = await ZendrySDKThreeds.init_threeds({
token: accessToken,
amount: 1000,
payment_form: {
network_preference: 'VISA',
account_type: 'CREDIT',
pan: '4970115000000228',
expiry_month: '12',
expiry_year: '29',
card_holder_name: 'JOHN DOE',
installment_number: 1,
issuer_installment: true
}
})

console.log(result)
</script>

init_threeds Parameters

ParameterTypeDescriptionRequired
tokenstringBearer Access Token generated via POST /auth/generate_tokenYes
amountintegerPayment amount in cents (e.g.: 1000 = R$ 10.00)Yes
payment_formobjectCard data and payment preferencesYes
payment_form.network_preferencestringCard brand. Examples: VISA, MASTERCARD, ELO, AMEXYes
payment_form.account_typestringAccount type. Allowed values: CREDIT, DEBITYes
payment_form.panstringCard number, no spaces or dashesYes
payment_form.expiry_monthstringCard expiration month, format MM (e.g.: 12)Yes
payment_form.expiry_yearstringCard expiration year, format YY (e.g.: 29)Yes
payment_form.card_holder_namestringCardholder name as printed on the cardYes
payment_form.installment_numberintegerNumber of installments (e.g.: 1 for full payment)Yes
payment_form.issuer_installmentbooleanIndicates whether installments are issuer (true) or merchant (false)Yes

3. Callbacks

You can track each authentication step through callbacks:

const result = await ZendrySDKThreeds.init_threeds({
token: accessToken,
amount: 1000,
payment_form: {
network_preference: 'VISA',
account_type: 'CREDIT',
pan: '4970115000000228',
expiry_month: '12',
expiry_year: '29',
card_holder_name: 'JOHN DOE',
installment_number: 1,
issuer_installment: true
},

onSessionCreated: function (session) {
console.log('3DS session created', session)
},

onAuthenticationStart: function (event) {
console.log('Authentication started', event)
},

onAuthenticationFinish: function (event) {
console.log('Provider finished', event)
},

onGetSessionFinish: function (session) {
console.log('Official result queried', session)
},

onSuccess: function (result) {
console.log('3DS approved', result.three_ds_data)
},

onFailure: function (result) {
console.log('3DS declined/not approved', result)
},

onError: function (error) {
console.error('Technical error in 3DS', error)
}
})

Return of each callback

onSessionCreated

{
"status": "SUCCESS",
"version": "V4",
"application_version": "6.43.10",
"server_date": "2026-05-15T00:50:03+00:00",
"ticket": "cb2af7b0afaa4507a1ffd1f5625e502f",
"answer": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"operation_url": "https://api.zendry.com/api-payment/V4/Charge/Public/Authenticate/Session/8f250597d1964683abb21a58241468c4",
"provider": 2
}
}

onAuthenticationStart

{
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"status": "STARTED"
}

onAuthenticationFinish

{
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"status": "FINISHED",
"partner_result": {
"status": "SUCCESS",
"flow": "CHALLENGE"
}
}

onGetSessionFinish

{
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"status": "SUCCESS",
"answer": {
"id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"xid": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"eci": "02",
"cavv": "kBMkIS6TvtjesABke//Be5hhJqAk",
"secure_version": "2.2.0",
"directory_server_transaction_id": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"three_ds_server_transaction_id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"trans_status": "SUCCESSFUL"
}
}

onSuccess

{
"success": true,
"status": "SUCCESS",
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"threeds_flow": "CHALLENGE",
"three_ds_data": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"xid": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"eci": "02",
"cavv": "kBMkIS6TvtjesABke//Be5hhJqAk",
"secure_version": "2.2.0",
"directory_server_transaction_id": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"three_ds_server_transaction_id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"trans_status": "SUCCESSFUL"
},
"session": {
"create_session": {
"status": "SUCCESS",
"version": "V4",
"application_version": "6.43.10",
"server_date": "2026-05-15T00:50:03+00:00",
"ticket": "cb2af7b0afaa4507a1ffd1f5625e502f",
"answer": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"operation_url": "https://api.zendry.com/api-payment/V4/Charge/Public/Authenticate/Session/8f250597d1964683abb21a58241468c4",
"provider": 2
}
},
"get_session": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"status": "SUCCESS",
"answer": {
"id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"xid": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"eci": "02",
"cavv": "kBMkIS6TvtjesABke//Be5hhJqAk",
"secure_version": "2.2.0",
"directory_server_transaction_id": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"three_ds_server_transaction_id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"trans_status": "SUCCESSFUL"
}
}
},
"partner_result": {
"status": "SUCCESS",
"flow": "CHALLENGE"
}
}

onFailure

{
"success": false,
"status": "REJECTED",
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"threeds_flow": "CHALLENGE",
"error": {
"code": "REJECTED",
"message": "Authentication rejected",
"detail": "Authentication was rejected by ACS"
},
"session": {
"create_session": {
"status": "SUCCESS",
"answer": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"operation_url": "https://api.zendry.com/api-payment/V4/Charge/Public/Authenticate/Session/8f250597d1964683abb21a58241468c4",
"provider": 2
}
},
"get_session": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"status": "REJECTED",
"answer": {
"trans_status": "REJECTED"
}
}
},
"partner_result": {
"status": "REJECTED"
}
}

onError

{
"message": "Failed to load script: vendor/kr-authenticate.umd.js",
"response": null
}

or:

{
"message": "web-service input data validation error",
"response": {
"status": "ERROR",
"version": "V4",
"application_version": "6.43.10",
"server_date": "2026-05-15T00:38:40+00:00",
"ticket": "5110c09d79b448d48807b67434a4c6d6",
"answer": {
"error_code": "INT_902",
"error_message": "web-service input data validation error",
"detailed_error_message": "Input value not defined [name=recurring.expiryDate]"
}
}
}

Final Promise return

If approved:

{
"success": true,
"status": "SUCCESS",
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"threeds_flow": "CHALLENGE",
"three_ds_data": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"xid": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"eci": "02",
"cavv": "kBMkIS6TvtjesABke//Be5hhJqAk",
"secure_version": "2.2.0",
"directory_server_transaction_id": "de25ed0c-b4c6-49ec-bd69-2f8478219068",
"three_ds_server_transaction_id": "0b47b037-5360-42e2-8b61-2d95605a53b7",
"trans_status": "SUCCESSFUL"
}
}

If not approved:

{
"success": false,
"status": "FAILED",
"provider": 2,
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"threeds_flow": "CHALLENGE",
"error": {
"code": "FAILED",
"message": "Authentication failed"
}
}

Success

After the SDK runs, the result is returned in an object containing the operation_session_id property, needed to query the 3DS authentication result.

Success Response
{
"status": "SUCCESS",
"version": "V4",
"application_version": "6.43.10",
"server_date": "2026-05-15T00:50:03+00:00",
"ticket": "cb2af7b0afaa4507a1ffd1f5625e502f",
"answer": {
"operation_session_id": "8f250597d1964683abb21a58241468c4",
"operation_url": "https://api.zendry.com.br/api-payment/V4/Charge/Public/Authentica",
"provider": 2
}
}

Errors

In case of authentication errors, the SDK returns an object with error details.

Error Response
{
"status": "ERROR",
"version": "V4",
"application_version": "6.43.10",
"server_date": "2026-05-15T00:38:40+00:00",
"ticket": "5110c09d79b448d48807b67434a4c6d6",
"answer": {
"error_code": "INT_902",
"error_message": "web-service input data validation error",
"detailed_error_message": "Input value not defined [name=recurring.expiryDate]"
}
}