3D Secure
Client-Side Implementation
Generate a client token
Before you can initialize a ThreeDSecureClient
, you will need to set up the SDK and initialize a BraintreeClient
with a ClientTokenProvider
.
Additionally, add the following Maven repository and (non-sensitive) credentials to your app-level gradle.
- Groovy
repositories {
maven {
url "https://cardinalcommerceprod.jfrog.io/artifactory/android"
credentials {
username = 'braintree_team_sdk'
password = 'AKCp8jQcoDy2hxSWhDAUQKXLDPDx6NYRkqrgFLRc3qDrayg6rrCbJpsKKyMwaykVL8FWusJpp'
}
}
}
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
First, make sure to include our Drop-in in your project. Next, declare a URL scheme in your AndroidManifest. This allows your app to switch to a browser to complete the 3D Secure verification workflow and return.
To use 3DS2, you will need to create a ThreeDSecureRequest
object with relevant customer and transaction data in order to minimize the need for issuing banks to present authentication challenges to customers. This object must contain the following fields:
amount
versionRequested
(You should passThreeDSecureRequest.VERSION_2
here)
And should contain as many of the following fields as possible:
email
billingAddress
additionalInformation
- Java
- Kotlin
ThreeDSecurePostalAddress address = new ThreeDSecurePostalAddress();
address.setGivenName("Jill"); // ASCII-printable characters required, else will throw a validation error
address.setSurname("Doe"); // ASCII-printable characters required, else will throw a validation error
address.setPhoneNumber("5551234567");
address.setStreetAddress("555 Smith St");
address.setExtendedAddress("#2");
address.setLocality("Chicago");
address.setRegion("IL"); // ISO-3166-2 code
address.setPostalCode("12345");
address.setCountryCodeAlpha2("US");
// For best results, provide as many additional elements as possible.
ThreeDSecureAdditionalInformation additionalInformation = new ThreeDSecureAdditionalInformation();
additionalInformation.setShippingAddress(address);
ThreeDSecureRequest threeDSecureRequest = new ThreeDSecureRequest();
threeDSecureRequest.setAmount("10.00");
threeDSecureRequest.setEmail("test@email.com");
threeDSecureRequest.setBillingAddress(address);
threeDSecureRequest.setVersionRequested(ThreeDSecureRequest.VERSION_2);
threeDSecureRequest.setAdditionalInformation(additionalInformation);
Then, add the ThreeDSecureRequest
to your DropInRequest
.
- Java
- Kotlin
DropInRequest dropInRequest = new DropInRequest();
dropInRequest.setThreeDSecureRequest(threeDSecureRequest);
Custom UI
To make sure your app can complete a 3D Secure verification, declare a URL scheme in your AndroidManifest. This will allow Android to return to your app from a browser-based verification flow.
Add the following to your app-level build.gradle
file:
- Groovy
dependencies {
implementation 'com.braintreepayments.api:three-d-secure:4.39.0'
}
Next, create a ThreeDSecureRequest
with relevant customer and transaction data to help minimize the need for issuing banks to present authentication challenges to customers. This object must contain the following fields:
amount
nonce
versionRequested
(You should passThreeDSecureRequest.VERSION_2
here)
And should contain as many of the following fields as possible:
email
billingAddress
additionalInformation
- Java
- Kotlin
// Card nonce that we wish to upgrade to a 3DS nonce.
CardNonce cardNonce = (CardNonce) paymentMethodNonce;
ThreeDSecurePostalAddress address = new ThreeDSecurePostalAddress();
address.setGivenName("Jill"); // ASCII-printable characters required, else will throw a validation error
address.setSurname("Doe"); // ASCII-printable characters required, else will throw a validation error
address.setPhoneNumber("5551234567");
address.setStreetAddress("555 Smith St");
address.setExtendedAddress("#2");
address.setLocality("Chicago");
address.setRegion("IL"); // ISO-3166-2 code
address.setPostalCode("12345");
address.setCountryCodeAlpha2("US");
// For best results, provide as many additional elements as possible.
ThreeDSecureAdditionalInformation additionalInformation = new ThreeDSecureAdditionalInformation();
additionalInformation.setShippingAddress(address);
ThreeDSecureRequest threeDSecureRequest = new ThreeDSecureRequest();
threeDSecureRequest.setAmount("10");
threeDSecureRequest.setEmail("test@email.com");
threeDSecureRequest.setBillingAddress(address);
threeDSecureRequest.setNonce(cardNonce.getString());
threeDSecureRequest.setVersionRequested(ThreeDSecureRequest.VERSION_2);
threeDSecureRequest.setAdditionalInformation(additionalInformation);
You can submit a ThreeDSecureRequest
by calling ThreeDSecureClient#performVerification
. If a card is enrolled in a 3D Secure program (e.g. Verified by Visa), the sdk will present a 3D Secure authentication challenge using card data linked to a payment method nonce.
- Java
- Kotlin
BraintreeClient braintreeClient = new BraintreeClient(this, new ExampleClientTokenProvider());
ThreeDSecureClient threeDSecureClient = new ThreeDSecureClient(this, braintreeClient);
threeDSecureClient.performVerification(activity, threeDSecureRequest, (threeDSecureLookupResult, lookupError) -> {
// optional: inspect the lookup result and prepare UI if a challenge is required
threeDSecureClient.continuePerformVerification(activity, threeDSecureRequest, threeDSecureLookupResult);
});
Implement a ThreeDSecureListener
to receive results from the 3D Secure flow. Once the user completes the 3D Secure process, send the nonce to your server and create a transaction.
- Java
- Kotlin
public class MyActivity extends AppCompatActivity implements ThreeDSecureListener {
@Override
public void onThreeDSecureSuccess(@NonNull ThreeDSecureResult threeDSecureResult) {
// send this nonce to your server
String nonce = threeDSecureResult.getTokenizedCard().getString();
}
@Override
public void onThreeDSecureFailure(@NonNull Exception error) {
if (error instanceof UserCanceledException) {
// user canceled
} else {
// handle error
}
}
}
If you are using using an Activity and your Activity's launch mode is singleTop
, singleTask
, or singleInstance
you will also need to override onNewIntent
:
- Java
- Kotlin
public class MyActivity extends AppCompatActivity {
@Override
protected void onNewIntent(Intent newIntent) {
super.onNewIntent(newIntent);
setIntent(newIntent);
}
}
Verify a vaulted credit card
First, on the server, generate and return a payment method nonce for the vaulted credit card.
Then in your app, you can call ThreeDSecureClient#performVerification
with 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.
- Java
- Kotlin
@Override
public void onThreeDSecureSuccess(@NonNull ThreeDSecureResult threeDSecureResult) {
Card card = threeDSecureResult.getTokenizedCard();
boolean liabilityShifted = card.getThreeDSecureInfo().isLiabilityShifted();
boolean liabilityShiftPossible = card.getThreeDSecureInfo().isLiabilityShiftPossible();
}
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:
- Java
- Kotlin
ThreeDSecureRequest request = new ThreeDSecureRequest();
request.setEmail("test@email.com");
request.setAmount("10");
request.setBillingAddress(address);
request.setAdditionalInformation(additionalInfo);
request.setNonce(paymentMethodNonce);
request.setVersionRequested(ThreeDSecureRequest.VERSION_2);
request.setDataOnlyRequested(true);
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 GooglePayCardNonce
as the nonce
property on your ThreeDSecureRequest
. See the Google Pay configuration guide for how to generate a GooglePayCardNonce
. Once you have generated a nonce, follow these instructions:
First, check if your GooglePayCardNonce
is non-network tokenized. Then, construct a ThreeDSecureRequest
with this nonce.
- Java
- Kotlin
if (!googlePayCardNonce.isNetworkTokenized()) {
// eligible for 3DS Verification
ThreeDSecurePostalAddress address = new ThreeDSecurePostalAddress()
address.setPhoneNumber(googlePayCardNonce.getBillingAddress().getPhoneNumber())
address.setStreetAddress(googlePayCardNonce.getBillingAddress().getStreetAddress())
address.setExtendedAddress(googlePayCardNonce.getBillingAddress().getExtendedAddress())
address.setLocality(googlePayCardNonce.getBillingAddress().getLocality())
address.setRegion(googlePayCardNonce.getBillingAddress().getRegion())
address.setPostalCode(googlePayCardNonce.getBillingAddress().getPostalCode())
address.setCountryCodeAlpha2(googlePayCardNonce.getBillingAddress().getCountryCodeAlpha2())
ThreeDSecureAdditionalInformation additionalInfo = new ThreeDSecureAdditionalInformation()
additionalInfo.setShippingAddress(address)
ThreeDSecureRequest request = new ThreeDSecureRequest();
request.setAmount("10");
request.setEmail(googlePayCardNonce.getEmail());
request.setBillingAddress(address);
request.setAdditionalInformation(additionalInfo);
request.setNonce(googlePayCardNonce); // Use Google Pay nonce
request.setVersionRequested(ThreeDSecureRequest.VERSION_2);
}
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.
- Java
- Kotlin
ThreeDSecureRequest request = new ThreeDSecureRequest();
request.setAmount("10");
request.setEmail("test@email.com");
request.setBillingAddress(address);
request.setAdditionalInformation(additionalInfo);
request.setNonce(paymentMethodNonce);
request.setVersionRequested(ThreeDSecureRequest.VERSION_2);
request.setAccountType(ThreeDSecureRequest.CREDIT);
See also
Next Page: Server-side →