3D Secure mobile SDKs
Last updated: April 29, 2022
Our 3D Secure (3DS) mobile SDKs allow you to provide a native 3DS2 experience in your Android and iOS apps, with visual styling that you can control.
They work with our non-hosted authentication solution, so you can authenticate within the payment authorization flow, or perform only authentication and complete the payment later.
Once you've initiated the authentication, the SDK handles the tasks of collecting device data, exchanging information with the customer's bank, and, if necessary, presenting a challenge to the customer. You can then use the authentication result to authorize the payment.
Your customers' data
Our SDKs collect only data which your app has permission to collect, and it is encrypted throughout authentication. The customer will never be prompted to grant new permissions. We don't store any of the device data collected during authentication, and our SDKs do not retain any personal information about the user.
Tip
Our 3D Secure SDK supports 3DS2 (version 2.1.0 and, if your configuration supports it, 2.2.0). It also supports 3DS1 in cases where 3DS2 is not available. However, this feature must be enabled for your account. The SDK handles the version complexity for you, and passes a simple authentication result back to your app, regardless of the 3D Secure version used.
The 3DS2 customer experience
3DS2 allows you and your payment provider to share more data (like the customer's device ID and payment history) with the customer's bank so they can better assess the risk of the transaction and select the appropriate response: either the "frictionless flow" or "challenge flow".
Frictionless flow
If the customer's bank is satisfied with the data and trusts that it is the cardholder making the payment, the transaction will be authenticated without interrupting the customer. All the customer will see of the 3DS process is a short "processing" overlay, with branding from their card scheme.

Challenge flow
If, however, the bank decides it needs further proof, they will prompt the customer to verify their identity. This can take one of the following forms:
One-time password. The customer's bank sends a single use password or code to the customer, usually as a text message or email, and asks them to enter it.
Single-select or multi-select. The bank asks the customer a multiple choice question, with either a single or multiple selections allowed.
Out-of-band. The customer is asked to confirm the transaction through another channel, typically their banking app. (See example below.)
HTML. The customer's bank defines the exact view to be presented to the customer, using HTML formatting. The challenge may take one of the above forms, or the bank may devise their own approach.

Customize the challenge UI
To provide a consistent experience across different devices and schemes, there are standard templates and rules that the 3DS challenge screens adhere to. However, there is some leeway around styling. Our SDKs give you control over the display of the native challenges in your app, while ensuring that the rules are followed.
How it works
To use one of our 3DS mobile SDKs, first integrate the library into your project. Then, configure your iOS or Android app to:
- Initialize the SDK with your preferred user interface options.
- Configure the parameters for an authentication.
- Request authentication and handle the result to continue your payment flow.
Implementation examples
Below are some code examples for each platform.
Integrate the 3D Secure SDK into your app
To gain access to the 3D Secure mobile SDKs, contact your Customer Success Manager or Integrations engineer, or email us at support@checkout.com.
Then, on iOS, install the library in your app project using CocoaPods. For Android, add the library to your app as a Gradle dependency.
1// Add the following to your project’s top-level build.gradle.kts file.2allprojects {3repositories {4maven {5url = uri("https://maven.pkg.github.com/checkout/checkout-3ds-sdk-android")6credentials {7username = ""8password = ""9}10}11}12}1314// Add the following to the module level build.gradle.kts file.15dependencies {16implementation("com.checkout:checkout-sdk-3ds-android:")17}
Add the 3D Secure SDK to your app's payment flow
Step 1: Initialize the SDK
Initialize the SDK, setting the environment (production or sandbox), the locale, and your preferred challenge user interface options.
1// 1a. Initialize with default arguments2let checkout3DS = Checkout3DSService()34// 1b. Alternatively, initialize with explicit arguments5let checkout3DS = Checkout3DSService(6environment: .production,7locale: Locale(identifier: "en_GB"),8uiCustomization: uiCustomization,9appURL: URL(string: "https://my-app-url.com")!10)
Step 2: Configure the authentication parameters
After your backend has requested an authentication session with our Sessions API, you will receive a response.
Use the authenticate
method to start the authentication, passing the values you received in the Sessions API response into authenticationParameters
.
The SDK will then gather the device data, share the information with the customer's bank, and, if necessary, present a challenge to the customer.
1let authenticationParameters = AuthenticationParameters(2sessionID: sessionID,3sessionSecret: sessionSecret,4scheme: scheme)
Step 3: Request authentication and handle the result
Once the authentication is completed, the SDK returns a result.
- On Android, the result is either
Successful
,Failed
, orError
. - On iOS, the SDK returns an optional
AuthenticationError
. If the attempt was unsuccessful, this indicates the failure reason, otherwise this value isnil
.
If successful, you can use our Payments API to complete the payment, or use another payment services provider to do so.
1checkout3DS.authenticate(authenticationParameters: authenticationParameters) { error in2if let error = error {3// Handle error.4} else {5// Continue with payment.6}7}
Customize the challenge user interface
We’ve built a simple, clean default style for the native challenge user interfaces, so you can quickly get going without defining your own style. But if you want to tailor the challenge screens in your app, our SDKs let you control:
- Fonts and font colors.
- The background color of the navigation bar and footer.
- The background color, opacity, shadows, and corner radiuses of the action buttons.
Our SDKs also handle different screen sizes and orientations, and allow you to address different user needs with dynamic text sizing, TalkBack and VoiceOver assistance, and support for 37 languages (though the body of the challenge screens is always presented in the language provided by the customer's bank).
To apply your own style, simply include a UI Customization object when you initialize the SDK. We've included some code examples below to show you how you might build the object.
1final class Customization1: UICustomization {2let toolbarCustomization: ToolbarCustomization = DefaultToolbarCustomization(3backgroundColor: .blue,4headerTitle: "3DS Check",5buttonTitle: "Cancel",6font: UIFont(name: "Optima-Bold", size: 20)!,7textColor: .black)8let labelCustomization: LabelCustomization = DefaultLabelCustomization(9headingTextColor: .purple,10headingFont: UIFont(name: "Optima-Bold", size: 16)!,11font: UIFont(name: "Optima-Regular", size: 16)!,12textColor: .orange)13let buttonCustomizations: ButtonCustomizations = DefaultButtonCustomizations(14verifyButtonCustomization: DefaultButtonCustomization(15backgroundColor: .red,16cornerRadius: 24,17cornerCurve: .circular,18font: UIFont(name: "Optima-Regular", size: 14)!,19textColor: .white,20borderWidth: 0,21borderColor: UIColor.clear.cgColor),22continueFlowButtonCustomization: DefaultButtonCustomization(23backgroundColor: UIColor.blue,24cornerRadius: 24,25cornerCurve: .circular,26font: UIFont(name: "Optima", size: 14)!,27textColor: .white,28borderWidth: 0,29borderColor: UIColor.clear.cgColor))30let whitelistCustomization: WhitelistCustomization = DefaultWhitelistCustomization(31font: UIFont(name: "Optima-Regular", size: 16)!,32textColor: .black,33switchTintColor: .green)34let footerCustomization: FooterCustomization = DefaultFooterCustomization(35backgroundColor: .clear,36font: UIFont(name: "Optima-Bold", size: 16)!,37textColor: .black,38labelFont: UIFont(name: "Optima-Regular", size: 16)!,39labelTextColor: .blue,40expandIndicatorColor: .green)41let entrySelectionCustomization: EntrySelectionCustomization = DefaultEntrySelectionCustomization(42borderWidth: 1,43borderColor: UIColor.blue.cgColor,44cornerRadius: 4,45cornerCurve: .continuous,46font: .systemFont(ofSize: 16),47textColor: .black,48borderStyle: .line,49backgroundColor: .white,50unselectedColor: .white,51selectedColor: .blue)52}