3DS 2.0 Android SDK

Integrate the 3D Secure 2.0 SDK into your Android application.

This is a mobile SDK that you embed into the your Android application. The SDK is available at https://github.com/Adyen/adyen-3ds2-android.


  1. Copy the SDK package adyen-3ds2-sdk.aar to the /libs folder in your app module.
  2. Import the SDK by adding these lines to your app module build.gradle file.

    dependencies {
        implementation "com.adyen.threeds2:adyen-3ds2-sdk:0.9.0@aar"
    repositories {
        flatDir {
            dirs 'libs'


SDK initialization

To start using the SDK, your app must first initialize it by providing the SDK parameters about configuration, UI customization and locale.

For this, create new instances of ThreeDS2Service, ConfigParameters, and UICustomization, as follows:

ThreeDS2Service service = ThreeDS2Handler.getService();
ConfigParameters configParam = new ConfigParameters();
UiCustomization uiConfig = new UiCustomization();

ThreeDS2Service initialization

Finally, your app should call the initialize() method of the ThreeDS2Service object.

service.initialize(currentActivity, configParam, locale, uiConfig);

If the locale parameter is null, then the default locale will be used.

If the uiConfig parameter is null, then your app's current theme will be used. For more details, see the UI Customization section.

Depending on implementation, calling the initialize() method may take some time and cause a short delay. Thus, it is recommended to call it in a separate thread.

After the initialize() method has been called, your app may call the getWarnings() method of the ThreeDS2Service to query possible warnings generated during initialization.

Transaction initiation

The transaction is created using the createTransaction() method of the ThreeDS2Service object service. This returns an instance of Transaction, through which your app can access the transaction data.

Transaction transaction = service.createTransaction(paymentSystemId, messageVersion);

Transaction message version

The SDK supports only the latest message version 2.1.0.

The createTransaction() method of the ThreeDS2Service interface has a messageVersion parameter, which allows your app to specify the Secure Protocol Version to be used by the 3DS SDK during the challenge. This means that the CReq messageVersion should follow this parameter, and any received CRes should have its messageVersion validated against the parameter value.

If the messageVersion parameter is null or empty, then the highest protocol version supported by the SDK will be used. If the passed messageVersion parameter is not supported by the SDK, then the SDK throws an InvalidInputException.

Progress dialog

While your app is communicating with the 3DS Requestor Environment, a progress dialog is displayed. Transaction implements a Dialog class, which can be accessed through getProgressView() method.

The example below creates progressDialog object and displays it in the current activity.

Dialog progressDialog = transaction.getProgressView(currentActivity);
progressDialog.show(); // To show the dialog.
progressDialog.cancel(); // To dismiss the dialog.

Retrieving authentication request parameters

The AuthenticationRequestParameters instance can be retrieved from the Transaction object.

AuthenticationRequestParameters params = transaction.getAuthenticationRequestParameters();

Implementing the AReq/ARes-phase

The actual AReq construction is outside of the SDK scope and depends on the 3DS Server implementation. The interface between your app and 3DS Server (or other access point in 3DS Environment) is not defined in the Core or SDK Specifications.

The SDK offers an AuthenticationRequestParameters class, which is used to access needed transaction data:

  • Device Data
  • SDK Transaction ID
  • SDK AppID
  • SDK Reference Number
  • SDK Ephemeral Public Key
  • Message Version

In addition to the above, the 3DS Server will need further transaction data, such as the card number and purchase amount. Your app passes the needed information to 3DS Server, which performs the AReq/ARes-phase. During this time, your app displays the Progress Dialog to the cardholder and waits for a response from 3DS Server.

Deciding to proceed to Challenge flow

Based on information received from the 3DS Server, your app has to decide if a Challenge is needed. If so, your app needs to pass the required data to the SDK so that the CReq-message can be constructed.

Request parameters are held in a ChallengeParameters object.

To perform the actual Challenge, your app should call the transaction.doChallenge() method with the appropriate ChallengeStatusReceiver.

The example below shows one way of implementing this phase in your app.

String transactionStatus = authenticationResponse.getString(ProtocolConstants.TransactionStatus);
boolean challenge = transactionStatus.contentEquals("C");

if (challenge) -->

String threeDSServerTransID = authenticationResponse.getString(ProtocolConstants.ThreeDSServerTransID);
String acsTransID = authenticationResponse.getString(ProtocolConstants.ACSTransID);
String acsSignedContent = authenticationResponse.getString(ProtocolConstants.ACSSignedContent);
String acsRenderingType = authenticationResponse.getString(ProtocolConstants.ACSRenderingType);
String acsReferenceNumber = authenticationResponse.getString(ProtocolConstants.ACSReferenceNumber);

ChallengeParameters challengeParameters = new ChallengeParameters();
challengeParameters.set3DSServerTransactionID(threeDSServerTransID); challengeParameters.setAcsTransactionID(acsTransID);

transaction.doChallenge(currentActivity, challengeParameters, new ChallengeStatusReceiver() {
    public void completed(CompletionEvent e) {
        log.debug("<- Completed");
        // At this point, your app can contact the 3DS Server to
        // determine the result of the challenge.

    public void cancelled() {
        log.debug("<- cancelled");
        // Can go to Cancelled view, if desired.

    public void timedout() {
        log.debug("<- timedout");
        // Can show the error alert.

    public void protocolError(ProtocolErrorEvent e) {
        log.debug("<- protocolError");
        // Can show the error alert.

    public void runtimeError(RuntimeErrorEvent e) {
        log.debug("<- runtimeError");
        // Can show the error alert.
}, timeout);

UI Customization

If you wish to provide custom look-and-feel for the Challenge pages in your app, use the UICustomization class.

For example, the following sample would set the Challenge page UI as:

  • 10px rounded corners on text input filed.
  • Monospace 18px font as label font.
  • The toolbar background as dark red with white 28px font.
  • The Verify button to have 10px rounding on corners and dark red background with white text.
ToolbarCustomization toolbarCustomization = new ToolbarCustomization(); toolbarCustomization.setBackgroundColor("#951728");

LabelCustomization labelCustomization = new LabelCustomization(); labelCustomization.setTextFontName(Typeface.MONOSPACE.toString());

TextBoxCustomization textBoxCustomization = new TextBoxCustomization(); textBoxCustomization.setCornerRadius(10);

ButtonCustomization buttonCustomization = new ButtonCustomization(); buttonCustomization.setBackgroundColor("#951728");

UiCustomization uiConfig = new UiCustomization();
uiConfig.setButtonCustomization(buttonCustomization, UiCustomization.ButtonType.VERIFY);

See also