Configure 3D Secure for your Primer account

Follow the below process to start using 3DS on sandbox immediately. Do note that for 3DS to work in production, you will need to complete the process described in step 4.

To get 3DS configured and running, you need to:

  1. 1
    Set up your workflow
  2. 2
    Configure your Client Session
  3. 3
    Handle 3DS in Universal Checkout
  4. 4
    Onboard your 3DS profile to go live

1. Set up your workflow

Configuring 3DS settings for your payments takes place within the "Authorize payment" Action. Learn more here about how to set up a workflow to process payments.

Example of setting up a workflow

In the configuration panel, you need to choose which 3DS option you want for all payments processed by this Action block:

🚫

No 3DS

3DS will not be used for any payments processed by this block. Payments will be declined when the Issuer requires authentication.

⭐️

Adaptive 3DS

Use Primer’s proprietary Adaptive 3DS which will only carry out 3DS authentication if the payment would be declined without it.

🔨

Primer 3DS

3DS authentication will be handled by Primer's agnostic 3DS solution for payments processed by this block. This could either be a challenge or frictionless.

💳

Processor 3DS

Your processor will present a 3DS challenge according to their configuration. This isn't compatible with Fallbacks as Primer is not involved in the flow.

2. Configure your Client Session

You need to pass the following field in POST/client-session:

FieldDescriptionRequired
  1. customer
  2. emailAddress
The customer's email addressYes

To improve 3DS success rates, it is recommended to pass the following field in POST/client-session:

FieldDescriptionRequired
  1. customer
The customer's billing addressRecommended

In Sandbox, both the email address and billing address must be provided to trigger 3DS.

3. Handle 3DS in Universal Checkout

Install Primer3DS SDK

3D Secure on iOS requires the addition of the Primer3DS library to your project.

With CocoaPods

First, modify your Podfile like so:

12345678910
source 'https://github.com/CocoaPods/Specs.git'source 'https://github.com/primer-io/primer-podspecs.git'
use_frameworks!
target 'PrimerSDK_Example' do  pod 'PrimerSDK'  pod 'Primer3DS'    // ...end
swift
copy

Then run pod install to install Primer3DS on your workspace.

In case you encounter an error that the bundle needs signing on Xcode 14, add the following post-install script in your podfile.

123456789
post_install do |installer|  installer.pods_project.targets.each do |target|    if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"      target.build_configurations.each do |config|          config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'      end    end  endend
ruby
copy

In case you notice the warning "WARNING! Failed to import Primer3DS" when you initialize the PrimerSDK, add the following post-install script in the end of your pod file.

1234567891011121314151617
target 'MyApp' do  pod 'PrimerSDK'  pod 'Primer3DS'
  # ...
  # This is what needs to be added  post_install do |installer|    installer.pods_project.targets.each do |target|      if target.name == "PrimerSDK"        target.build_configurations.each do |config|          config.build_settings['OTHER_LDFLAGS'] = '$(inherited) -framework "Primer3DS"'        end      end    end  endend
ruby
copy
With Swift Package Manager

To add PrimerSDK with Swift Package Manager;

  1. 1
    Select your project, and then navigate to Package Dependencies
  2. 2
    Click on the + button at the bottom-left of the Packages section
  3. 3
    Paste https://github.com/primer-io/primer-sdk-3ds-ios into the Search Bar
  4. 4
    Press Add Package
  5. 5
    Let Xcode download the package and set everything up

Adding Primer 3DS

❗️

If Primer3DS is not installed, 3DS will fail. In the case of a 3DS triggered by the workflow, the primerDidFailWithError functions will be called.

Interoperability matrix

Primer SDK internally uses Primer 3DS SDK as a compile time dependency. In order for the SDKs to work properly, the versions used internally and the one imported to your code must match.

Here is a breakdown of supported interoperable versions:

Primer SDK versionPrimer 3DS SDK version
>= 2.24.0>= 2.3.0
2.19.0 - 2.23.02.1.0 - 2.2.1
<= 2.18.32.0.0 - 2.0.2

Handle Out-of-Band (OOB) redirects (Optional)

Starting from 3D Secure protocol version 2.2.0, you can enhance the user experience by implementing an automatic redirect from another (authentication) application during an OOB challenge to your application once the challenge is successfully completed. This feature allows for a seamless transition and improved user flow.

⚠️

If this feature is not implemented, the user will have to come back to your application manually to complete their payment, which adds significant friction.

To enable this feature, ensure that you include the threeDsAppRequestorUrl parameter when configuring the PrimerThreeDsOptions object.

Please note that the threeDsAppRequestorUrl value must be an iOS Universal Link. Additionally, it is essential that your application is configured to handle the Universal Link properly in order to facilitate the redirection.

To configure the Universal Link correctly using Universal Checkout, follow these steps:

    123456789
    let settings = PrimerSettings(  // ...  paymentMethodOptions: PrimerPaymentMethodOptions(    threeDsOptions: PrimerThreeDsOptions(      threeDsAppRequestorUrl: "https://{UNIVERSAL_LINK}"    ),  ),  // ...)
    swift
    copy
      123456789101112
      import PrimerSDKimport UIKit
      @UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {
        // ...
        func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {    return Primer.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)  }}
      swift
      copy
        123456789101112
        import PrimerSDKimport UIKit
        @UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {
          // ...
          func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {    return Primer.shared.application(app, open: url, options: options)  }}
        swift
        copy

        Execute 3D Secure

        Universal Checkout drop-in and headless automatically render the 3DS challenge when required by your workflow.

        If your application is not installed from a trusted source (e.g. a debug version, not installed from the store, or used on an simulator), try to set PrimerDebugOptions.is3DSSanityCheckEnabled to false. Otherwise 3D Secure library initialization will fail due to security checks being performed.

        ⚠️

        is3DSSanityCheckEnabled flag should only be used in development mode, and not in production release of your app.

        1234567
        let settings = PrimerSettings(  // ...  debugOptions: PrimerDebugOptions(    is3DSSanityCheckEnabled: false  )  // ...)
        swift
        copy

        Troubleshooting

        • If you notice a console warning "Failed to import Primer3DS" on the SDK initialization, go to Scheme settings and select Manual order. Dependencies

        4. Onboard your 3DS profile to go live

        Before going live with 3DS on Primer, your account has to be configured with your 3DS profile(s). This 3DS profile consists of the following fields for each card network:

        • Acquirer Merchant ID (MID)
        • Acquirer BIN
        • Merchant Category Code (MCC)

        Please reach out to us directly via our Service Desk to configure this. If you don’t have access, please contact your account administrator for assistance.

        Test 3D Secure

        Monitor 3DS

        You can monitor 3DS on Primer in three main ways:

        • Payment status update webhook
        • Payments API
        • Payment timeline

        1. Payment status update webhook

        Subscribe to the payment status update webhook to receive notification updates each time your payment changes status.

        As part of the webhook body, the threeDSecureAuthentication object is included detailing the outcome. Below is an example of this object for a successful 3DS authentication:

        12345
        {    "responseCode": "AUTH_SUCCESS",    "protocolVersion": "2.2.0",    "challengeIssued": true}
        json
        copy

        2. Payments API

        Using Primer's Payments API, you can retrieve the payment object, where the threeDSecureAuthentication object is included detailing the outcome. This is available in the GET/payments/{paymentId} request, alongside POST/payments.

        Below is an example for an unsuccessful 3DS authentication:

        1234567
        {    "responseCode": "AUTH_FAILED",    "reasonCode": "CARD_AUTHENTICATION_FAILED",    "reasonText": "Card Authentication Failed",    "protocolVersion": "2.1.0",    "challengeIssued": true}
        json
        copy

        3. Payment timeline

        You can see all your Primer payments from the Payments timeline in the Primer Dashboard.

        Navigate to the specific payment detailed timeline page. You will see the 3DS authentication event. Select this event to open the side drawer that contains the data tied to this 3DS event.

        3DS Side Drawer Example