iOS 3DS SDK

Contents:


Introduction

This document serves as a guide for the integrator of Ravelin’s iOS 3DS SDK, providing details on how the SDK should be configured and integrated into an iOS application.


System Requirements and Delivery

Ravelin’s 3DS iOS SDK supports a minimum iOS Version of iOS 12 and the development language used is Swift version 5. The SDK can be used with Objective-C, provided that appropriate bridging is implemented in the host application.


Versioning

The iOS SDK follows semantic versioning - The version can be described as MAJOR.MINOR.PATCH, where:

  • MAJOR - new features
  • MINOR - improvements
  • PATCH - bug / security fix

Supporting documentation

The Ravelin 3D-Secure SDK is built and tested according to the following supporting EMV 3D-Secure documentation. Therefore, this guide should be used in conjunction with the following specifications (n.b. access requires authentication on the EMVCo website):


Integration

This section provides technical details on how to integrate the 3DS SDK into the host application.

Note that the SDK utilises UIKit but it is possible to integrate this into an app using SwiftUI.

Integration options include:

  • Swift Package Manager (SPM)
  • CocoaPods

To assist with integration, simple demo apps can be supplied, these consist of:

  • convenience wrappers intended to illustrate an approach to interfacing with the 3DS SDK
  • a host app, utilising the wrappers

Swift Package Manager Setup

  1. Add the 3DS SDK via SPM/Xcode, a SPM package manifest is available at: git@github.com:unravelin/ravelin-3ds-sdk-ios-xcframework-distribution.git

CocoaPods Setup

  1. Install CocoaPods following the official instructions.

  2. Add Ravelin3DS to the host app’s PodFile:

 pod 'Ravelin3DS', '~> 1.1.2', :source => 'https://github.com/unravelin/Specs.git'
  1. Install the pods using pod install.

Security

There are three primary security goals:

  • Protect sensitive cardholder information while being transferred, being processed, or at rest. A cardholder’s response to an authentication challenge is an example of sensitive cardholder information.
  • Protect sensitive information while being transferred, being processed, or at rest.
  • Control access to the process and information that is used during interactions between the 3DS Requestor App and 3DS SDK.

API Key Setup

An API key is available for use with the SDK. You need to add this in ConfigParameters which are passed upon initialisation of the ThreeDS2Service.


Card Schemes Configuration

The Ravelin 3DS SDK aims to provide an authentication service for payment transactions which involve different Card schemes. Each card scheme provides public keys for device data encryption, a root/mediator keys for to verify signed certificates which arrive from the ACS and the Card scheme logos. In order to comply with the PCI 3DS SDK 1.1v requirements these values cannot be bundled with the SDK. In order to protect this information the Ravelin 3DS SDK fetches this information from a remote host over a secured TLS link protected by an API token. The metadata downloaded from the host is stored in encrypted storage.

The following is a list of card schemes, Ravelin 3DS SDK is certified with:

Card Scheme Directory Server ID
Visa A000000003
Mastercard A000000004
JCB (Japan Credit Bureau) A000000065
CB (Cartes Bancaires) A000000042
Diners Club/Discover A000000152
Amex (American Express) A000000025

Pass an appropriate Directory Server ID value, as directoryServerId, when calling createTransaction(directoryServerId, messageVersion) during Authentication with an argument matching a value from the table above.


Dependencies

The 3DS SDK uses the listed external dependencies which are integrated directly into the SDK; there is no requirement to include these dependencies in any app using the 3DS SDK.

Here you can find a list of these dependencies:

Name Usage Website License Version
JOSESwift a framework supporting the JOSE standards https://github.com/airsidemobile/JOSESwift Apache 2.4.0

Transport Security

The EMVCo 3DS Specification requires the communication between the 3DS SDK and the ACS to be done through HTTPS, but there’s no such requirement when downloading the Payment System and Issuer logo images that the SDK displays in the challenge screens. These URLs are provided as parameters by the ACS in the CRes and it’s expected that they will be HTTPS URLs.

If, however, an insecure HTTP URL is provided, the images will not be downloaded due to Apple’s default policies on insecure network connections. For more information on this, please visit the relevant Apple documentation.


Restricted Device Information Parameters Configuration

Device Information parameters can be set as restricted, which will in turn make the SDK not collect them.

Pass through ConfigParameters. A list of device info parameters and their corresponding IDs can be found in the EMV® 3-D Secure SDK—Device Information Data Version 1.5 documentation.

InvalidInput is thrown if a passed ID doesn’t correspond to any predefined device info parameter.

Using ConfigParameters

By using ConfigParameters.addParam(...), with the following arguments:

paramType: .restrictedDeviceParameters
paramValue: Comma-separated list of device info parameter IDs.

Example:

let configParameters = ConfigParameters()

do {
    try configParameters.addParam(paramType: .restrictedDeviceParameters,
                                  paramValue:"C001,C002,C003,I001,I002")
} catch let error {
    errorHandler(error.localizedDescription)
}

Permissions

This section describes which iOS Permissions should be granted.

Permission Mandatory Description
Location No Used during the device info collection process for better risk calculation. Request permission from the user before calling initialize.

SDK API

The SDK API complies with the API defined by the EMVCo 3DS SDK Specification. This section describes how the SDK can be used to perform 3DS Authentication of payment / non-payment transactions.

Please refer to the iOS 3DS SDK Interface.


Initialization

An instance of ThreeDS2SDK should be created.

let threeDS2Service: ThreeDS2Service = ThreeDS2SDK()

To initialize the SDK, the host application must call the initialize method before the start of the payment stage of a transaction, passing configuration parameters and UI Configuration parameters. You will also need to set an api key by adding a value for the ‘publishableApiKey’ to the ConfigParameters object.

do {
    let threeDS2Service: ThreeDS2Service = ThreeDS2SDK()
    let configParameters = ConfigParameters()
    try configParameters.addParam(paramType: .publishableApiKey,
                                  paramValue:"xxxx...")
    try threeDS2Service.initialize(configParameters: configParameters, uiCustomization: nil)
    //...
} catch ThreeDS2Exception.InvalidInput(let message, _) {
    //...
} catch ThreeDS2Exception.SDKAlreadyInitialized(let message, _) {
    //...
} catch {
    //...
}
Function Argument Description
configParameters Instance of ConfigParameters
uiCustomization Instance of UiCustomization

During initialization, security checks are performed and device information collected. These parameters will be part of Authentication and will be provided to the ACS via 3DS Server for risk analysis. For more details, refer to Security Features.


UI Customisation

The EMV 3DS protocol defines an API for challenge flow UI Customisation. This includes text colour, fonts, background colour, etc. A list of all available methods can be found in Section 4.5 of the 3DS SDK Specification.

For an integrator supporting iOS 13 or later, the iOS SDK has additional methods for setting colour alternatives for dark-mode. The default methods set light-mode colour.

Class Method Description
Customization setDarkTextColor(hexColorCode: String) Sets the dark-mode text colour.
ButtonCustomization setDarkBackgroundColor(hexColorCode: String) Sets the dark-mode background colour.
ButtonCustomization setDarkBorderColor(hexColorCode: String) Sets the dark-mode border colour.
ToolbarCustomization setDarkBackgroundColor(hexColorCode: String) Sets the dark-mode background colour.
LabelCustomization setHeadingDarkTextColor(hexColorCode: String) Sets the dark-mode heading text colour.
TextBoxCustomization setDarkBorderColor(hexColorCode: String) Sets the dark-mode border colour.

The iOS 3DS SDK supports customization of UI elements that are being shown by itself. For configuration, the UiCustomization object is used.

Example:

let uiCustomization = UiCustomization()
let toolbarCustomization = ToolbarCustomization()
try toolbarCustomization.setHeaderText(headerText:"Secure Checkout")
try toolbarCustomization.setBackgroundColor(hexColorCode: "#EC6C2D")
uiCustomization.setToolbarCustomization(toolbarCustomization: toolbarCustomization)
let labelCustomization = LabelCustomization()
try labelCustomization.setHeadingTextFontName(fontName: "NotoSerif")
try labelCustomization.setHeadingTextColor(hexColorCode: "#83ADD7")
uiCustomization.setLabelCustomization(labelCustomization: labelCustomization)

For more detailed information, refer to Section 4.5 in the 3DS SDK Specification.

Integrators supporting iOS 13 and above can take advantage of Dark Mode support. If no UI Customisation colours are provided, then Dark Mode is supported by default. If different UI Customisations are specified, remember to provide dark-mode alternatives for the colours.

The iOS 3DS SDK has an extended API for dark-mode colours to be configured. Every method for setting a colour in the classes for UI Customisation has an additional dark-mode colour setter.

Example:

let buttonCustomization = ButtonCustomization()

try buttonCustomization.setBackgroundColor(hexColorCode: "#000000") // Setting light mode background color.
try buttonCustomization.setDarkBackgroundColor(hexColorCode: "#FFFFFF") // Setting dark mode background color.

Warnings

After security checks are performed, the SDK provides the outcome as list of Warning objects. To obtain the result of these checks, call ThreeDS2Service.getWarnings().

do {
    let sdkWarnings = try threeDS2Service.getWarnings()
} catch ThreeDS2Exception.SDKNotInitialized(let message, _){
    //...
} catch {
    //...
}

Each Warning object has a Severity property with value LOW, MEDIUM or HIGH. It’s up to the integrator to decide what to do with this information. The resulting warnings are also provided as part of Device Info in the Authentication process. For more details, please refer to Security Warnings.


Authentication

The 3DS Authentication flow starts with the Authentication Request that is sent to the 3DS Server, where an AReq is created, forwarded to the relevant DS and further forwarded to the relevant ACS. The ACS then evaluates the data in the AReq and responds with an ARes back to the DS, which comes back to the 3DS Requestor Environment via the 3DS Server.

The SDK generates authentication parameters that should be used to build the Authentication Request. All these parameters should be sent to the 3DS Server. These are made available in the Transaction object.

To obtain an instance of Transaction, call ThreeDS2Service.createTransaction(...):

do {
  try threeDS2Service.createTransaction(directoryServerId: "M000000003", messageVersion: "2.2.0")
} catch {
  // ...
}
Function Argument Description
directoryServerID The Directory Server ID is a Registered Application Provider Identifier (RID) that is unique to the Payment System.
messageVersion 3DS Protocol Version to be used (‘2.1.0’ or ‘2.2.0’). If this value is nil, the highest version supported (‘2.2.0’) will be used.

After the Transaction object has been created, AuthenticationRequestParameters can be obtained by calling Transaction.getAuthenticationRequestParameters().

try {
  let transactionParameters = try transaction.getAuthenticationRequestParameters()
} catch {
  // ...
}

All available AuthenticationRequestParameters are defined in Chapter 4.12 in the EMVCo 3DS SDK Specification.

While the Authentication Request is ongoing, a Processing Screen supplied by the SDK will be shown. To get a reference to the associated ProgressDialog object, use Transaction.getProgressView().

A requirement from the 3DS Specification is that this processing screen should be shown for a minimum of two seconds, regardless of authentication response time or result.


Challenge Flow

If the ACS assesses a transaction as high-risk, it forces the challenge flow onto it. In case of Challenge, the 3DS Requestor calls Transaction.doChallenge(...) and the SDK takes over the Challenge process.

do {
    try transaction.doChallenge(challengeParameters: challengeParamethers,
                                challengeStatusReceiver: challengeStatusReceiver,
                                timeOut:5,
                                challengeView: challengeView)
} catch {
    // ...
}
Function Argument Description
challengeParameters Instance of 2ChallengeParameters, created with values from the Authentication Response.
challengeStatusReceiver Callback object that implements ChallengeStatusReceiver. Through this the application will be notified about the challenge result. The SDK holds a weak reference to this object.
timeOut Timeout interval (in minutes) within which the challenge process must be completed. The minimum value is defined to be 5 minutes.
challengeView An implementation of ChallengeView, providing a view controller onto which the challenge flow will be presented. The SDK holds a weak reference to this view controller.

Once a Challenge has been started, any calls to Transaction.doChallenge(...) or Transaction.close() will result in an SDK Runtime Error, however the challenge flow will not be interrupted.


Requestor App URL

Starting with version 2.2.0 of 3DS, the application integrating the 3DS SDK can be called from another authentication application during an Out-of-Band challenge flow to indicate completed OOB authentication. To use this feature, the requestor application should define its app URL and provide it to the SDK.

This is done by calling the ChallengeParameters.setThreeDSRequestorAppURL(threeDSRequestorAppURL: String) method.

challengeParameters.setThreeDSRequestorAppURL(threeDSRequestorAppURL: "oobScheme://appURL?transID=e8...")

The inclusion of this value in ChallengeParameters is optional. This value will be ignored if provided for an irrelevant version of 3DS (like 2.1.0). The transID query parameter value in the URL must be the same as the current ongoing transaction.


Challenge Flow Results

After invoking Transaction.doChallenge(...), the challenge flow starts and the SDK takes control of the UI. It will get control back when any of the callback methods from ChallengeStatusReceiver are invoked:

class ChallengeStatusReceiver: ChallengeStatusReceiver {

    func completed(completionEvent: CompletionEvent) {
        // Handle successfully or unsuccessful completion of challenge flow
    }

    func cancelled() {
        // Handle challenge canceled by the user
    }

    func timedout() {
        // Handle challenge timeout
    }

    func protocolError(protocolErrorEvent: ProtocolErrorEvent) {
        // Handle protocol error that has been send by the ACS
    }

    func runtimeError(runtimeErrorEvent: RuntimeErrorEvent) {
        // Handle error that has occurred in the SDK at runtime
    }
}

When any of these are invoked, the Challenge is considered as finished. As a result, the SDK dismisses the Challenge screen, closes the transaction, cleans up resources and returns control back to the host application application.


Cleanup

After the 3DS Authentication is finished, the 3DS Requestor should close the Transaction by calling Transaction.close() in order to clear references and avoid memory leaks. When the authentication is done with the Challenge flow, the SDK handles this.

Similarly, in order to free up resources used by ThreeDS2Service, the ThreeDS2Service.cleanup() function can be used. Once an instance of ThreeDS2Service has freed up its resources, it’s in the same state as a newly created ThreeDS2Service and can be used again, however you’ll need to go through initialisation. Create a new Transaction object after initialising the service.


SDK Error Handling

This section covers SDK Errors and their meaning.

Exceptions

The 3DS SDK specification states: the SDK must throw four type of error type:

Exception Description
Invalid input Occurs due to invalid data provided to the SDK.
SDK Already Initialized Occurs when initialize is called on an already initialised ThreeDS2Service object.
SDK Not Initialized Occurs due to attempted usage of an uninitialised ThreeDS2Service object.
SDK runtime error Internal SDK Error. Will contain information describing the error cause more in depth.

Security Features

This section goes into detail about the security aspects concerning the SDK and its integration.

The SDK implements a number of security functions that are defined in the EMVCo 3DS SDK Specification and in PCI 3DS SDK Security Standard.

Security Warnings

During Initialisation, the SDK performs a number of required security checks. These checks may result in warnings that are available to the host application. It’s up to you to act upon these warnings - The SDK will continue to operate as normal should you decide to, for example, ignore them.

Below is a list of the possible warnings:

Code Severity Description
SW01 HIGH Jailbroken device.
SW02 HIGH The SDK has been tampered with.
SW03 HIGH An emulator is being used to run the Application.
SM04 MEDIUM Debugger is attached.
SW05 HIGH Unsupported OS Version.

Secure Communication

The SDK uses several cryptographic methods to secure the communication and transfer of data.

Device Data collected during initialisation is sent to the 3DS Server, which forwards it to the DS and ACS. In order to secure the transmission, the SDK encrypts that data with the DS Public Key in JWE format. The encrypted data can be retrieved by calling AuthenticationRequestParameters.getDeviceData().

After the DS receives this encrypted data, it decrypts it and sends it to the ACS. Using data transferred in the Authentication, the 3DS SDK and ACS exchange keys using the Diffie-Hellman protocol - This establishes the secure channel that is used during the challenge flow.

The Ephemeral Key used for the key exchange is generated by the SDK. It can be retrieved in JWK format by invoking AuthenticationRequestParameters.getSDKEphemeralPublicKey(). This key should be sent in the Authentication Request to the 3DS Server together with the other parameters.

// Setup SDK Authentication Request Parameters
let authRequestParams: try transaction!.getAuthenticationRequestParameters()
let encryptedDeviceInfo = authRequestParams.getDeviceData()
let sdkTransactionId = authRequestParams.getSDKTransactionID()
let sdkEphemeralPublicKey = authRequestParams.getSDKEphemeralPublicKey()
let sdkReferenceNumber = authRequestParams.getSDKReferenceNumber()
let sdkAppID = authRequestParams.getSDKAppID()

Encryption Export Regulations

The SDK and dependencies only make use of cryptographic functions provided as part of the OS, specifically based upon the CommonCrypto library.

Complying with Encryption Export Regulationsd.


iOS 3DS SDK Interface

A complete definition for the 3DS SDK intreface.

ThreeDS2Service

The ThreeDS2Service interface is the main 3DS SDK interface.

The basic steps of the Requestor App are:

// initialize
threeDS2Service = ThreeDS2Service.initialize
warnings = threeDS2Service.getWarnings
evaluate warnings

// authentication
transaction = threeDS2Service.createTransaction
authenticationRequestParameters = transaction.getAuthenticationRequestParameters
authenticationResponse = make AuthenticationRequest with authenticationRequestParameters

// challenge
if authenticationResponse.challengeRequired
    build challengeParameters from authenticationResponse
    transaction.doChallenge(challengeParameters,challengeStatusReceiver)

// handle challenge completion event
challengeStatusReceiver receives an async event:
    completed
    cancelled
    timedout
    error

// cleanup
    transaction.close
    threeDS2Service.cleanup

ThreeDS2Service Interface Details:


public protocol ThreeDS2Service {
    /// Initializes the 3DS SDK instance.
    ///
    /// - Parameters:
    ///   - configParameters: Configuration information to be used during initialization.
    ///   - uiCustomization: UI configuration information that is used to specify the UI layout and theme. For example, font style and font size.
    ///   - completion: as initialize is async, an optional completion handler can be provided
    /// - Throws: InvalidInput, SDKAlreadyInitialized, SDKRuntime
    func initialize(configParameters: ConfigParameters,
                    uiCustomization: UiCustomization?,
                    completion: ((Bool) -> Void)?
                    ) throws

    /// Returns the warnings produced by the 3DS SDK during initialization.
    ///
    /// - Returns: Returns an Array of warnings produced by the 3DS SDK during initialization.
    /// - Throws: SDKNotInitialized.
    func getWarnings() throws -> [Warning]

    /// Returns the version of the 3DS SDK that is integrated with the 3DS Requestor App.
    ///
    /// - Returns: returns (as a string) the version of the 3DS SDK that is integrated with the 3DS
    ///   Requestor App.
    /// - Throws: SDKNotInitialized, SDKRuntime
    func getSDKVersion() throws -> String

    /// Creates an instance of Transaction through which the 3DS Requestor App gets the data that
    /// is required to perform the transaction.
    ///
    /// - Parameters:
    ///   - directoryServerId: Registered Application Provider Identifier (RID) that is unique to
    ///     the Payment System.
    ///   - messageVersion: Protocol version according to which the transaction shall be created.
    /// - Throws: InvalidInput, SDKNotInitialized, SDKRuntime.
    func createTransaction(directoryServerID: String,
                           messageVersion: String?) throws -> Transaction


    /// Frees up resources that are used by the 3DS Requestor App until it is closed.
    ///
    /// - Throws: SDKNotInitialized
    func cleanup() throws

}

ThreeDS2Service - initialize(ConfigParameters, UiCustomization)

The 3DS Requestor App calls the initialize method at the start of the payment stage of a transaction. The app passes configuration parameters and UI configuration parameters.

The following tasks are performed during initialization:

Depending on the 3DS Requestor App implementation, a ThreeDS2Service instance is called either during 3DS Requestor App startup as a background task or when a transaction is initiated.

Once initialized, state is maintained until the cleanup method is called.


ThreeDS2Service - getWarnings() -> Warning

The getWarnings method returns any warnings produced by the 3DS SDK during initialization.


ThreeDS2Service -getSDKVersion() -> String

The getSDKVersion method returns the version of the 3DS SDK that is integrated with the 3DS Requestor App.


ThreeDS2Service - createTransaction(directoryServerID, messageVersion) -> Transaction

The createTransaction method creates an instance of Transaction through which the 3DS Requestor App gets the data that is required to perform the transaction. The 3DS Requestor App calls the createTransaction method for each transaction that is to be processed. When the createTransaction method is called:

  • The 3DS SDK uses the information adhering to the protocol version passed in the optional messageVersion parameter, if it supports the protocol version. If it does not support the protocol version, it generates an InvalidInputException. If the messageVersion parameter is empty or nil, the highest protocol version that the 3DS SDK supports is used. If a challenge flow is triggered for the transaction, the 3DS SDK uses the same protocol version during the challenge process.
  • The 3DS SDK uses a secure random function to generate a Transaction ID in UUID format. This ID is used to uniquely identify each transaction.
  • The 3DS SDK generates a fresh ephemeral key pair. This key pair is used to establish a secure session between the 3DS SDK and the ACS subsequently during the transaction.

ThreeDS2Service - cleanup()

The cleanup method frees up resources that are used by the 3DS SDK.


Transaction

Iimplements the Transaction interface and holds parameters that the 3DS Server requires to create AReq messages and to perform the Challenge Flow.


public protocol Transaction {
    /// Returns device and 3DS SDK information to the 3DS Requestor App.
    ///
    /// - Returns: Returns an AuthenticationRequestParameters object that contains device information and 3DS SDK information.
    /// - Throws: SDKRuntime exception.
    func getAuthenticationRequestParameters()  throws -> AuthenticationRequestParameters

    /// Initiates the challenge process.
    ///
    /// - Parameters:
    ///   - challengeParameters: ACS details required by the 3DS SDK to conduct the challenge
    ///     process during the transaction.
    ///   - challengeStatusReceiver: Callback object for notifying the 3DS Requestor App about the
    ///     challenge status.
    ///   - timeOut: Timeout interval (in minutes) within which the challenge process must be
    ///     completed. The minimum timeout interval shall be 5 minutes.
    ///   - challengeView: implementation of ChallengeView providing a UIViewController
    /// - Throws: Invalid input or SDKRuntime exception.
    func doChallenge(challengeParameters: ChallengeParameters,
                     challengeStatusReceiver: ChallengeStatusReceiver,
                     timeOut: Int,
                     challengeView: ChallengeView) throws

    /// Returns an instance of Progress View (processing screen) that the 3DS Requestor App uses.
    ///
    /// - Returns: Returns a ProgressDialog object.
    func getProgressView() -> ProgressDialog

    /// Cleans up resources that are held by the Transaction object.
    /// - Throws: SDKRuntime exception.
    func close() throws
}

Transaction - getAuthenticationRequestParameters() -> AuthenticationRequestParameters

When the 3DS Requestor App calls the getAuthenticationRequestParameters method, the 3DS SDK encrypts the device information, that it collects during initialization, sends this information, along with the SDK information ,to the 3DS Requestor App. The Requestor App includes this information in its message to the 3DS Server.

The 3DS SDK encrypts the device information by using the DS public key. This key is identified based on the directoryServerID that is passed to the createTransaction method. The 3DS SDK can use A128CBC-HS256 or A128GCM as the encryption algorithm. Refer to 3DS SDK Encryption to DS in EMV 3DS Protocol Specification.

The 3DS SDK generates an ephemeral key pair that is required for subsequent communication with the ACS if a challenge must be applied. For more information, refer to ACS Secure Channel in EMVCo 3DS SDK Specification


Transaction - doChallenge(ChallengeParameters, ChallengeStatusReceiver, timeOut)

If the ARes that is returned indicates that the challenge flow must be applied, the 3DS Requestor App calls the doChallenge method with the required input parameters.

When the doChallenge method is called, control of the app is passed to the 3DS SDK and the SDK initiates the challenge process:

  • starts a time counter to measure the overall time taken by the challenge process.
  • checks if the CA public key (root) of the Directory Server CA (DS-CA) is present, based on the directoryServerID that was passed to the createTransaction method.
  • uses the CA public key of the DS-CA to validate the ACS signed content JWS object. Based on the information included in the JWS object, the algorithm used to perform the validation can be PS256 or ES256.
  • completes the Diffie-Hellman key exchange process according to JWA (RFC 7518) in Direct Key Agreement mode using curve P-256. The output of this process is a pair of CEKs.
  • uses the CEKs to encrypt the CReq messages and decrypt the CRes messages.

For more information about the algorithms used for validation, and the CEKs, refer to the 3DS SDK Secure Channel Set-Up in EMV 3DS Protocol Specification.

The 3DS SDK displays the challenge to the Cardholder. The following steps shall take place during the challenge process,The SDK will:

  • prevent the Cardholder from revisiting the 3DS Requestor App’s current screen (e.g. card details screen) during the challenge process.
  • exchange two or more CReq and CRes messages with the ACS.
  • send the challenge status back to the 3DS Requestor App by using the ChallengeStatusReceiver callback functions.
  • clean up resources that are held by the Transaction object.

If the time taken by the challenge process exceeds the timeout value passed by the 3DS Requestor App(minimum of 5 minutes), the 3DS SDK shall:


Transaction - getProgressView() -> ProgressDialog

The getProgressView method shall return an instance of ProgressDialog associated with a ProgressView, both the view and the association is managed by the SDK. The 3DS Requestor App uses the ProgressDialog.


Transaction - close()

The close method is called to clean up resources that are held by the Transaction object. Note: This method is required to be called only when the doChallenge method is not called in the transaction. The following are some examples of scenarios in which the close method is called:

  • Frictionless transaction.
  • The ACS recommends a challenge, but the Merchant overrides the recommendation and chooses to complete the transaction without a challenge.

Supporting definitions


ConfigParameters

N.B. An instance of ConfigParameters is used to pass a number of parameters to the SDK. The options for these parameters are provided in sample code

/// Represents additional configuration parameters that can be passed to the 3DS SDK during initialization.
public protocol ConfigParameters {
    func addParam(group: String?, paramName: String, paramValue: String?) throws
    func getParamValue(group: String?, paramName: String) throws -> String
    func removeParam(group: String?, paramName: String) throws -> String
    func addParam(paramType: ConfigParamType, paramValue: String?) throws
    func getParamValue(paramType: ConfigParamType) throws -> String
    func removeParam(paramType: ConfigParamType) throws -> String
}
    case publishableApiKey

public enum ConfigParamType {
    case logLevel
    case metaDataHost
    case publishableApiKey
    case restrictedDeviceParameters
    case registeredApplicationProviderIdentifiers
}

UiCustomization

registeredApplicationProviderIdentifiers/// Provides the functionality required for 3DS SDK UI customization.
public protocol UiCustomization {
    func setButtonCustomization(_ buttonCustomization: ButtonCustomization, _ buttonType: ButtonType) throws
    func setButtonCustomization(_ buttonCustomization: ButtonCustomization, _ buttonType: String) throws
    func setToolbarCustomization(_ toolbarCustomization: ToolbarCustomization) throws
    func setLabelCustomization(_ labelCustomization: LabelCustomization) throws
    func setTextBoxCustomization(_ textBoxCustomization: TextBoxCustomization) throws
    func getButtonCustomization(_ buttonType: ButtonType) throws -> ButtonCustomization
    func getButtonCustomization(_ buttonType: String) throws -> ButtonCustomization
    func getToolbarCustomization() throws -> ToolbarCustomization
    func getLabelCustomization() throws -> LabelCustomization
    func getTextBoxCustomization() throws -> TextBoxCustomization
}

/// Provides methods to pass UI customization parameters to the 3DS SDK.
public protocol Customization {
    func setTextFontName(_ fontName: String) throws
    func setTextColor(_ hexColorCode: String) throws
    func setTextFontSize(_ fontSize: Int) throws
    func getTextFontName() -> String
    func getTextColor() -> String
    func getTextFontSize() -> Int
}

public enum ButtonType {
    case SUBMIT
    case CONTINUE
    case NEXT
    case CANCEL
    case RESEND
}

public protocol ButtonCustomization: Customization {
    func setBackgroundColor(_ hexColorCode: String) throws
    func setCornerRadius(_ cornerRadius: Int) throws
    func setBorderWidth(_ borderWidth: Int) throws
    func setBorderColor(_ hexColorCode: String) throws
    func getBackgroundColor() -> String
    func getCornerRadius() -> Int
    func getBorderWidth() -> Int
    func getBorderColor() -> String
}

public protocol ToolbarCustomization: Customization {
    func setBackgroundColor(_ hexColorCode: String) throws
    func setHeaderText(_ headerText: String) throws
    func getBackgroundColor() -> String
    func getHeaderText() -> String
}

public protocol LabelCustomization: Customization {
    func setHeadingTextColor(_ hexColorCode: String) throws
    func setHeadingTextFontName(_ fontName: String) throws
    func setHeadingTextFontSize(_ fontSize: Int) throws
    func getHeadingTextColor() -> String
    func getHeadingTextFontName() -> String
    func getHeadingTextFontSize() -> Int
}

public protocol TextBoxCustomization: Customization {
    func setBorderWidth(_ borderWidth: Int) throws
    func setBorderColor(_ hexColorCode: String) throws
    func setCornerRadius(_ cornerRadius: Int) throws
    func getBorderWidth() -> Int
    func getBorderColor() -> String
    func getCornerRadius() -> Int
}

Warning

Warning represents a warning that is produced by the 3DS SDK while performing security checks during initialization.


public protocol Warning {
    /// Return the warning ID
    ///
    /// - Returns: The warning ID as a string.
    func getID() -> String
    /// Returns the warning message.
    ///
    /// - Returns: The warning message as a string.
    func getMessage() -> String
    /// Return the severity level of the warning produced by the 3DS SDK.
    ///
    /// - Returns: The severity level of the warning as a Severity enum type.
    func getSeverity() -> Severity
}

/// Severity levels of warnings produced by the 3DS SDK while conducting security checks during initialization.
/// - LOW:  A low-severity warning
/// - MEDIUM:  A medium-severity warning
/// - HIGH:  A high-severity warning
public enum Severity {
    case LOW
    case MEDIUM
    case HIGH
}

AuthenticationRequestParameters

Parameters that the Requsteror App passes to the 3DS Server when creating the AReq


public protocol AuthenticationRequestParameters {
    func getDeviceData() -> String
    func getSDKTransactionID() -> String
    func getSDKAppID() -> String
    func getSDKReferenceNumber() -> String
    func getSDKEphemeralPublicKey() -> String
    func getMessageVersion() -> String
}

ChallengeParameters

Parameters that are required to conduct the challenge process; it is mandatory to set values for these parameters.


public protocol ChallengeParameters {
    func set3DSServerTransactionID(_ transactionID: String)
    func setAcsTransactionID(_ transactionID: String)
    func setAcsRefNumber(_ refNumber: String)
    func setAcsSignedContent(_ signedContent: String)
    func setThreeDSRequestorAppURL (_ threeDSRequestorAppURL : String)

    func get3DSServerTransactionID() -> String
    func getAcsTransactionID() -> String
    func getAcsRefNumber() -> String
    func getAcsSignedContent() -> String
    func getThreeDSRequestorAppURL() -> String
}

ChallengeStatusReceiver

A callback object that implements the ChallengeStatusReceiver interface to receive challenge status notifications from the 3DS SDK at the end of the challenge process. Depending on the result of the challenge process, the 3DS Requestor App may display a message or redirect the cardholder to a screen in the app.


public protocol ChallengeStatusReceiver {
    func completed(_ completionEvent: CompletionEvent)
    func cancelled()
    func timedout()
    func protocolError(_ protocolErrorEvent: ProtocolErrorEvent)
    func runtimeError(_ runtimeErrorEvent: RuntimeErrorEvent)
}

ProgressDialog

Protocol defining functions to control the progress view.


public protocol ProgressDialog  {
    /// Start the progress dialog
    func start()
    /// Stop the progress dialog
    /// As required by the 3DS specification, after a call to stop() the progress dialog, the indicator will continue until it has been displayed for a minimum of 2 seconds.
    func stop()
}

Events & Errors


public protocol CompletionEvent {
    func getSDKTransactionID() -> String
    func getTransactionStatus() -> String
}

public protocol ErrorMessage {
    func getTransactionID() -> String
    func getErrorCode() -> String
    func getErrorDescription() -> String
    func getErrorDetails() -> String
}

public protocol ProtocolErrorEvent {
    func getErrorMessage() -> ErrorMessage
    func getSDKTransactionID() -> String
}

public protocol RuntimeErrorEvent {
    func getErrorCode() -> String?
    func getErrorMessage() -> String
}

Feedback