3D Secure
Client-Side Implementation
Generate a client token
Before you can initialize the JavaScript SDK, you will need to generate a client token. The client_token
is generated on your server and must be accessible from the JavaScript in your checkout page.
Specify a merchant account
If you would like to use a merchant account ID other than your default, specify the merchant_account_id
when generating the client token.
Using 3DS
Drop-in UI
To add our Drop-in UI to your checkout page, include the dropin
script:
- JavaScript
<!-- Load the Drop-in component -->
<script src="https://js.braintreegateway.com/web/dropin/1.40.2/js/dropin.min.js"></script>
To use 3DS, you will need to pass an object with relevant customer and transaction data into the threeDSecure
field of the requestPaymentMethod
options in order to minimize the need for issuing banks to present authentication challenges to customers. This object must contain the amount
field and should contain as many of the following fields as possible:
email
billingAddress
additionalInformation
As of Braintree Web Drop-in version 1.37.0, an option to submit additional device data to 3DS is available. Submitting this additional data may reduce the occurance of lookup failures or authentication challenges.
- JavaScript
var threeDSecureParameters = {
amount: '500.00',
email: 'test@example.com',
billingAddress: {
givenName: 'Jill', // ASCII-printable characters required, else will throw a validation error
surname: 'Doe', // ASCII-printable characters required, else will throw a validation error
phoneNumber: '8101234567',
streetAddress: '555 Smith St.',
extendedAddress: '#5',
locality: 'Oakland',
region: 'CA', // ISO-3166-2 code
postalCode: '12345',
countryCodeAlpha2: 'US'
},
collectDeviceData: true,
additionalInformation: {
workPhoneNumber: '8101234567',
shippingGivenName: 'Jill',
shippingSurname: 'Doe',
shippingPhone: '8101234567',
shippingAddress: {
streetAddress: '555 Smith St.',
extendedAddress: '#5',
locality: 'Oakland',
region: 'CA', // ISO-3166-2 code
postalCode: '12345',
countryCodeAlpha2: 'US'
}
},
};
Then, create the Drop-in and pass in the 3DS parameters accordingly.
- Callback
- Promise
braintree.dropin.create({
authorization: 'CLIENT_AUTHORIZATION',
container: '#dropin-container',
threeDSecure: true
}, function (err, dropinInstance) {
if (err) {
// Handle any errors that might've occurred when creating Drop-in
console.error(err);
return;
}
submitButton.addEventListener('click', function (e) {
e.preventDefault();
dropinInstance.requestPaymentMethod({
threeDSecure: threeDSecureParameters
}, function (err, payload) {
if (err) {
// Handle errors in requesting payment method
}
// Send payload.nonce to your server
// The 3D Secure Authentication ID can be found
// at payload.threeDSecureInfo.threeDSecureAuthenticationId
});
});
});
Hosted Fields
To use 3DS with Hosted Fields, include the client
, three-d-secure
, and hosted-fields
scripts:
- HTML
<!-- Load the client component. -->
https://js.braintreegateway.com/web/3.97.2/js/client.min.js
<!-- Load the 3D Secure component. -->
https://js.braintreegateway.com/web/3.97.2/js/three-d-secure.min.js
<!-- Load the Hosted Fields component. -->
https://js.braintreegateway.com/web/3.97.2/js/hosted-fields.min.js
Recommended Settings
To use 3DS2, you will need to pass an object with relevant customer and transaction data into the threeDSecure
field of the requestPaymentMethod
options in order to minimize the need for issuing banks to present authentication challenges to customers. This object must contain the following fields:
amount
nonce
bin
And should contain as many of the following fields as possible:
email
billingAddress
additionalInformation
As of Braintree version 3.94.0 an option to submit additional device settings to 3D Secure is available. Submitting this data may reduce lookup failures and/or authentication challenges for customers. Set the collectDeviceData
option to true
to enable collection of additional device data.
Handle Lookup Response
You will also need to implement the required callback onLookupComplete
, which will be invoked after receiving the ThreeDSecure lookup response, before initializing the challenge and completing the flow.
- JavaScript
var threeDSecureParameters = {
amount: '500.00',
nonce: NONCE_FROM_INTEGRATION, // Example: hostedFieldsTokenizationPayload.nonce
bin: BIN_FROM_INTEGRATION, // Example: hostedFieldsTokenizationPayload.details.bin
email: 'test@example.com',
collectDeviceData: true,
billingAddress: {
givenName: 'Jill', // ASCII-printable characters required, else will throw a validation error
surname: 'Doe', // ASCII-printable characters required, else will throw a validation error
phoneNumber: '8101234567',
streetAddress: '555 Smith St.',
extendedAddress: '#5',
locality: 'Oakland',
region: 'CA', // ISO-3166-2 code
postalCode: '12345',
countryCodeAlpha2: 'US'
},
additionalInformation: {
workPhoneNumber: '8101234567',
shippingGivenName: 'Jill',
shippingSurname: 'Doe',
shippingPhone: '8101234567',
shippingAddress: {
streetAddress: '555 Smith St.',
extendedAddress: '#5',
locality: 'Oakland',
region: 'CA', // ISO-3166-2 code
postalCode: '12345',
countryCodeAlpha2: 'US'
}
},
onLookupComplete: function (data, next) {
// use 'data' here, then call 'next()'
next();
}
};
Specify version: 2
in your options object when calling threeDSecure.create()
.
- Callback
- Promise
var threeDSecure;
braintree.client.create({
// Use the generated client token to instantiate the Braintree client.
authorization: 'CLIENT_TOKEN_FROM_SERVER'
}, function (clientErr, clientInstance) {
if (clientErr) {
// Handle error in client creation
return;
}
braintree.threeDSecure.create({
version: 2, // Will use 3DS2 whenever possible
client: clientInstance
}, function (threeDSecureErr, threeDSecureInstance) {
if (threeDSecureErr) {
// Handle error in 3D Secure component creation
return;
}
threeDSecure = threeDSecureInstance;
});
});
Once the 3D Secure client has been created, you can verify cards by passing the threeDSecureParameters
into verifyCard
. This call may challenge the cardholder to authenticate (if the card is enrolled in a 3D Secure program, such as Verified by Visa, and the cardholder's issuing bank decides to challenge).
- Callback
- Promise
threeDSecure.verifyCard(threeDSecureParameters, function (err, response) {
if (err) {
// Handle error
return;
}
// Send response.nonce to your server for use in your integration
// The 3D Secure Authentication ID can be found
// at response.threeDSecureInfo.threeDSecureAuthenticationId
});
Device Data
Submitting additional device data to 3D Secure may reduce rejections and/or the need for authentication challenges for customers. Include the following option (set to true
) with 3DS lookup parameters to enable collection of additional device data.
collectDeviceData
The following device attributes are sent to 3D Secure when this option is enabled:
- browser color depth
- browser Java enabled
- browser JavaScript enabled
- browser language
- browser screen height and width
- browser time zone
- device channel
Verify a vaulted credit card
First, on the server, generate and return a payment method nonce for the vaulted credit card.
Then, on the browser, you can use the same verifyCard
method just as before and pass it the newly-generated nonce.
Validation errors
Braintree will evaluate any fields passed against Cardinal's documentation. You will receive a validation error from Braintree if a field is incorrect.
Advanced client-side options
We expose additional information about the authentication request that you can use for more advanced UI flows or risk assessment. You should be aware that making such assessments may result in accepting the liability for fraudulent transactions.
These parameters pass through the client-side first and should not be trusted for your server-side risk assessment. They should be used for UI flow only.
- Callback
- Promise
threeDSecure.verifyCard({
amount: '500.00',
nonce: NONCE_FROM_INTEGRATION,
bin: BIN_FROM_INTEGRATION,
onLookupComplete: function (data, next) {
// use 'data' here, then call 'next()'
next();
}
}, function (err, response) {
var liabilityShifted = response.liabilityShifted; // true || false
var liabilityShiftPossible = response.liabilityShiftPossible; // true || false
});
liabilityShifted
indicates that 3D Secure worked and authentication succeeded. This will also be true if the issuing bank does not support 3D Secure, but the payment method does. In both cases, the liability for fraud has been shifted to the bank. You should go on creating a transaction using the new nonce.liabilityShiftPossible
indicates that the payment method was eligible for 3D Secure. IfliabilityShifted
isfalse
, then the user failed 3D Secure authentication. In this situation, the card brands recommend asking the user for another form of payment. However, if you have server-side risk assessment processes that allow for it, you can still use the new nonce to create a transaction. If you want to use a nonce that did not pass 3D Secure authentication, you need to set therequired
option tofalse
in your server integration.- If both of the above values are
false
then this card was ineligible for 3D Secure. You can continue to create the transaction with the new nonce. However, liability shift will not apply to this transaction. This case may be useful if you would like to ask the user for additional verification (AVS, etc).
Using 3D Secure with a CVV-only nonce
If you want to use a CVV-only nonce when creating a transaction with 3D Secure, you will need to pass a 3D Secure Authentication ID together with a CVV-only nonce when creating a transaction, creating a payment method, or creating a customer with a payment method
Using 3D Secure Data-Only
To use use the 3D Secure data-only protocol for a given cardbrand, add the dataOnlyRequested
boolean, and check for the resulting status in the onLookupComplete()
callback:
- Callback
- Promise
threeDSecure.verifyCard({
amount: '500.00',
nonce: NONCE_FROM_INTEGRATION,
bin: BIN_FROM_INTEGRATION,
dataOnlyRequested: true,
onLookupComplete: function (data, next) {
// use 'data' here, then call 'next()'
next();
}
}, function (err, response) {
var liabilityShifted = response.liabilityShifted; // true || false
var liabilityShiftPossible = response.liabilityShiftPossible; // true || false
});
Using 3D Secure with Google Pay
We support 3DS for Google Pay non-network tokenized cards.
Google Pay cards can be tokenized in one of two ways:
- A non-network tokenized card is a standard credit card. Access to the card's primary account number (PAN) makes 3DS verification possible.
- A network tokenized card is a generated virtual card with a device-specific account number (DPAN) that is used in place of the underlying source card. These cards cannot be used with 3DS.
Drop-in UI with Google Pay
If 3DS was requested, Google Pay cards that are non-network tokenized will automatically be processed for 3DS verification.
Custom UI
To process non-network tokenized Google Pay cards for 3DS verification, include a Google Pay nonce as the nonce
field on your threeDSecureParameters
. See the Google Pay configuration guide for how to generate a Google Pay nonce. Once you have generated a nonce, follow these instructions:
First, check if your Google Pay nonce is non-network tokenized.
- JavaScript
if (nonce.isNetworkTokenized === false) {
// eligible for 3DS Verification
}
Then, construct your threeDSecureParameters
with this nonce.
- JavaScript
var threeDSecureParameters = {
amount: '500.00',
nonce: GOOGLE_PAY_NONCE, // Use Google Pay nonce
email: 'test@example.com',
billingAddress: {
// see example above
},
additionalInformation: {
// see example above
},
onLookupComplete: function (data, next) {
next();
}
};
Using accountType for combo cards in Brazil
When processing Brazilian cards domestically, customers with combo cards should be given the opportunity to select the account type of their card. To do this, generate a UI for this selection and reflect that choice in the 3D Secure call, as well as the corresponding transaction, payment method or customer API call.
- Callback
- Promise
threeDSecure.verifyCard({
amount: '500.00',
nonce: NONCE_FROM_INTEGRATION,
bin: BIN_FROM_INTEGRATION,
accountType: 'credit',
onLookupComplete: function (data, next) {
// use 'data' here, then call 'next()'
next();
}
}, function (err, response) {
var liabilityShifted = response.liabilityShifted; // true || false
var liabilityShiftPossible = response.liabilityShiftPossible; // true || false
});
See also
- 3D Secure component reference
- 3D Secure 2 with Hosted Fields integration example
- 3D Secure 2 with Drop-in integration example
Next Page: Server-side →