The Checkout.com 3D Secure (3DS) mobile SDK allows you to provide a native 3DS2 experience in your mobile app, with visual styling that you can control.
The SDK handles the device data collection, communication with the card issuer, and presentation of 3D Secure challenges to the customer when required.
- Features
- Minimum Requirements
- Installation
- Integration
- Payment Authorisation
- Dependencies
- Help and Feedback
- License
👉 See the Integration Guide with Code Examples
📚 Read the reference documentation
- Supports 3D Secure protocol 2.2.0.
- Presents native 3DS2 challenge screens to the user, with styling that you can customise to best fit your apps and branding.
- Optionally falls back to 3DS1 when 3DS2 is not available, returning the same authentication result to your app as for 3DS2. (This option can be configured by Checkout.com for your account.)
- Supports a range of local languages and accessibility needs, and allows you to set your own string translations.
- Meets requirements from EMVCo and the PCI Security Standards Council, specifically set for 3DS SDKs, so you can be sure it is interoperable with card issuers and that your customers’ sensitive data stays secure.
- The 3DS SDK for iOS requires Xcode 14.1 and above with Swift version 5.8 and above, and supports apps targeting iOS 12.0 and above. It also supports Objective-C.
- We have discontinued support for intel machines (x86_64 architecture based environments). You must use ARM64 architecture based environments to compile our 3DS iOS SDK.
We've done our best to support the most common distribution methods on iOS. We are in strong favour of SPM (Swift Package Manager) but if for any reason this doesn't work for you, we also support Cocoapods.
Swift Package Manager integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. It should work out of the box on latest Xcode projects since Xcode 11 and has had a lot of community support, seeing huge adoption over the recent years. This is our preferred distribution method for Frames iOS and is the easiest one to integrate, keep updated and build around.
If you've never used it before, get started with Apple's step by step guide into adding package dependencies to your app .
.package(url: "https://github.com/checkout/checkout-3ds-sdk-ios", from: "3.2.5")
CocoaPods is the traditional dependency manager for Apple projects. We still support it, but we're not always able to validate all its peculiar ways.
Make sure cocoapods is installed on your machine by running
$ pod --version
Any version newer than 1.10.0 is a good sign. If not installed, or unsupported, follow Cocoapods Getting Started
Once Cocoapods of a valid version is on your machine, to integrate Frames into your Xcode project, update your Podfile
:
platform :ios, '12.0'
use_frameworks!
target '<Your Target Name>' do
pod 'Checkout3DS', :git => '[email protected]:checkout/checkout-3ds-sdk-ios.git', :tag => '3.2.5'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'i386 x86_64'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end
end
end
Then, run the following command in terminal:
$ pod install
Note: your Pod setup may have the following issue
To update your existing Cocoapod dependencies, use:
$ pod update
Then, configure your app to:
This integration method involves one call to our authenticate
method, which will perform an entire Authentication flow using Checkout.com's 3DS servers.
- Initialize the SDK with your preferred user interface options using our
uiCustomization
object. - Configure the parameters for an authentication.
- Request authentication and handle the result to continue your payment flow.
- The authenticate function now returns
Result
type with two casesAuthenticationResult
withtransactionStatus
andsdkTransactionID
👉 More info about transaction statusAuthenticationError
with amessage
.
// 1. Init with defaults
let checkout3DS = Checkout3DSService()
// 2. Init with explicit arguments
let checkout3DS = Checkout3DSService(
environment: .production,
locale: Locale(identifier: "en_GB"),
uiCustomization: uiCustomization,
appURL: URL(string: "myapp://my-app-url")!
)
let authenticationParameters = AuthenticationParameters(
sessionID: sessionID,
sessionSecret: sessionSecret,
scheme: scheme)
checkout3DS.authenticate(authenticationParameters: authenticationParameters) { result in
switch authenticationResult {
case .success(let authenticationResult):
// handle authentication result. Checkout Payment Authorisation section.
case .failure(let error):
// handle failure scenarios
}
}
👉 See the Integration Guide with Code Examples for full details.
📚 Read the reference documentation
Standalone 3DS allows our SDKs to be used with any Authentication provider, be it Checkout.com or otherwise. This is a higher touch integration that breaks up the 3DS flow more granularly. In order to integrate with the Standalone 3DS service:
- Initialize the SDK with your preferred user interface options using our
uiCustomization
object. - Create
transaction
object - Get
authenticationRequestParameters
for the AReq - If a challenge is mandated from the Authentication response from your 3DS server then call the
doChallenge
method to render the challenge however, if the challenge is not mandated by the ACS then it would have triggered a frictionless 3DS flow.
Here is a useful diagram that highlights the end-to-end 3DS flow using our standalone3DSService
.
1- Creates an instance of ThreeDS2Service
through which the 3DS Requestor App can create a transaction object to get the authenticationRequestParameters
that are required to perform a challenge:
private var transaction: Transaction?
private var standalone3DSService: ThreeDS2Service?
2-Initialize the SDK with your preferred user interface options:
scheme
can be set only asvisa
andmastercard
in lowercase string.
// initialise Standalone 3DS Service with required parameters
do {
let directoryServerData = ThreeDS2ServiceConfiguration.DirectoryServerData(directoryServerID: <directoryServerID>,
directoryServerPublicKey: <ds_public>,
directoryServerRootCertificates: [<caPublic>])
let configParameters = ThreeDS2ServiceConfiguration.ConfigParameters(directoryServerData: directoryServerData,
messageVersion: <messageVersion>,
scheme: <scheme>)
let serviceConfiguration = ThreeDS2ServiceConfiguration(configParameters: configParameters)
self.standalone3DSService = try Standalone3DSService.initialize(with: serviceConfiguration)
} catch let error {
// handle failure scenario
}
- Create
transaction
using createdThreeDS2Service
object:
self.transaction = self.standalone3DSService?.createTransaction()
- Retrieve the
authenticationRequestParameters
:
// get Authentication Request parameters
self.transaction?.getAuthenticationRequestParameters { result in
switch result {
case .success(let params):
// make an Authentication Request to your 3DS Server
case .failure(let error):
// handle failure scenario
}
}
- Handle the
doChallenge
flow:
- If the Authentication response that is returned indicates that the Challenge Flow must be applied, the 3DS Requestor App calls the
doChallenge
method with the required inputChallengeParameters
. ThedoChallenge
method initiates the challenge process. - The
doChallenge
function now returnsResult
type with two casesAuthenticationResult
withtransactionStatus
andsdkTransactionID
👉 More info about transaction statusAuthenticationError
with amessage
.
let params = ChallengeParameters(threeDSServerTransactionID: response.transactionId,
acsTransactionID: response.acs.transactionId,
acsRefNumber: response.acs.referenceNumber,
acsSignedContent: response.acs.signedContent)
transaction?.doChallenge(challengeParameters: params, completion: { [weak self] result in
switch result {
case .success(let authenticationResult):
// handle authentication result. Checkout Payment Authorisation section.
case .failure(let error):
// handle failure scenario
}
// call close and cleanUp methods after challenge flow is completed.
self?.transaction?.close()
self?.standalone3DSService?.cleanUp()
})
- Service
cleanUp
and transactionclose
:
- After a challenge/frictionless flow is completed, you should call:
transaction?.close()
standalone3DSService?.cleanUp()
After initiating the authentication process and obtaining the AuthenticationResult
object, you can continue the authentication flow based on the value of transStatus
:
transStatus |
Description | Proceed with Payment Authorisation Request |
---|---|---|
Y |
Authentication verification successful. | Yes |
A |
Attempt at processing performed. | Yes |
I |
Informational only. | Yes |
N |
Not authenticated or account not verified. | No |
R |
Authentication or account verification rejected. | No |
U |
Authentication or account verification could not be performed. | No |
👉 More info about transaction status
Our iOS SDK depends on some external libraries:
- To help maintain security, we use JOSESwift. To overcome the limitation in Swift Package Manager (SPM) related to binary target dependencies, we've integrated JOSESwift as an xcframework sourced from the same JOSESwift.
- To help provide support and monitor the performance of the SDK, we use our own Checkout Event Logger Kit.
For help using the 3D Secure SDK, or to pass on your feedback, you can email our team at [email protected].
If you’ve found a bug, we encourage you to open an issue through GitHub. If your problem isn’t already listed, please detail the versions of the SDK and your development environment that you’re using, what you were hoping to accomplish, and what the actual result you observed was.
If you have an idea for a new feature, we’d also love to hear about it through GitHub. Please open an issue, detailing your idea and why it’s important for your project.
This software is released under license. See LICENSE for details.