3-D Secure 2

Keep your transactions compliant with Strong Customer Authentication (SCA) requirements and bring more friendly user experience to your customers with a 3-D Secure 2, also known as EMV 3-D Secure, a brand new secure authentication protocol which supports app-based authentication. Mobile SDK makes it easy to integrate all new 3-D Secure features into your e-commerce app.

iOS

App-based authentication

In the app-based flow, a cardholder initiates a transaction on a mobile device (Android or iOS) from a 3-D Secure-enabled app. Mobile SDK collects and encrypts data from the mobile device and sends it to the issuer bank. Based on the data, the bank decides whether the cardholder needs to take further action.

Frictionless flow

The authentication happens without cardholder interaction.

Challenge flow

The cardholder must interact to authenticate the payment. With Mobile SDK, the authentication runs natively in the app, with no redirects to a browser. The bank chooses from different authentication options, such as a password input in a native UI, an OTP, or an out-of-band authentication using fingerprint or, facial recognition in the banking app. Check advanced options for more details.

Integration types

The Mobile SDK provides seamless integration with 3-D Secure 2 payments.

Integration steps depend on how the app uses Mobile SDK. These guides assume that the base Mobile SDK integration is complete and payments work through one of the following methods:

  • Ready-to-use UI: Using Peach Payments' checkout screen
  • Your custom UI: Using Mobile SDK for sending transactions

Where do I start

3-D Secure 2 works out of the box with Mobile SDK. Configure 3-D Secure 2 in the Administration Portal, import the 3-D Secure library into the project, and run the first 3-D Secure 2 transaction.

Import the library

If the app follows the Install the SDK guide, then ipworks3ds_sdk is already installed. No extra imports needed.

The ipworks3ds_sdk includes two versions:

  • A development version
  • A production version: Enforces stricter security measures and blocks common development processes, such as running with attached debuggers or using simulators or emulators. This version works with apps in the official App Store or Play Store. The filename includes _deploy.

Ready-to-use UI

Before using 3-D Secure 2, enable it for specific card brands in the Administration Portal.

Peach Payments assumes that the app already integrates the base Mobile SDK and processes payments. If so, follow these steps to enhance payments with 3-D Secure 2 verification.

3-D Secure 2 works without extra setup, but Peach Payments recommends checking advanced options. Use the threeDSConfig property of the OPPCheckoutSettings instance to apply customisations.

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];  
checkoutSettings.threeDSConfig = config;  
let config = OPPThreeDSConfig()  
checkoutSettings.threeDSConfig = config  

Your custom UI

Before using 3-D Secure 2, enable it for specific card brands in the Administration Portal.

Peach Payments assumes that the app already integrates the base Mobile SDK and processes payments. If so, follow these steps to enhance payments with 3-D Secure 2 verification.

Use challenge callback

Use the OPPThreeDSEventListener protocol to handle challenge authentication:

  • onThreeDSChallengeRequiredWithCompletion: Displays the challenge screen
  • onThreeDSConfigRequiredWithCompletion: Provides extra 3-D Secure service configurations

Conform to a protocol

@interface MyCardViewController() <OPPThreeDSWorkflowListener>  
@property (nonatomic) OPPPaymentProvider *paymentProvider;  
@end  
class MyCardViewController: OPPThreeDSWorkflowListener {
    var provider: OPPPaymentProvider?
    ///
}

Assign the payment provider delegate

self.paymentProvider.threeDSEventListener = self;  
self.provider?.threeDSEventListener = self

Use protocol methods

- (void)onThreeDSConfigRequiredWithCompletion:(void (^)(OPPThreeDSConfig * _Nonnull))completion {  
    OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];  
    completion(config);  
}  

- (void)onThreeDSChallengeRequiredWithCompletion:(void (^)(UINavigationController * _Nonnull))completion {  
    completion(self.navController);  
}  
//OPPThreeDSEventListener protocol methods
    func onThreeDSChallengeRequired(completion: @escaping (UINavigationController) -> Void) {
        completion(self.navigationController!)
    }
    
    func onThreeDSConfigRequired(completion: @escaping (OPPThreeDSConfig) -> Void) {
        let config = OPPThreeDSConfig()
        completion(config)
    }

Submit transaction call

Follow the submit a transaction step of the Mobile SDK Custom UI integration guide. The payment request includes all 3-D Secure 2 actions.

Advanced options

Device data collection

The mobile SDK gathers device information from a customer's device during 3-D Secure service setup. By default, the SDK collects parameters to the fullest extent. The full list of device information is in the EMVCo specifications under the file EMV® 3-D Secure SDK—Device Information.

Device data blacklist

You can exclude specific parameters from device data collection due to market or regional restrictions. Use identifiers from the EMV® 3-D Secure SDK—Device Information file, example: I001, I002, and add them to the 3-D Secure configuration.

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
NSArray<NSString *> *blacklist = @[@"I001", @"I002"];
config.deviceParameterBlacklist = blacklist;
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
let blacklist = ["I001", "I002"]
config.deviceParameterBlacklist = blacklist

checkoutSettings.threeDSConfig = config

Security

After you set up the 3-D Secure service, verify security warnings and stop the transaction if there is high risk. Below are possible security warnings:

Security warning IDDescriptionSeverity level
SW01The device is jailbroken.High
SW02Tempering with the SDK's integrity occurredHigh
SW03An emulator is running the app.High
SW04The app has a debugger attached to itMedium
SW05The supported versions are OS or OSHigh
[paymentProvider securityWarningsWithCompletionHandler:^(NSArray * _Nullable warnings, NSError * _Nullable error) {
    if (warnings != nil && [warnings count] > 0) {
        // handle warnings
    }
}];
paymentProvider!.securityWarnings { (warnings, error) in
    if warnings.count > 0 {
        // handle warnings
    }            
}

If using the ready-to-use UI, check warnings in the callback before submitting the transaction. Use OPPCheckoutProviderDelegate to listen for checkout events. See the Mobile SDK guide for details.

If using the mobile SDK with a custom UI, invoke this method anywhere in the code.

App bundle identifier

This must match the bundle identifier set when building the application. A security warning (SW02) appears if this does not match the application's bundle ID at runtime.

Store this value on your server and retrieve it at runtime instead of hardcoding it.

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
config.appBundleID = @"com.companyname.appname";
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
config.appBundleID = "com.companyname.appname"
checkoutSettings.threeDSConfig = config

Out-of-band (OOB) authentication

Starting from 3-D Secure version 2.2.0, the authenticating application can use a special URL to call your application after an OOB authentication occurs.

Set the URL in threeDSRequestorAppURL in OPPThreeDSConfig. Your app's URL is in {CUSTOM_SCHEME}://{CUSTOM_DOMAIN} format. During OOB authentication, the authenticating application uses this URL to call your merchant application.

Add the URL to the application build settings. Refer to Register a custom URL scheme for details.

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
config.threeDSRequestorAppURL = @"{CUSTOM_SCHEME}://{CUSTOM_DOMAIN}";
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
config.threeDSRequestorAppURL = "{CUSTOM_SCHEME}://{CUSTOM_DOMAIN}"
checkoutSettings.threeDSConfig = config

Use threeDSRequestorAppURL instead of shopperResultURL to simplify integration.

After a successful OOB authentication, the authenticating application redirects to the merchant application automatically.

UI customisation

The mobile SDK allows customisation of challenge screens to match your app's design. The API provides these classes:

ClassDescription
ToolbarCustomizationCustomises the toolbar background colour and header label.
LabelCustomizationCustomises heading text.
TextCustomizationCustomises non-heading text.
TextBoxCustomizationCustomises the corner radius of input fields and labels.
ButtonCustomizationCustomises button background colour, corner radius, and font. Set the appropriate style for each button type: CANCEL: Appears in the toolbar's right corner. SUBMIT: Main action on the screen. RESEND: Secondary action. CONTINUE: Main action for authentication in an external app. Next: Main action when authentication has multiple steps.

Example UI customisation:

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
    
UiCustomization *uiCustomization = [[UiCustomization alloc] init];
ButtonCustomization *customButton = [uiCustomization getButtonCustomizationWithButtonType:ButtonTypeSUBMIT];
[customButton setTextColorWithColor:[UIColor whiteColor]];
[customButton setBackgroundColorWithColor:[UIColor redColor]];

config.uiCustomization = uiCustomization;
    
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
        
let uiCustomization = UiCustomization()
let customButton = uiCustomization.getButtonCustomization(buttonType: .SUBMIT)
customButton.setTextColor(color: UIColor.white)
customButton.setBackgroundColor(color: UIColor.red)

config.uiCustomization = uiCustomization

checkoutSettings.threeDSConfig = config

Cardholder information

Cardholder information is a 3-D Secure response field provided by ACS/Issuer during a frictionless or decoupled transaction. If this value is present in the response, display it to the cardholder.

3-D Secure app flow

Retrieve cardholder information from the OPPTransaction object. See Mobile SDK first integration for details.

- (void)handleSubmittedTransaction:(nullable OPPTransaction *)transaction error:(nullable NSError *)error {
    // get cardholder information
    if (transaction.threeDS2Info.cardHolderInfo && [transaction.threeDS2Info.cardHolderInfo length] > 0) {
                   // display cardholder info to user
    }
}
func handleSubmittedTransaction(transaction: OPPTransaction?, error: Error?) {
       //get Cardholder information
        let cardholderInfo = transaction.threeDS2Info?.cardHolderInfo
        if cardholderInfo != nil , !cardholderInfo!.isEmpty {
                 //display cardholder info to user
        }
}

3-D Secure web flow

Retrieve cardholder information from the request payment status JSON response. See 'Mobile SDK first integration' for details.

+ (nullable NSString*) cardHolderInfo: (nonnull id)responseObject {
    NSString *cardholderInfoDesc = nil;
    if ([responseObject isKindOfClass:[NSDictionary class]] && [(NSDictionary *)responseObject count] > 0) {
        NSDictionary *response = (NSDictionary *)responseObject;
        cardholderInfoDesc = response["cardholderInfo"];
    }
    return cardholderInfoDesc;
}
static func cardHolderInfo(_ response: [String: Any]) -> String {
    var cardholderInfoDesc = ""
    if let resultDetails = response["resultDetails"] as? [String: Any] {
        if let cardholderInfo = resultDetails["cardholderInfo"] as? String {
            cardholderInfoDesc = cardholderInfo
        }
    }
    return cardholderInfoDesc
}

Browser data in payment request

The mobile SDK automatically collects app- or web-related data. However, some external MPIs that support the web flow require the mobile SDK to collect browser data manually.

Enable this by setting isBrowserDataRequired in OPPThreeDSConfig. The default is false. If set to true, the mobile SDK collects browser data and appends it to the payment request.

OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
config.isBrowserDataRequired = YES;
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
config.isBrowserDataRequired = true
checkoutSettings.threeDSConfig = config

Android

App-based authentication

In the app-based flow, a cardholder starts a transaction on a mobile device (Android or iOS) from a 3-D Secure-enabled app. The Mobile SDK collects and encrypts data from the mobile device and sends it to the issuer bank. Based on the data, the bank decides whether the cardholder must interact.

Frictionless flow

The authentication happens without cardholder interaction.

Challenge flow

The cardholder must interact to authenticate the payment. With Mobile SDK, the app embeds authentication natively without browser redirects. The bank can start multiple authentication options, such as password input in a native UI, an OTP, or out-of-band authentication using fingerprint or, facial recognition in the banking app. Check advanced options for details.

Integration types

The Mobile SDK provides seamless integration with 3-D Secure 2 payments.

Integration steps differ depending on how the app uses Mobile SDK. These guides assume that base Mobile SDK is already integrated to make payments using one of the following methods:

  • Ready-to-use UI: using the checkout screen.
  • Custom UI: using Mobile SDK for sending transactions.

Where to start

3-D Secure 2 should work out of the box with the Mobile SDK. Configure 3-D Secure 2 in the administration portal, import the 3-D Secure library into the project, and run the first 3-D Secure 2 transaction.

Import the library

If you followed the SDK installation guide, the ipworks3ds_sdk library is already installed. You don't need to import anything extra.

The two versions of ipworks3ds_sdk: one for development and one for production. The production version includes stricter security measures that prevent common development processes, such as running with attached debuggers or using simulators/emulators. The production version does not work with apps outside the official app/play store and includes _deploy in the filename.

Ready-to-use UI

You must complete the base Mobile SDK integration and submit payments. Follow these instructions to enhance payments with 3-D Secure 2 verification.

📘

You must configure the administration portal to enable 3-D Secure 2 for specific card brands.

3-D Secure 2 integration works out of the box, but you should review advanced options. Use the threeDSConfig property of the CheckoutSettings instance to apply customisations.

CheckoutSettings checkoutSettings = new CheckoutSettings(checkoutId, paymentBrands, providerMode);
ThreeDSConfig.Builder configBuilder = new ThreeDSConfig.Builder();
checkoutSettings.setThreeDS2Config(configBuilder.build());
val checkoutSettings = CheckoutSettings(checkoutId, paymentBrands, providerMode) 
val configBuilder =ThreeDSConfig.Builder() 
checkoutSettings.setThreeDS2Config(configBuilder.build())

Your custom UI

You must complete the base Mobile SDK integration and submit payments. Follow these instructions to enhance payments with 3-D Secure 2 verification.

📘

You must configure the administration portal to enable 3-D Secure 2 for specific card brands.

Use challenge callback

Use ThreeDSWorkflowListener:

  • onThreeDSChallengeRequired for displaying the challenge screen.
  • onThreeDSConfigRequired for providing extra 3-D Secure service configuration.
ThreeDSWorkflowListener threeDSWorkflowListener = new ThreeDSWorkflowListener() {
    @Override
    public Activity onThreeDSChallengeRequired() {
        return activity;
    }

    @Override
    public ThreeDSConfig onThreeDSConfigRequired() {
        return threeDSConfig;
    }
};
val threeDSWorkflowListener: ThreeDSWorkflowListener = object : ThreeDSWorkflowListener {
    override fun onThreeDSChallengeRequired(): Activity {
        // provide your Activity
        return activity
    }

    override fun onThreeDSConfigRequired(): ThreeDSConfig {
        // provide your ThreeDSConfig
        return threeDSConfig
    }
}

Set the listener to the provider:

paymentProvider.setThreeDSWorkflowListener(threeDSWorkflowListener);
paymentProvider!!.setThreeDSWorkflowListener(threeDSWorkflowListener)

Submit transaction call

Follow the submit transaction step in the Mobile SDK custom UI integration guide. The payment request includes all 3-D Secure 2 actions.

Handling app process destruction during the 3-D Secure flow

If the app moves to the background during the 3-D Secure flow, the OS might destroy it due to low memory, removing the transaction state. After restarting the app, use ThreeDS2Service.wasTransactionKilled() to check whether the transaction stopped prematurely.

if (ThreeDS2Service.wasTransactionKilled()) {
    // Request payment status
}
if (ThreeDS2Service.wasTransactionKilled()) {
    // request payment status
}

Advanced options

These options include:

  • Improving device data collection
  • Making authentication more secure
  • Customising challenge screens

Device data collection

Mobile SDK gathers device information during 3-D Secure service initialisation. By default, the SDK collects parameters to the fullest extent. A full list of device information is in the EMVCo Specifications, check the file called EMV® 3-D Secure SDK—Device Information.

App permissions

Some device data requires specific permissions:

Data sourcePermission typeRequired permissions
Telephony ManagerRun-time permissionsandroid.permission.SEND_SMS
android.permission.READ_PHONE_STATE
android.permission.READ_PHONE_NUMBERS
The system grants these permissions during installation for API 22 and earlier, so user approval is not needed.
Wifi ManagerInstallation-time permissionsandroid.permission.ACCESS_WIFI_STATE
Bluetooth ManagerInstallation-time permissionsandroid.permission.BLUETOOTH

Device data blacklist

Exclude specific device parameters due to market or regional restrictions using setDeviceParameterBlacklist. Use identifiers from the EMV® 3-D Secure SDK—Device Information file, for example, A001, A002, and add this information to the 3-D Secure config.

ThreeDSConfig.Builder configBuilder = new ThreeDSConfig.Builder();
String[] blacklist = {"A001", "A002"};
configBuilder.setDeviceParameterBlacklist(blacklist);
checkoutSettings.setThreeDS2Config(configBuilder.build());
val configBuilder = ThreeDSConfig.Builder() 
val blacklist = arrayOf("A001", "A002") 
configBuilder.setDeviceParameterBlacklist(blacklist) 

checkoutSettings.setThreeDS2Config(configBuilder.build())

Security

After initialising the 3-D Secure service, verify security warnings. Abort the transaction if the risk is high.

Security warnings

Security warning IDDescriptionSeverity level
SW01The device is jailbroken.High
SW02Tempering with the SDK's integrity occurredHigh
SW03An emulator is running the app.High
SW04The app has a debugger attached to itMedium
SW05The supported versions are OS or OSHigh

If you use the ready-to-use UI, the right place to check warnings is a callback which is called before submitting the transaction. For this purpose, you should implement the broadcast receiver to listen the intents from CheckoutActivity. See details in the Mobile SDK guide.

public class CheckoutBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (CheckoutActivity.ACTION_ON_BEFORE_SUBMIT.equals(intent.getAction())) {
            if (intent.hasExtra(CheckoutActivity.EXTRA_THREEDS_WARNINGS)) {
                List<Warning> threeDS2Warnings = intent
                    .getParcelableArrayListExtra(CheckoutActivity.EXTRA_THREEDS_WARNINGS);
                // Handle warnings
            }
        }
    }
}
class CheckoutBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, oldIntent: Intent?) {
        val action = oldIntent?.action

        if (CheckoutActivity.ACTION_ON_BEFORE_SUBMIT == action) {
            if (intent.hasExtra(CheckoutActivity.EXTRA_THREEDS_WARNINGS)) {
                val threeDS2Warnings: List<Warning> = intent
                        .getParcelableArrayListExtra(CheckoutActivity.EXTRA_THREEDS_WARNINGS)

                // handle warnings
            }
        }
    }
}

If you use Mobile SDK and your custom UI, you can invoke this method anywhere in your code.

val threeDS2Warnings: List<Warning> = paymentProvider!!.threeDS2Warnings
val threeDS2Warnings: List<Warning> = paymentProvider!!.threeDS2Warnings

App signature

The app signature verifies that the application was not tampered with before installation. The SDK expects the value as the SHA256 fingerprint of the certificate used to sign the app. If this value does not match the real app signature, it raises a security warning (SW02).

Do not hardcode the app signature in the app for security reasons. Store it on your server and retrieve it at runtime.

val configBuilder = ThreeDSConfig.Builder() 
configBuilder.setAppSignature("85:05:D8:B8:26:C6:AB:C6:AB:0B:49:08:F8:6E:5D:DF:CD:FF:16:69:DD:B2:93:3B:78:9D:64:6A:DE:FC:7A:9F") 

checkoutSettings.setThreeDS2Config(configBuilder.build())
val configBuilder = ThreeDSConfig.Builder() 
configBuilder.setAppSignature("85:05:D8:B8:26:C6:AB:C6:AB:0B:49:08:F8:6E:5D:DF:CD:FF:16:69:DD:B2:93:3B:78:9D:64:6A:DE:FC:7A:9F") 
 
checkoutSettings.setThreeDS2Config(configBuilder.build())

Apps filter

The 3-D Secure Service checks the list of installed apps on the customer's device. If it finds any suspicious applications or those not installed from trusted app stores, it raises a security warning (SW02).

By default, the trusted store is:

  • Google Play store (com.android.vending)

Malicious apps include:

  • de.robv.android.xposed
  • de.robv.android.xposed.installer
  • com.saurik.substrate

You can complete these lists with your values using configuration properties:

val configBuilder = ThreeDSConfig.Builder() 
configBuilder.setTrustedAppStores(arrayOf("com.xiaomi.market")) 
             .setMaliciousApps(arrayOf("de.robv.android.xposed")) 

checkoutSettings.setThreeDS2Config(configBuilder.build())
val configBuilder = ThreeDSConfig.Builder() 
configBuilder.setTrustedAppStores(arrayOf("com.xiaomi.market")) 
             .setMaliciousApps(arrayOf("de.robv.android.xposed")) 
 
checkoutSettings.setThreeDS2Config(configBuilder.build())

Out-of-band (OOB) authentication

Starting from 3-D Secure version 2.2.0, an OOB authenticating application can use threeDSRequestorAppURL to call your application after an OOB authentication occurs.

After successful OOB authentication, redirection from the authenticating application to the merchant application happens automatically.

This URL is not used by default. Enable it in the ThreeDSConfig:

ThreeDSConfig threeDSConfig = new ThreeDSConfig.Builder()
        .setThreeDSRequestorAppUrlUsed(true)
        .build();
checkoutSettings.setThreeDS2Config(threeDSConfig);
val threeDSConfig: ThreeDSConfig = ThreeDSConfig.Builder()
        .setThreeDSRequestorAppUrlUsed(true)
        .build()
checkoutSettings.threeDS2Config = threeDSConfig

UI customisation

Customise challenge screens to match the app's look and feel. The following classes are available:

ClassDescription
ToolbarCustomizationToolbar background colour and header label
LabelCustomizationHeading text
TextCustomizationNon-heading text
TextBoxCustomizationInput fields and labels
ButtonCustomizationButton background color, corner radius, and font customisation. Set appropriate style for each button type: CANCEL (right corner of toolbar), SUBMIT (main action), RESEND (secondary action), CONTINUE (main action for authentication in external app), NEXT (main action for multi-step authentication)
ThreeDSConfig.Builder configBuilder = new ThreeDSConfig.Builder();
UiCustomization uiCustomization = new UiCustomization();
ButtonCustomization customButton = new ButtonCustomization();
customButton.setTextColor("#FFFFFF");
customButton.setBackgroundColor("#951728");
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.SUBMIT);
configBuilder.setUiCustomization(uiCustomization);
checkoutSettings.setThreeDS2Config(configBuilder.build());
val configBuilder = ThreeDSConfig.Builder() 
 
val uiCustomization = UiCustomization() 
val customButton = ButtonCustomization() 
customButton.textColor = "#FFFFFF" // White 
customButton.backgroundColor = "#951728" // Dark red 
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.SUBMIT) 
 
configBuilder.setUiCustomization(uiCustomization) 
 
checkoutSettings.setThreeDS2Config(configBuilder.build())

Cardholder information

Cardholder information is a 3-D Secure response field that the ACS or issuer provides during a frictionless or decoupled transaction. The issuer provides information to the cardholder. If this value is in the transaction response, the merchant app must display it to the cardholder.

3-D Secure app flow

Retrieve cardholder information in the transaction object in CheckoutActivityResult in the 3-D Secure app flow. See Mobile SDK first integration for more details.

private void handleCheckoutResult(@NonNull CheckoutActivityResult result) {
    Transaction transaction = result.getTransaction();
    String cardHolderInfo = null;
    if (tranasction != null) {
        //get Cardholder information
        if (transaction.getThreeDS2Info() != null
                && (transaction.getThreeDS2Info().getCardHolderInfo() != null)) {

            cardHolderInfo = transaction.getThreeDS2Info().getCardHolderInfo();
            if (cardHolderInfo != null) {
                //display cardholder info to user
            }
        }
    }
}
private fun handleCheckoutActivityResult(result: CheckoutActivityResult) {
    val transaction = result.transaction
    val cardHolderInfo = transaction?.threeDS2Info?.cardHolderInfo
    if (cardHolderInfo != null) {
        // display cardholder info to user
    }
}

3-D Secure web flow

Retrieve cardholder information in the request payment status JSON response in the 3-D Secure web flow. See Mobile SDK First Integration for more details.

@Nullable
public static String getCardHolderInfo(@NonNull String response)
            throws Exception {
        JSONObject responseJson = new JSONObject(response);

        if (responseJson.has("resultDetails")) {
            JSONObject resultDetails = responseJson.getJSONObject("resultDetails");
            if (resultDetails.has("cardholderInfo")) {
                return resultDetails.getString("cardholderInfo");
            }
        }
        return null;
}
fun getCardHolderInfo(response:String): String? {
    val responseJson = JSONObject(response)
    if (responseJson.has("resultDetails")) {
        val resultDetails = responseJson.getJSONObject("resultDetails")
        if (resultDetails.has("cardholderInfo")) {
            return resultDetails.getString("cardholderInfo")
        }
    }
    return null
}

Browser data in payment request

The mobile SDK collects app- or web-related information automatically. Some external MPIs that support the web flow may require the mobile SDK to collect browser information manually.

Set isBrowserDataRequired to true in the ThreeDSConfig class to collect browser data and add it to the payment request when submitting the transaction.

ThreeDSConfig threeDSConfig = new ThreeDSConfig.Builder()
          .setBrowserDataRequired(true)
          .build();
checkoutSettings.setThreeDS2Config(threeDSConfig);
val threeDSConfig = ThreeDSConfig.Builder()
      .setBrowserDataRequired(true)
      .build()
checkoutSettings.setThreeDS2Config(threeDSConfig)

Async transaction in 3-D Secure web flow

If 3-D Secure authentication happens in the bank app using a custom scheme in the 3-D Secure web flow, mSDK returns this custom scheme as the redirect URL in the transactionCompleted event. Open this redirect URL as an intent or in Chrome custom tabs to launch the bank app. After 3-D Secure authentication, the redirect to shopperResultUrl returns control to the merchant app.

Ready-to-use UI

Mobile SDK handles this.

Custom UI integration

Use ITransactionListener.

@Override
public void transactionCompleted(Transaction transaction) {
  // if a transaction is ASYNC, open custom schema in Chrome Custom Tab
  if (transaction.getTransactionType() == TransactionType.ASYNC) {
        String redirectUrl = transaction.getRedirectUrl();
        showChromeCustomTab(redirectUrl);
        return;
     }
  }
 
 @Override
 public void transactionFailed(@NonNull Transaction transaction, @NonNull PaymentError error) {
    // show error message
 }
 
 public void showChromeCustomTab(String url) {
    CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
    builder.setShareState(CustomTabsIntent.SHARE_STATE_OFF);
    CustomTabsIntent tabIntent = builder.build();
    tabIntent.launchUrl(context, url);
 }    
override fun transactionCompleted(transaction: Transaction) {
    // if a transaction is ASYNC, open custom scheme in Chrome Custom Tab
    if (transaction.transactionType == TransactionType.ASYNC) {
        val redirectUrl = transaction.redirectUrl
        showChromeCustomTab(redirectUrl)
        return
    }
}

override fun transactionFailed(transaction: Transaction, error: PaymentError) {
    // show error message
}

fun showChromeCustomTab(url: String) {
    val builder = CustomTabsIntent.Builder()
    builder.setShareState(CustomTabsIntent.SHARE_STATE_OFF)
    val tabIntent = builder.build()
    tabIntent.launchUrl(context, Uri.parse(url))
}