Getting Started with the 3DS SDK

/n software 3-D Secure includes an EMVCo Certified 3DS SDK that can be used to support 3-D Secure V2 authentication natively in a mobile application. This SDK is built according to the 3DS V2 (2.1.0, 2.2.0) specification released by EMVCo. This specification, as well as more information on 3-D Secure V2 in general, can be found on the EMV 3-D Secure website. The following sections provide guidance on getting started with the /n software 3DS SDK.

Demo applications are included with the SDK for both Android and iOS. These communicate with a test server, and can be helpful in seeing the 3DS SDK in action, and how it fits in to a mobile application project.

Contents

Getting Started in Android

To begin add the ipworks3ds_sdk.aar to your app:

  1. Copy the ipworks3ds_sdk.aar to the /libs folder in your module.
  2. Import the SDK by adding this line to your module build.gradle file:
    implementation(name: 'ipworks3ds_sdk', ext: 'aar')

Initializing the SDK

Before being used, the SDK must be initialized via the initialize method. Depending on the 3DS Requestor application implementation, a ThreeDSService instance is created either during startup of the 3DS Requestor app (as a background task), or when a transaction is initiated. The state of the service is maintained until the cleanup method is called. The initialize method can be called like so:

ThreeDS2Service.INSTANCE.initialize(getApplicationContext()),
									configParameters,
									locale,
									uiCustomization,
									newMyClientEventListener());

The parameters this initialize method takes are as follows:

Name Type Description
applicationContext Context An instance of Android application context. For example, using the getApplicationContext method.
configParameters ConfigParameters Configuration information that shall be used during initialization. For details, see the ConfigParameters section.
locale String A string that represents the locale for the app's user interface (e.g. "en-US"). For future use.
uiCustomization UiCustomization UI configuration information that is used to specify the UI layout and theme (fonts, colors, etc.) For details, see the UiCustomization section.
clientEventListener ClientEventListener A listener to hook in to SDK events (for logging, etc.) For details, see the ClientEventListener section.

Config Parameters

The ConfigParameters class is used to provide details required by the 3DS SDK for initialization. The ConfigParameters.Builder class helps with organizing these parameters which can be used as follows:

List<ConfigParameters.DirectoryServerInfo> directoryServerInfoList = new ArrayList<>();
directoryServerInfoList.add(new ConfigParameters.DirectoryServerInfo(DSInfo.TEST_DS_ID, DSInfo.TEST_DS_CERT, DSInfo.TEST_DS_CA));

List<String> deviceParameterBlacklist = new ArrayList<>();
	deviceParameterBlacklist.add("A009");
	deviceParameterBlacklist.add("A010");	

List<String> maliciousApps = new ArrayList<>();
	maliciousApps.add("de.robv.android.xposed");

List<String> trustedAppStores = new ArrayList<>();
	trustedAppStores.add("com.xiaomi.market");

String appsignature = ParseAppSignature(HTTP.Get("https://www.example.com/signature"));

List<String> clientConfigs = new ArrayList<>();
	clientConfigs.add("logLevel=3");
	clientConfigs.add("MaskSensitive=false");

ConfigParameters configParameters = new ConfigParameters.Builder(directoryServerInfoList, runtimeLicense)
	.deviceParameterBlacklist(deviceParameterBlacklist)
	.maliciousApps(maliciousApps)
	.trustedAppStores(trustedAppStores)
	.appSignature(appsignature)
	.clientConfig(clientConfigs)
	.build();

Parameters fall into a few groups:

Name Type Description
DirectoryServerInfo DirectoryServerInfo Used to add keys and certificates for different directory servers.
RuntimeLicense String The 3DS SDK license string.
DeviceParameterBlacklist List<String> A list of device parameters NOT to pull from the device. By default, the SDK will pull as many device parameters as it can. This setting group can be used to instruct the SDK not to pull certain parameters. You can add parameters to this list by specifying the identifier. A full list of parameters can be found in the EMV® 3-D Secure SDK Device Information document, which can be obtained from EMVCo directly.
MaliciousApps List<String> Apps that are recognized as malicious. If the apps are installed, a security warning (SW02) will be raised. There are some default malicious apps configured by default:
  • de.robv.android.xposed
  • de.robv.android.xposed.installer
  • com.saurik.substrate
TrustedAppStores List<String> A security warning (SW02) will be raised if the app is not installed from a trusted app store. By default, the Google Play Store (com.android.vending) is trusted. This parameter can be used to specify additional trusted app stores.
AppSignature List<String> A security warning (SW02) is raised if this value does not match the app signature. This property should be set to the SHA256 fingerprint of the certificate used to sign the app. If this value is not specified, the SDK will see the signature as invalid. Note that this value should not be hardcoded in the app for security reasons. The user should store the app signature on their server, retrieve it, and set it here.
ClientConfig List<String> Configuration settings used for additional configuration of the SDK. A list of available options can be found in the ClientConfig section.

UI Customization

Should the 3DS Requestor wish to have its own look-and-feel in the challenge pages, the UiCustomization class is used. This class allows the customization of Buttons, Labels, TextBoxes, and Toolbars. For example, the following will configure buttons with dark red backgrounds and white font:

UiCustomization uiCustomization = new UiCustomization();
ButtonCustomization customButton = new ButtonCustomization();
customButton.setTextColor("#FFFFFF"); // White
customButton.setBackgroundColor("#951728"); // Dark red
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.CANCEL);
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.CONTINUE);
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.NEXT);
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.RESEND);
uiCustomization.setButtonCustomization(customButton, UiCustomization.ButtonType.SUBMIT);

Here is the resulting Submit button for a Single-Select challenge:

Custom Submit Button

Icon Customization

Along with the customization of the look-and-feel of the UI via the UiCustomization class detailed above, it may be desirable to also customize the images utilized by the SDK. There are three images used by the Android SDK for this, and they can be customized by including files with the exact names listed below in the drawable resources section of the project:

  • ipworks3ds_expand_section_indicator: The icon used to indicate a section that can be expanded.
  • ipworks3ds_collapse_section_indicator: The icon used to indicate a section that can be collapsed.
  • ipworks3ds_warning_indicator: The icon used (as indicated by the ACS) to draw attention to challenge information text being displayed.

If these images are included in the project, the SDK will use them automatically; no additional code or configuration is required.

ClientEventListener

The ClientEventListener object exposes a number of events that are fired at certain points during the SDK's operation. Below is a list of the available events:

DataPacketIn

Fired when receiving a data packet from the server.

public class MyClientEventListener implements ClientEventListener {
	...
  	public void fireDataPacketIn(byte[] dataPacket) {
		Log.i("ClientDataPacketIn", new String(dataPacket));
  	}
  	...
}

This event fires when a packet is received. The entire data packet (including all framing and error detection characters) is contained in the dataPacket parameter. This parameter may be inspected for advanced troubleshooting, or to extract additional response properties beyond the scope of this component.

DataPacketOut

Fired when sending a data packet to the server.

public class MyClientEventListener implements ClientEventListener {
	...
	public void fireDataPacketOut(byte[] dataPacket) {
		Log.i("ClientDataPacketOut", new String(dataPacket));
	}
	...
}

This event fires right before each data packet is sent. The entire data packet (including all framing and error detection characters) is contained in the dataPacket parameter. This parameter may be inspected for advanced troubleshooting.

Log

Fires once for each log message.

public class MyClientEventListener implements ClientEventListener {
	...
	public void fireLog(int logLevel, String message, String logType) {
		Log.i("ClientLog", logType + " - " + message);
	}
	...
}

Logging is handled through the Log event. This will fire any time a message is built or a response is parsed, including error messages.

When the Log event is fired, the message in question is made available via the message event parameter. The other event arguments are logType and logLevel.

The logType parameter indicates the type of the log entry. Possible values are:

  • Info
  • RequestHeaders
  • ResponseHeaders
  • RequestBody
  • ResponseBody
  • ProxyRequest
  • ProxyResponse
  • FirewallRequest
  • FirewallResponse
  • CReq
  • CRes
  • Erro
  • EphemeralKey
  • DeviceParams
The LogLevel configuration setting can be used to specify the detail of the logs raised through the Log event. The logLevel parameter in the event indicates the log level to which the current message belongs. Possible values are:

  • 0 - None
  • 1 - Info
  • 2 - Verbose
  • 3 - Debug

The LogLevel is initially specified in the Client Config settings.

It is recommended to output all messages raised in this event to a file for record keeping purposes, or for later debugging issues that may have come up.

SSLServerAuthentication

Fired after the server presents its certificate to the client.

public class MyClientEventListener implements ClientEventListener {
	...
	public void fireSSLServerAuthentication(byte[] certEncoded, String certSubject, String certIssuer, String status, boolean[] accept) {
		//...
	}
	...
}

This event is where the client can decide whether to continue with the connection process or not. The accept parameter is a recommendation on whether to continue or close the connection. This is just a suggestion: application software must use its own logic to determine whether to continue or not.

When accept is False, status shows why the verification failed (otherwise, status contains the string "OK"). If it is decided to continue, you can override and accept the certificate by setting the accept parameter to True.

SSLStatus

Shows the progress of the secure connection.

public class MyClientEventListener implements ClientEventListener {
	...
	public void fireSSLStatus(String message) {
		Log.i("ClientSSLStatus", message);
	}
	...
}

The event is fired for informational and logging purposes only. Used to track the progress of the connection.

Client Config

The SDK accepts one or more of the following configuration settings. These are set as SETTING=VALUE pairs, and set as the clientConfig when building the ConfigParameters.

LogLevel

This config specifies the level of logging enabled in the component. Possible values include:

  • 0 (None) No events are logged.
  • 1 (Info - default) Informational events are logged.
  • 2 (Verbose) Detailed data is logged.
  • 3 (Debug) Debug data is logged.

The LogLevel is initially specified in the Client Config settings.

MaskSensitive

This setting controls whether sensitive data is masked in the Log event. When set to True (default) the card number value will be replaced with the value *************.

Note: DataPacketOut will always contain the raw unmasked value regardless of this setting. This setting only applies to the Log event.

The default value is True.

Security Checks

The SDK performs security checks and collects device information during initialization. Warnings produced during the 3DS SDK initialization process can be retrieved using the getWarnings method, which returns a list of Warning objects. These can be checked by the app to determine whether or not to proceed with the checkout process:

/* check warnings */
List<Warning> warnings = ThreeDS2Service.INSTANCE.getWarnings();
if (warnings.size() > 0) {
	// process warnings
	// abort the checkout if necessary
}

The Warning object consists of the following fields:

Name Type Description
id String Warning identifier.
message String Warning message.
severity Severity (enum) Warning severity level (LOW, MEDIUM, HIGH).

The following warnings are documented in the EMVCo specification:

Security Warning ID Description Severity Level
SW01 The device is jailbroken. HIGH
SW02 The integrity of the SDK has been tampered. HIGH
SW03 An emulator is being used to run the app. HIGH
SW04 A debugger is attached to the app. MEDIUM
SW05 The OS or the OS version is not supported. HIGH

Creating a Transaction

Call the createTransaction method to start a transaction. A reference should be kept for this transaction throughout the entire 3-D Secure process. This method takes the directory server ID, which points to a DirectoryServerInfo configuration parameter added during SDK initialization. The second parameter is a protocol version as a string. Supported version strings are 2.1.0 and 2.2.0.

sdkTransaction = ThreeDS2Service.INSTANCE.createTransaction(DSInfo.TEST_DS_ID, "2.2.0");

Later, when the transaction is complete, it should be closed via the Transaction object's close method.

Displaying Progress

A progress dialog must be displayed to the end user at certain points in the 3-D Secure process. While performing the challenge, the 3DS SDK will automatically display a progress dialog when appropriate.

A progress dialog must also be displayed to the user while the application is communicating with the 3DS Server and waiting for the authentication request results. The dialog used by the 3DS SDK is available to be used by the application if desired, and can be obtained from the Transaction object via the getProgressView method like so:

// The progress dialog is an instance of android.app.ProgressDialog
ProgressDialog sdkProgressDialog;

// Retrieve the progress dialog from the transaction object instance
sdkProgressDialog = sdkTransaction.getProgressView(mActivity);
sdkProgressDialog.show();

// Later, to hide/dismiss:
sdkProgressDialog.dismiss();

The 3DS SDK will automatically hide the dialog when starting the challenge process, so there is no need to explicitly dismiss the dialog in the application code.

Authenticating

The authentication process starts with a call to the Transaction object's getAuthenticationRequestParameters method. When this method is called, the 3DS SDK will encrypt the device information it collected during initialization and make it, along with other SDK information required by the 3DS Server, available in the returned AuthenticationRequestParameters object. This AuthenticationRequestParameters object consists of the following fields:

Name Description
SDKTransactionId A transaction identifier randomly generated by the SDK.
DeviceData Device data collected by the SDK during initialization and encrypted using the DS key.
SDKEphemeralPublicKeyThe public key component of the ephemeral key pair generated by the SDK.
SDKAppId A UUID value, generated by the 3DS SDK, that uniquely identifies the app on the device.
SDKReferenceNumber Assigned to our SDK by EMVCo after certification.
MessageVersion From createTransaction, or a default value from the SDK (2.1.0).
AuthRequest Packaged authentication request data to be sent to the 3DS Server.

The AuthRequest property is a packaged form of the other properties. The app would transmit this to the 3DS Server via a communication channel outside the scope of the 3DS SDK itself. On the server side, this AuthRequest data is designed to be passed directly in to the 3DS Server component's ClientAuthRequest property prior to sending the authentication request to the directory server via its SendAuthRequest method.

When the SendAuthRequest method completes, the Server component's ClientAuthResponse property will contain data that can be sent back to the app and passed to the 3DS SDK to use if a challenge is required.

Response Handling

The 3DS Server is responsible for reading the authentication response from the directory server and indicating to the client (in this case, the app) whether or not a challenge is required. In our 3DS Server component, check the TransactionStatus property after the SendAuthRequest method completes. If this is a value of C or D, a challenge is required.

If no challenge is required (frictionless flow), or authentication cannot be performed for some reason, no further action is required from a 3-D Secure standpoint. Proceed to the Completing Authentication section for details on closing the transaction.

If a challenge is required, the 3DS Server should return the ClientAuthResponse property value to the app for use when starting the challenge process. The Performing a Challenge section details how to perform the challenge.

Performing a Challenge

If a challenge is required, the challenge is performed by creating the ChallengeParameters (using the ClientAuthResponse from the 3DS Server component) and calling the doChallenge method. The SDK will take care of all communication with the ACS while performing the challenge, as well as prompting the user as needed for the required input. When the challenge process is complete, the relevant ChallengeStatusReceiver callback method will fire.

Challenge Status Receiver

ChallengeStatusReceiver is an interface that should be implemented in the application and passed to the doChallenge method when Starting the Challenge. When the challenge process has finished, either successfully or in error, one of the following corresponding methods will be called:

Name Description
completed Called when the challenge process (that is, the transaction) is completed. When a transaction is completed, a transaction status shall be available.
cancelled Called when the cardholder selects the option to cancel the transaction on the challenge screen.
timedout Called when the challenge process reaches or exceeds the timeout interval that is specified during the doChallenge call.
protocolErrorCalled when the 3DS SDK receives an EMV 3-D Secure protocol-defined error message from the ACS.
runtimeError Called when the 3DS SDK encounters errors during the challenge process. These errors include all errors except those covered by the protocolError method.

Example implementations of these methods can be found below:

@Override
public void completed(CompletionEvent completionEvent) {
	showToast("Challenge completed with transactionStatus " + completionEvent.getTransactionStatus());
	closeTransaction();
}

@Override
public void cancelled() {
	showToast("Challenge cancelled.");
	closeTransaction();
}

@Override
public void timedout() {
	showToast("Challenge timed out.");
	closeTransaction();
}

@Override
public void protocolError(ProtocolErrorEvent protocolErrorEvent) {
	showToast("Challenge protocolError: " +
		protocolErrorEvent.getErrorMessage().getErrorDescription() + "\t" +
		protocolErrorEvent.getErrorMessage().getErrorDetails());
}

@Override
public void runtimeError(RuntimeErrorEvent runtimeErrorEvent) {
	showToast("Challenge runtimeError: " + runtimeErrorEvent.getErrorMessage());
}

Challenge Parameters

The ChallengeParameters class holds parameters that are required to conduct the challenge process. This is passed to the doChallenge method when Starting the Challenge. Available properties, accessible via getters and setters, are:

Name Type Description
3DSServerTransactionID String 3DS Server Transaction ID.
AcsTransactionID String ACS Transaction ID.
AcsRefNumber String ACS Reference Number.
AcsSignedContent String ACS signed content. This data includes the ACS URL, ACS ephemeral public key, and SDK ephemeral public key.
ThreeDSRequestorAppURL String 3DS Requestor App URL.
ThreeDSServerAuthResponse String The Authentication Response from the 3DS Server component.

These properties can be set individually based on what comes back from the 3DS Server. If using the 3DS Server component, the ThreeDSServerAuthResponse can be set to the generated ClientAuthResponse value, and the other properties will be set automatically based on this value.

ChallengeParameters challengeParameters = new ChallengeParameters();
	challengeParameters.setThreeDSServerAuthResponse(authResponse);

Starting the Challenge

If the response from the 3DS Server indicates that a challenge is required, the challenge process is initiated using the doChallenge method. When this is called, control of the UI is handed over to the 3DS SDK. The challenge will be performed by the SDK, and when finished the appropriate ChallengeStatusReceiver event will fire (completed, cancelled, etc.)

sdkTransaction.doChallenge(mActivity, challengeParameters, this, 5);

The doChallenge method takes the following parameters:

Name Type Description
currentActivity android.app.Activity The activity used by the SDK for the challenge process.
challengeParameters ChallengeParameters ACS details required by the 3DS SDK to conduct the challenge process during the transaction. For details, see the ChallengeParameters section.
challengeStatusReceiver ChallengeStatusReceiver Callback object for notifying the 3DS Requestor App about the challenge status. For details, see the ChallengeStatusReceiver section.
timeout Integer Timeout interval (in minutes) within which the challenge process must be completed. The minimum timeout interval is 5 minutes.

Completing Authentication

If the completed callback fires, the CompletionEvent parameter will contain more details on the authentication results. This has two properties: sdkTransactionID, and transactionStatus. The transactionStatus contains the transStatus from the last CRes packet, which would be one of the values below:

  • Y: Order completed successfully / Authentication successful
  • A: Order completed successfully / Attempts processing performed
  • N: Order denied / Not authenticated (denied)
  • R: Order denied / Authentication rejected
  • U: Order failed due to technical reasons / Authentication could not be performed

Getting Started in iOS

First, the framework will need to be referenced in the project. To do this, drag the .xcframework into the Frameworks section of the project settings.

Initializing the SDK

Before being used, the SDK must be initialized via the initialize method. Depending on the 3DS Requestor application implementation, a ThreeDSService instance is created either during startup of the 3DS Requestor app (as a background task), or when a transaction is initiated. The state of the service is maintained until the cleanup method is called. The initialize method can be called like so:

try threeDS2Service.initialize(
	configParameters: configParameters,
	locale: nil,
	uiCustomization: uiCustom,
	clientEventListener: clientEventListener)

The parameters this initialize method takes are as follows:

Name Type Description
configParameters ConfigParameters Configuration information that shall be used during initialization. For details, see the ConfigParameters section.
locale String A string that represents the locale for the app's user interface (e.g. "en-US"). For future use.
uiCustomization UiCustomization UI configuration information that is used to specify the UI layout and theme (fonts, colors, etc.) For details, see the UI Customization section.
clientEventListener ClientEventListener A listener to hook in to SDK events (for logging, etc.) For details, see the ClientEventListener section.

Config Parameters

The ConfigParameters class is used to provide details required by the 3DS SDK for initialization. The ConfigParametersBuilder class helps with organizing these parameters which can be used as follows:

var directoryServerInfoList = [DirectoryServerInfo]()
directoryServerInfoList.append(DirectoryServerInfo(RID: DSInfo.TEST_DS_ID, publicKey: DSInfo.TEST_DS_CERT, CA: DSInfo.TEST_DS_CA))

let deviceParameterBlacklist = ["C005", "I010"]
let clientConfigs = ["LogLevel=3", "MaskSensitive=false"]

let builder = ConfigParametersBuilder.init(directoryServerInfoList: directoryServerInfoList, runtimeLicense: "", deviceParameterBlacklist: deviceParameterBlacklist, clientConfig: clientConfigs)
let configParameters = try builder.build()

Parameters fall into a few groups:

Name Type Description
DirectoryServerInfo DirectoryServerInfo Used to add keys and certificates for different directory servers.
RuntimeLicense String The 3DS SDK license string.
DeviceParameterBlacklist List<String> A list of device parameters NOT to pull from the device. By default, the SDK will pull as many device parameters as it can. This setting group can be used to instruct the SDK not to pull certain parameters. You can add parameters to this list by specifying the identifier. A full list of parameters can be found in the EMV® 3-D Secure SDK Device Information document, which can be obtained from EMVCo directly.
ClientConfig List<String> Configuration settings used for additional configuration of the SDK. A list of available options can be found in the Client Config section.

UI Customization

Should the 3DS Requestor wish to have its own look-and-feel in the challenge pages, the UICustomization class is used. This class allows the customization of Buttons, Labels, TextBoxes, and Toolbars. For example, the following will configure buttons with red backgrounds and white font:

let uiCustom = UiCustomization()

let customButton = ButtonCustomization()
customButton.setTextColor(color: UIColor.white)
customButton.setBackgroundColor(color:UIColor.red)
	
try uiCustom.setButtonCustomization(buttonCustomization: customButton, buttonType: .CANCEL)
try uiCustom.setButtonCustomization(buttonCustomization: customButton, buttonType: .CONTINUE)
try uiCustom.setButtonCustomization(buttonCustomization: customButton, buttonType: .NEXT)
try uiCustom.setButtonCustomization(buttonCustomization: customButton, buttonType: .RESEND)
try uiCustom.setButtonCustomization(buttonCustomization: customButton, buttonType: .SUBMIT)

Here is the resulting Submit button for a Single-Select challenge:

Custom Submit Button

Icon Customization

Along with the customization of the look-and-feel of the UI via the UiCustomization class detailed above, it may be desirable to also customize the images utilized by the SDK. There are seven images used by iOS for this that can be customized via a Bundle of images with the following names:

  • CollapsedLabelIndicator The icon used to indicate a section that can be collapsed.
  • ExpandedLabelIndicator The icon used to indicate a section that can be expanded.
  • MultiSelection The icon used for a multi selection option.
  • MultiSelectionSelected The icon used for selected multi selection option(s).
  • SingleSelection The icon used for a single selection option.
  • SingleSelectionSelected The icon used for the selected single selection option.
  • WarningIndicator: The icon used (as indicated by the ACS) to draw attention to challenge information text being displayed.

The bundle containing these images can be passed to the ThreeDS2Service constructor like so:

let threeDS2Service = ThreeDS2Service(bundle: Bundle.main)

ClientEventListener

The ClientEventListener class exposes a number of events that are fired at certain points during the SDK's operation. Below is a list of the available events:

DataPacketIn

Fired when receiving a data packet from the server.

class MyClientEventListener: ClientEventListener {
	...
	func onDataPacketIn(_ dataPacket: Data) {
		//...
	}
	...
}

This event fires when a packet is received. The entire data packet (including all framing and error detection characters) is contained in the dataPacket parameter. This parameter may be inspected for advanced troubleshooting, or to extract additional response properties beyond the scope of this component.

DataPacketOut

Fired when sending a data packet to the server.

class MyClientEventListener: ClientEventListener {
	...
	func onDataPacketOut(_ dataPacket: Data) {
		//...
	}
	...
}

This event fires right before each data packet is sent. The entire data packet (including all framing and error detection characters) is contained in the dataPacket parameter. This parameter may be inspected for advanced troubleshooting.

Log

Fires once for each log message.

class MyClientEventListener: ClientEventListener {
	...
	func onLog(_ logLevel: Int32, _ message: String, _ logType: String) {
		print("[\(logType)]\(message)")
	}
	...
}

Logging is handled through the Log event. This will fire any time a message is built or a response is parsed, including error messages.

When the Log event is fired, the message in question is made available via the message event parameter. The other event arguments are logType and logLevel.

The logType parameter indicates the type of the log entry. Possible values are:

  • Info
  • RequestHeaders
  • ResponseHeaders
  • RequestBody
  • ResponseBody
  • ProxyRequest
  • ProxyResponse
  • FirewallRequest
  • FirewallResponse
  • CReq
  • CRes
  • Erro
  • EphemeralKey
  • DeviceParams
The LogLevel configuration setting can be used to specify the detail of the logs raised through the Log event. The logLevel parameter in the event indicates the log level to which the current message belongs. Possible values are:

  • 0 (None) No events are logged.
  • 1 (Info - default) Informational events are logged.
  • 2 (Verbose) Detailed data is logged.
  • 3 (Debug) Debug data is logged.

The LogLevel is initially specified in the Client Config settings.

It is recommended to output all messages raised in this event to a file for record keeping purposes, or for later debugging issues that may have come up.

SSLServerAuthentication

Fired after the server presents its certificate to the client.

class MyClientEventListener: ClientEventListener {
	...
	func onSSLServerAuthentication(_ certEncoded: Data, _ certSubject: String, _ certIssuer: String, _ status: String, _ accept: UnsafeMutablePointer&lt;Int32&gt;) {
		//...
	}
	...
}

This event is where the client can decide whether to continue with the connection process or not. The accept parameter is a recommendation on whether to continue or close the connection. This is just a suggestion: application software must use its own logic to determine whether to continue or not.

When accept is False, status shows why the verification failed (otherwise, status contains the string "OK"). If it is decided to continue, you can override and accept the certificate by setting the accept parameter to True.

SSLStatus

Shows the progress of the secure connection.

class MyClientEventListener: ClientEventListener {
	...
	func onSSLStatus(_ message: String) {
		//...
	}
	...
}

The event is fired for informational and logging purposes only. Used to track the progress of the connection.

Client Config

The SDK accepts one or more of the following configuration settings. These are set as SETTING=VALUE pairs, and set as the clientConfig when building the ConfigParameters.

LogLevel
This config specifies the level of logging enabled in the component. Possible values include:

  • 0 - None
  • 1 - Info
  • 2 - Verbose
  • 3 - Debug
This is set to 1 (Info) by default.

MaskSensitive

This setting controls whether sensitive data is masked in the Log event. When set to True (default) the card number value will be replaced with the value *************.

Note: DataPacketOut will always contain the raw unmasked value regardless of this setting. This setting only applies to the Log event.

The default value is True.

Security Checks

The SDK performs security checks and collects device information during initialization. Warnings produced during the 3DS SDK initialization process can be retrieved using the getWarnings method, which returns a list of Warning objects. These can be checked by the app to determine whether or not to proceed with the checkout process:

// check warnings
let warnings = try threeDS2Service.getWarnings()
if warnings.count > 0 {
	// process warnings
	// abort the checkout if necessary
}

The Warning object consists of the following fields:

Name Type Description
id String Warning identifier.
message String Warning message.
severity Severity (enum) Warning severity level (LOW, MEDIUM, HIGH).

The following warnings are documented in the EMVCo specification:

Security Warning ID Description Severity Level
SW01 The device is jailbroken. HIGH
SW02 The integrity of the SDK has been tampered. HIGH
SW03 An emulator is being used to run the app. HIGH
SW04 A debugger is attached to the app. MEDIUM
SW05 The OS or the OS version is not supported. HIGH

Creating a Transaction

Call the createTransaction method to start a transaction. A reference should be kept for this transaction throughout the entire 3-D Secure authentication process. This method takes the directory server ID, which points to a DirectoryServerInfo configuration parameter added during SDK initialization. The second parameter is a protocol version as a string. Supported version strings are 2.1.0 and 2.2.0:

sdkTransaction = try threeDS2Service.createTransaction(DSInfo.TEST_DS_ID, "2.2.0")

Later, when the transaction is complete, it should be closed via the Transaction object's close method.

Displaying Progress

A progress dialog must be displayed to the end user at certain points in the 3-D Secure process. While performing the challenge, the 3DS SDK will automatically display a progress dialog when appropriate.

A progress dialog must also be displayed to the user while the application is communicating with the 3DS Server and waiting for the authentication request results. The dialog used by the 3DS SDK is available to be used by the application if desired, and can be obtained from the Transaction object via the getProgressView method like so:

// The progress dialog is an instance of ProgressView
var sdkProgressDialog: ProgressView?

// Retrieve the progress dialog from the transaction object instance
sdkProgressDialog = try sdkTransaction?.getProgressView()
sdkProgressDialog?.show()

// Later, to hide/dismiss if desired:
sdkProgressDialog?.close()

The 3DS SDK will automatically hide the dialog when starting the challenge process, so there is no need to explicitly dismiss the dialog in the application code.

Authenticating

The authentication process starts with a call to the Transaction object's getAuthenticationRequestParameters method. When this method is called, the 3DS SDK will encrypt the device information it collected during initialization and make it, along with other SDK information required by the 3DS Server, available in the returned AuthenticationRequestParameters object. This AuthenticationRequestParameters object consists of the following fields:

Name Description
SDKTransactionId A transaction identifier randomly generated by the SDK.
DeviceData Device data collected by the SDK during initialization and encrypted using the DS key.
SDKEphemeralPublicKeyThe public key component of the ephemeral key pair generated by the SDK.
SDKAppId A UUID value that uniquely identifies the app on the device.
SDKReferenceNumber Assigned to our SDK by EMVCo after certification.
MessageVersion From createTransaction, or a default value from the SDK (2.1.0).
AuthRequest Packaged authentication request data to be sent to the 3DS Server.

The AuthRequest property is a packaged form of the other properties. The app would transmit this to the 3DS Server via a communication channel outside the scope of the 3DS SDK itself. On the server side, this AuthRequest data is designed to be passed directly in to the 3DS Server component's ClientAuthRequest property prior to sending the authentication request to the directory server via its SendAuthRequest method.

When the SendAuthRequest method completes, the Server component's ClientAuthResponse property will contain data that can be sent back to the app and passed to the 3DS SDK to use if a challenge is required.

Response Handling

The 3DS Server is responsible for reading the authentication response from the directory server and indicating to the client (in this case, the app) whether or not a challenge is required. In our 3DS Server component, check the TransactionStatus property after the SendAuthRequest method completes. If this is a value of C or D, a challenge is required.

If no challenge is required (frictionless flow), or authentication cannot be performed for some reason, no further action is required from a 3-D Secure standpoint. Proceed to the Completing Authentication section for details on closing the transaction.

If a challenge is required, the 3DS Server should return the ClientAuthResponse property value to the app for use when starting the challenge process. The Performing a Challenge section below details how to perform the challenge.

Performing a Challenge

If a challenge is required, the challenge is performed by creating the ChallengeParameters (using the ClientAuthResponse from the 3DS Server component) and calling the doChallenge method. The SDK will take care of all communication with the ACS while performing the challenge, as well as prompting the user as needed for the required input. When the challenge process is complete, the relevant ChallengeStatusReceiver callback method will fire.

Challenge Status Receiver

ChallengeStatusReceiver is an interface that should be implemented in the application and passed to the doChallenge when Starting the Challenge. Depending on the result of the challenge process, one of the following methods will be called:

Name Description
completed Called when the challenge process (that is, the transaction) is completed. When a transaction is completed, a transaction status shall be available.
cancelled Called when the cardholder selects the option to cancel the transaction on the challenge screen.
timedout Called when the challenge process reaches or exceeds the timeout interval that is specified during the doChallenge call.
protocolErrorCalled when the 3DS SDK receives an EMV 3-D Secure protocol-defined error message from the ACS.
runtimeError Called when the 3DS SDK encounters errors during the challenge process. These errors include all errors except those covered by the protocolError method.

Example implementations of these methods can be found below:

func completed(_ completionEvent: CompletionEvent) {
	showToast("Challenge completed with transactionStatus " + completionEvent.getTransactionStatus())

	try? closeTransaction()
}

func cancelled() {
	showToast("Challenge cancelled.")
}

func timedout() {
	showToast("Challenge timed out.")
}

func protocolError(_ protocolErrorEvent: ProtocolErrorEvent) {
	showToast("Challenge protocolError: " +
		protocolErrorEvent.getErrorMessage().getErrorDescription() + "\t" +
		protocolErrorEvent.getErrorMessage().getErrorDetails());
}

func runtimeError(_ runtimeErrorEvent: RuntimeErrorEvent) {
	showToast("Challenge runtimeError: " + runtimeErrorEvent.getErrorMessage());
}

Challenge Parameters

ChallengeParameters hold parameters that are required to conduct the challenge process. This is passed to the doChallenge method when starting the challenge process. Available properties, accessible via getters and setters, are:

Name Type Description
3DSServerTransactionID String 3DS Server Transaction ID.
AcsTransactionID String ACS Transaction ID.
AcsRefNumber String ACS Reference Number.
AcsSignedContent String ACS signed content. This data includes the ACS URL, ACS ephemeral public key, and SDK ephemeral public key.
ThreeDSRequestorAppURL String 3DS Requestor App URL.
ThreeDSServerAuthResponse String The Authentication Response from the 3DS Server component.

These properties can be set individually based on what comes back from the 3DS Server. If using the 3DS Server component, the ThreeDSServerAuthResponse can be set to the generated ClientAuthResponse value, and the other properties will be set automatically based on this value.

let challengeParameters = ChallengeParameters(threeDSServerAuthResponse: authResponse)

Starting the Challenge

If the response from the 3DS Server indicates that a challenge is required, the challenge process is initiated using the doChallenge method. When this is called, control of the UI is handed over to the 3DS SDK. The challenge will be performed by the SDK, and when finished the appropriate ChallengeStatusReceiver event will fire (completed, cancelled, etc.)

try sdkTransaction?.doChallenge(rootViewController: navigationController, challengeParameters: challengeParameters, challengeStatusReceiver: self, timeout: 5)
Name Type Description
navigationController UIViewController The view controller used by the SDK for the challenge process.
challengeParameters ChallengeParameters ACS details required by the 3DS SDK to conduct the challenge process during the transaction. For details, see the Challenge Parameters section.
challengeStatusReceiver ChallengeStatusReceiver Callback object for notifying the 3DS Requestor App about the challenge status. For details, see the Challenge Status Receiver section.
timeout Integer Timeout interval (in minutes) within which the challenge process must be completed. The minimum timeout interval is 5 minutes.

Completing Authentication

If the completed callback fires, the CompletionEvent parameter will contain more details on the authentication results. This has two properties: sdkTransactionID, and transactionStatus. The transactionStatus contains the transStatus from the last CRes packet, which would be one of the values below:

  • Y: Order completed successfully / Authentication successful
  • A: Order completed successfully / Attempts processing performed
  • N: Order denied / Not authenticated (denied)
  • R: Order denied / Authentication rejected
  • U: Order failed due to technical reasons / Authentication could not be performed

Managing Resources

The cleanup method frees up resources that are used by the 3DS SDK. It is called only once during a single 3DS Requestor App session:

Android

ThreeDS2Service.INSTANCE.cleanup(applicationContext);

iOS

threeDS2Service.cleanup();

Notes on Application Permissions

The SDK itself does not require any specific permissions outside of internet access, and it will use only the permissions that the application has requested. The app should require permission before the SDK is initialized. This is required by the specification and some device parameters will not be available if permission is not granted.

For a full list of required permissions for each device parameter, see the EMV® 3-D Secure SDK Device Information document, which can be obtained from EMVCo directly.

We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.