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
- The client generates the
access_tokenin the backend via Access Token Generation. - The client calls
ZendrySDKThreeds.init_threeds()withtoken,amount, andpayment_form. - The client receives the SDK result, which contains the
operation_session_id. - After authentication finishes, the client must use the
operation_session_idto 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
| Parameter | Type | Description | Required |
|---|---|---|---|
token | string | Bearer Access Token generated via POST /auth/generate_token | Yes |
amount | integer | Payment amount in cents (e.g.: 1000 = R$ 10.00) | Yes |
payment_form | object | Card data and payment preferences | Yes |
payment_form.network_preference | string | Card brand. Examples: VISA, MASTERCARD, ELO, AMEX | Yes |
payment_form.account_type | string | Account type. Allowed values: CREDIT, DEBIT | Yes |
payment_form.pan | string | Card number, no spaces or dashes | Yes |
payment_form.expiry_month | string | Card expiration month, format MM (e.g.: 12) | Yes |
payment_form.expiry_year | string | Card expiration year, format YY (e.g.: 29) | Yes |
payment_form.card_holder_name | string | Cardholder name as printed on the card | Yes |
payment_form.installment_number | integer | Number of installments (e.g.: 1 for full payment) | Yes |
payment_form.issuer_installment | boolean | Indicates 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.
{
"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.
{
"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]"
}
}