Netcetera 3DS SDK API

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

ObjC class prefixes

To avoid conflicts of class/protocol names when using the SDK in ObjectiveC, all public classes and protocols of the SDK are prefixed with ‘NCA’. Note: This is only valid for ObjectiveC

Example: NCAThreeDS2ServiceSDK NCATransaction NCAToolbarCustomization …

Instantiation

First an istance of ThreeDS2ServiceSDK should be created. When creating the ThreeDS2ServiceSDK object, two constructors are available. One with a bundle argument and one without. The default value is Bundle.main. In case you want to specify a seperate bundle for resources, pass the value using the ThreeDS2ServiceSDK(bundle:Bundle) constructor.

1
2
3
4
5
/// The bundle from which the SDK will read resources is Bundle.main
let threeDS2Service: ThreeDS2Service = ThreeDS2ServiceSDK()
 
/// Pass the bundle from which the SDK will read resources
let threeDS2Service: ThreeDS2Service = ThreeDS2ServiceSDK(bundle: bundle)

UICustomization

The 3DS SDK 2.0 Protocol defines API with classes and methods to customize the UI that is shown to the user during the challenge flow. This includes, text color, fonts, background color etc. A list of all methods is available in section 4.5 in the EMVCo 3DS SDK Specification.

Additionally, for every integrator supporting iOS 13 and later, Netcetera iOS 3DS SDK has additional methods for setting color alternatives for dark mode. The default methods set light mode color.

Class Method Description
Customization setDarkTextColor(hexColorCode: String) Sets the dark mode text color
as hex string value
ButtonCustomization setDarkBackgroundColor(hexColorCode: String) Sets the dark mode background color
as hex string value
ToolbarCustomization setDarkBackgroundColor(hexColorCode: String) Sets the dark mode background color
as hex string value
LabelCustomization setHeadingDarkTextColor(hexColorCode: String) Sets the dark mode heading text color
as hex string value
TextBoxCustomization setDarkBorderColor(hexColorCode: String) Sets the dark mode border color
as hex string value

Initialization

The 3DS Requestor App calls the initialize method at the start of the payment stage of a transaction. The app passes configuration parameters, UI configuration parameters, and user locale to this method. Until the ThreeDS2Service instance is initialized, it is unusable.

In order to use the ThreeDS2Service for further actions, initialize it with ThreeDS2Service.initialize(...) method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
do {
    let threeDS2Service: ThreeDS2Service = ThreeDS2ServiceSDK()
    let configParameters = ConfigParameters()
    try configParamethers.setLicenseKey(licenseKey: "ey...")
    try threeDS2Service.initialize(configParameters,
                                   locale: nil,
                                   uiCustomization: nil)
    //...
} catch ThreeDS2Error.InvalidInput(let message, _) {
    //...
} catch ThreeDS2Error.SDKAlreadyInitialized(let message, _) {
    //...
 
} catch {
    //...
 
}
Parameter Description
configParameters Instance of ConfigParameters. Before passing this parameter set the licence as described in License Setup
locale String that represents the locale for the app’s user interface.
uiCustomization Instance of UiCustomization created during SDK Configuration.

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

Fore more details about the security checks and their handling, refer to Security Features.

For more details on the device data that is collected, refer to EMVCo 3DS SDK Device Info Specification.

Warnings

After the security checks are performed, the SDK provides the outcome as list of Warning.

To obtain the result of these security checks call ThreeDS2Service.getWarnings().

1
2
3
4
5
6
7
do {
    let sdkWarnings = try threeDS2Service.getWarnings()
} catch ThreeDS2Error.SDKNotInitialized(let message, _){
    //...
} catch {
    //...
}

Each of the resulting Warning has Severity with value of LOW, MEDIUM and HIGH and it is up to the integrator to decide whether to act on each of them. For more details, please refer to Security Warnings.

The resulting warnings will be provided as part of Device Info in the Authentication.

Authentication

The 3DS Authentication flow starts with the authentication request that the 3DS Requestor Environment (Application or Library) sends it to the 3DS Server. The 3DS Server uses the data to compose the AReq that is sent to the DS and further forwarded to the appropriate ACS.

The ACS evaluates the data provided in the AReq and responds with ARes message to the DS, which then forwards the message to the 3DS Server. At the end the 3DS Server communicates the result of the ARes message back to the 3DS Requestor Environment.

The 3DS SDK generates authentication parameters that should be used for building the initial Authentication Request. All these parameters should be send to the 3DS Server, in the format the 3DS Server API defines. This parameters can be retrieved from Transaction object.

To obtain instance of Transaction, ThreeDS2Service.createTransaction(...) method can be used.

1
2
3
4
5
6
7
do {
  let directoryServerId = //...
  try threeDS2Service.createTransaction(directoryServerId: directoryServerId,
                                           messageVersion: "2.1.0")
} catch {
  // ...
}
Parameter Description
directoryServerID The ID of the Directory Server that will be used. Make sure there is already configuration for this DS made in DS Configuration.
messageVersion Protocol version according to which the transaction shall be created. If null highest supported value will be used.

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

1
2
3
4
5
try {
  let transactionParameters = try transaction.getAuthenticationRequestParameters()
} catch {
  // ...
}

The parameters that are part of the 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 3DS SDK shall be shown. To get instance of this processing screen use Transaction.getProgressView(...). For better user experience, one requirement from EMVCo 3DS Specification is that this processing screen shall be shown for minimum of two seconds, regardless of the authentication response time or result.

This requirement shall be implemented by the 3DS SDK integrator. For example, reference the Netcetera Demo Merchant application.

Starting of Challenge Flow

If the ACS assesses the transaction as high-risk, above certain threshold or that it requires higher level of authentication, it forces the Challenge Flow communication.

In case of Challenge Flow, the 3DS Requestor calls Transaction.doChallenge(...),` and the SDK takes over the Challenge process.

1
2
3
4
5
6
7
8
do {
    try transaction.doChallenge(challengeParameters: challengeParamethers,
                                challengeStatusReceiver: challengeStatusReceiver,
                                timeOut:5,
                                inViewController: viewController)
} catch {
    // ...
}

Once a challenge has been started, invocation on Transaction.doChallenge(...) and Transaction.close() will result in SDK Runtime Error, but the Challenge Flow won’t be interrupted nor the Transaction will be put in invalid state. Once any result comes through the ChallengeStatusReceiver, calling of Transaction.doChallenge(...) and Transaction.close() is allowed if required.

Parameter Description
challengeParameters Instance of ChallengeParameters created with values from the Authentication Response.
challengeStatusReceiver Callback object that implements ChallengeStatusReceiver. It will be notified about the challenge status.
timeOut Timeout interval (in minutes) within which the challenge process must be completed. The minimum timeout interval is defined to be 5 minutes.
inViewController The view controller in which the challenge flow will be presented modally. This must not be a view controller that is presented. A presented view controller cannot present another view controller, so make sure the method is called with a correct parameter, otherwise the challenge view will not be shown.

Requestor App URL

Starting with version 2.2.0 of the EMV 3DS Specification Protocol, the application (requestor) integrating the 3DS SDK can be called from another (authentication) application during an OOB challenge flow to indicate completed OOB authentication. To use this feature, the requestor application should define its app url and provide it to the 3DS SDK.

The app url can be provided to the 3DS SDK in the challenge parameters via the setThreeDSRequestorAppURL(threeDSRequestorAppURL: String) method.

1
challengeParameters.setThreeDSRequestorAppURL(threeDSRequestorAppURL: "merchantScheme://appURL?transID=b2385523-a66c-4907-ac3c-91848e8c0067")

This URL can either be URL scheme defined by the application or universal link that will open it. The inclusion of this value in the challenge parameters is optional. If the app url is provided for irrelevant version of the 3DS Specification Protocol (example version 2.1.0), the 3DS SDK ignores it.

For further information on how to define the threeDSRequestorAppURL value, you can check the EMVCo 3DS Specification.

If the threeDSRequestorAppURL is set and the app is opened with this url in 2.2.0 transactions the OOB flow automatically continues. The transID query parameter in the URL must be the same as the current ongoing transaction. In this case the SDK knows that the authentication for that transaction did finish and can automatically send challenge request to the ACS.

In iOS the handling of events when the app was opened from a URL scheme or universal link is done in the main application delegate. In order for the SDK to be able to catch these events, the main application delegate needs to call the appropriate methods from ThreeDSSDKAppDelegate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
 
    var window: UIWindow?
 
    // ...
     
    func application(_ app: UIApplication,
                     open url: URL,
                     options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return ThreeDSSDKAppDelegate.shared.appOpened(url: url)
    }
     
    func application(_ application: UIApplication,
                     continue userActivity: NSUserActivity,
                     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        return ThreeDSSDKAppDelegate.shared.appOpened(userActivity: userActivity)
    }
}

As an example on how to use and handle the app url on the application side, you can refer to Netcetera Demo Merchant application.

Challenge Flow Results

After invoking Transaction.doChallenge(...), Challenge Flow is started and the control of the UI is handed over to the 3DS SDK. The DS Requestor has the controls back when any of the callback methods from the ChallengeStatusReceiver are invoked.

Implement a class that conform to the ChallengeStatusReceiver protocol.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class AppChallengeStatusReceiver: 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 the callback methods of the ChallengeStatusReceiver are invoked, the challenge flow is considered finished. As a result, the 3DS SDK dismisses the challenge screen, closes the transaction, cleans up resources and gives the 3DS Requestor control over the UI.

Closing of the Transaction

After the 3DS Authentication has finished with frictionless flow, the 3DS Requestor should close the Transaction by calling Transaction.close() in order to clear references and avoid possible memory leaks. When the authentication is done with challenge flow, the closing of the transaction is done by the SDK when the challenge flow authentication finishes.

Cleanup of the ThreeDS2Service

Similar to closing Transaction, in order to free up resources which are used by the ThreeDS2Service, the ThreeDS2Service.cleanup() shall be used. Once an instance of ThreeDS2Service has freed up the used resources, it is in the same state as newly created ThreeDS2Service and can be used once again, but should go through Initialization again. After the ThreeDS2Service.cleanup() has been performed, previously created Transaction objects are in invalid state and shall not be used anymore. It is recommended to always create new transaction object, after initializing the service.

Error handling

According to the EMVCo 3DS SDK Specification, the Netcetera iOS 3DS SDK throws a messaging error whenever a problem occurs. There are four types of errors which are thrown by the SDK.

  • Invalid input - Represents an error which occurs due to invalid parameters provided to the 3DS SDK.
  • SDK not initialized - Represents error that is caused when calling ThreeDS2Service method that requires it to be initialized, but it has not yet been initialized.
  • SDK already initialized - Represents error that is caused when initializing the ThreeDS2Service instance, but it has been already initialized.
  • SDK runtime error - Represents an error that is thrown when an internal error is encountered by the 3DS SDK.

In case of a problem, the integrator of the Netcetera 3DS SDK is provided with an appropriate error. All these errors are returned as an NSError object. The information that can be retrieved from the error object are:

Information Description
error.localizedDescription Message explaining the error
error.code The code of the error
error.localizedFailureReason Additional error code that gives more detailed information of the error