---
updatedAt: 2026-02-26T13:08:02.000Z
agentTools:
  projectIndex: https://docs.ngenius-payments.com/llms.txt
---

# EMV 3DS (3DS 2.X) Integration

EMV 3-D Secure (3DS) is a messaging protocol that promotes frictionless consumer authentication and enables consumers to authenticate themselves with their card issuer when making card-not-present (CNP) e-commerce purchases.

It was designed to replace the 3DS 1.X standard, which is due to be decommissioned in October 2022.

## Before you start

Before you start making changes to integrate the EMV 3DS workflow on N-Genius Online, you should check the following:

1. That you have EMV 3DS enabled on your N-Genius Online account
2. That you are able to designate a specific URL on your server/site that will handle EMV 3DS challenge responses before these are sent back to the N-Genius Online APIs
3. That you are able to capture information about the card-holder/shopper's device information before proceeding with the EMV 3DS workflow

> 📘 Direct API Integrations Only
>
> This article is intended for use by Direct API integrated merchants only. All other integration types, i.e. Hosted Payment Page, Hosted Session (WebSDK), Mobile SDK, will not be required to make any changes to their integrations in order to support the new EMV 3DS standard.

With the 3DS 2 (EMV 3DS) option enabled for your N-Genius Online account, in most cases you will now begin receiving new authentication data following presentment of the card information to the N-Genius Online APIs.

An example of these new authentication parameters is below, and can be found in the new `3ds2` block returned during the `AWAIT_3DS` stage of payment processing:

```json
"3ds2": {
  "messageVersion": "2.1.0",
  "threeDSMethodURL": "https://paypage-uat.ngenius-payments.com/fake/3ds2/method",
  "threeDSServerTransID": "6bd31847-9d7d-4c12-bd8c-a4943a585ad3",
  "directoryServerID": "M000000004"
}
```

You will also note that there are two new URIs returned in the `_links` block:

| URI                           | Purpose                                                                                                                    |
| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `cnp:3ds2-authentication`     | Used to initiate the EMV 3DS authentication workflow on behalf of your card-holder/shopper                                 |
| `cnp:3ds2-challenge-response` | Used to present the result of the EMV 3DS authentication outcome to N-Genius Online APIs for completion of the transaction |

> 👍 Please check that you are receiving EMV 3DS data
>
> If you are not receiving the new EMV 3DS parameter block, or the additional URIs listed above, it is likely that either the card presented is not enabled for EMV 3DS, or this facility is not enabled on your account. Please contact your relationship manager or our E-Commerce Support team for further assistance if you are unsure.

If you are satisfied that you are being presented with this information during the `AWAIT_3DS` step, you may proceed with implementing the EMV 3DS workflow. The workflow is similar (but not identical) to the legacy 3DS 1.X process, albeit with a greater emphasis on card-holder experience, notably:

* The authentication process now allows greater flexibility in terms of consumer device usage
* The authentication process may sometimes result in having no requirement to issue a 'challenge' to the cardholder

The typical workflow is therefore as follows:

1. Send user agent and card-holder/shopper device information to the designated N-Genius Online 3DS 2 API endpoint (`_links.cnp:3ds2-authentication`), and receive EMV authentication data in return
2. Check whether the transaction requires a 'challenge' to be presented to the card-holder/shopper, and - if so - post all relevant data to the provided ACS (Access Control Server) URL along with the shopper's browser. Otherwise, you can consider this transaction complete.
3. The result of the ACS challenge to the card-holder will be posted to a notification URL of your choice
4. You should then post this information back to the designated N-Genius Online URI (`_links.cnp:3ds2-challenge-response`) for completion of the payment and onwards authorization of the transaction.

[block:image]
{
  "images": [
    {
      "image": [
        "https://files.readme.io/2b5b10e-emv-3ds-merchant-workflow.png",
        "emv-3ds-merchant-workflow.png",
        "Use this sequence diagram alongside our EMV 3DS2 Recipes for a complete, hands-on implementation guide."
      ],
      "align": "center",
      "caption": "Use this sequence diagram alongside our EMV 3DS2 Recipes for a complete, hands-on implementation guide."
    }
  ]
}
[/block]

Let's get started...

## Step 1: Send Device Information

In this step, we must capture the shopper's user agent, and information about their display dimensions, IP address, and the status of their browser's Java/JavaScript capability.

> 📘 Capturing Browser Information
>
> There are many ways to capture this information (user agent, display dimensions, etc.) and how you choose to implement is entirely your decision. However, the most common way is to use either JavaScript, or an Ajax function, to do so (or a dedicated "jump page"), then post this information to a back-end script for execution of the N-Genius Online API endpoint.
>
> For example, for Javascript based environments, many of the device attributes can be retrieved from the `navigator` object: [see here for more information](https://www.w3schools.com/js/js_window_navigator.asp)

## Looking for a Guided Integration?

To make your implementation smoother, we’ve created a step-by-step recipe that walks you through the full EMV 3DS 2.X authentication process. This interactive guide highlights the code blocks, responses, and actions at each stage—ideal for developers looking for clarity and speed.

[block:tutorial-tile]
{
  "backgroundColor": "#018FF4",
  "emoji": "🇸🇮",
  "id": "6808a2bf62b1da0010c60caa",
  "link": "https://docs.ngenius-payments.com/v3.0/recipes/emv-3ds2-authentication-with-n-genius-one-stage-payments",
  "slug": "emv-3ds2-authentication-with-n-genius-one-stage-payments",
  "title": "EMV 3DS2 Authentication with N-Genius (one-stage Payments.)"
}
[/block]

Or explore the Two-Stage Payments version.

[block:tutorial-tile]
{
  "backgroundColor": "#0168b1",
  "emoji": "🔒",
  "id": "67fddd2f342fc1001e473048",
  "link": "https://docs.ngenius-payments.com/v3.0/recipes/emv-3ds2-authentication-with-n-genius-two-stage-payments-1",
  "slug": "emv-3ds2-authentication-with-n-genius-two-stage-payments-1",
  "title": "EMV 3DS2 Authentication with N-Genius (Two-stage Payments.)"
}
[/block]

**HTTP Request Method**: POST\
**Explicit URI**: `https://api-gateway.sandbox.ngenius-payments.com/transactions/outlets/{outletId}/orders/{orderRef}/payments/{paymentRef}/card/3ds2/authentications`\
**Document Link**: `_links.cnp:3ds2-authentication`

**Headers**:

Add these headers to your request (note that you should replace `access_token` with the access token value we received from the [Request an access token](https://docs.ngenius-payments.com/reference/request-an-access-token-direct) step).

| Header        | Value                              |
| :------------ | :--------------------------------- |
| Authorization | Bearer `access_token`              |
| Content-Type  | application/vnd.ni-payment.v2+json |

**Body**:

You should send the captured information about the shopper/browser's device in the `browserInfo` block, as below.

```json
{
    	"deviceChannel": "BRW",
    	"threeDSCompInd": "Y",
    	"notificationURL": "https://notificationURL.com",
    	"browserInfo": {
    		"browserAcceptHeader": "application/json",
    		"browserJavaEnabled": true,
    		"browserLanguage": "en",
    		"browserTZ": "0",
    		"browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
    		"browserColorDepth": "30",
    		"browserScreenHeight": "1055",
    		"browserScreenWidth": "1680",
    		"browserJavascriptEnabled": true,
    		"browserIP": "192.168.1.1",
    		"challengeWindowSize": "05"
    	}
}
```

For the `deviceChannel` value, you should use one of the following two values:

* `BRW` if the shopper is using a web-browser on your traditional E-Commerce site (this should be the default value if you're unsure)
* `APP` if the shopper is using a native mobile-app experience (Currently unavailable, will be available soon)

The `threeDSCompInd` value should be set to `Y` in all cases.

The `notificationURL` value should contain the explicit URL on your server/site that will handle the response from the EMV 3DS card-holder authentication workflow.

**Response (Example)**:

```json
"3ds2": {
        "eci": "02",
        "transStatus": "C",
        "messageVersion": "2.1.0",
        "acsReferenceNumber": "00001ACS00001",
        "threeDSMethodURL": "https://paypage-uat.ngenius-payments.com/fake/3ds2/method",
        "threeDSServerTransID": "6bd31847-9d7d-4c12-bd8c-a4943a585ad3",
        "acsURL": "https://paypage-uat.ngenius-payments.com/fake/3ds2/acs?challengeNotificationUrl=https%3A%2F%2FnotificationURL.com",
        "acsTransID": "4a2a8308-03d0-4a96-8119-34be99fcbbf2",
        "directoryServerID": "M000000004",
        "base64EncodedCReq": "eyJ0cmFuc1N0YXR1cyI6IkMiLCJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjZiZDMxODQ3LTlkN2QtNGMxMi1iZDhjLWE0OTQzYTU4NWFkMyIsIm1lc3NhZ2VWZXJzaW9uIjoiMi4xLjAiLCJjaGFsbGVuZ2VDb21wbGV0aW9uSW5kIjoiMDEiLCJtZXNzYWdlVHlwZSI6IjAxIiwiYWNzVHJhbnNJRCI6IjRhMmE4MzA4LTAzZDAtNGE5Ni04MTE5LTM0YmU5OWZjYmJmMiJ9"
    }
```

If the request was completed successfully, you should now receive some new information returned in the `3ds2` block. This data will both a.) allow you to determine whether the transaction requires a card-holder/shopper challenge to be presented, and b.) where to redirect the shopper to, if so.

[block:parameters]
{
  "data": {
    "h-0": "Attribute",
    "h-1": "Purpose",
    "0-0": "`eci`",
    "0-1": "An indication of the expected ECI (E-Commerce Indicator) value that this transaction will result in, if successful.",
    "1-0": "`transStatus`",
    "1-1": "If this value is `C` then a challenge is required. For any other value, no challenge is required and you may consider the transaction complete.  \n  \nYou should also check the value of the order `state` for confirmation. If this value remains as `AWAIT_3DS`, then further action (i.e. a challenge step) is required. Otherwise, this value will show the post-authorization outcome of the transaction (`PURCHASE`, `CAPTURED`, `AUTHORIZED`, `DECLINED`, etc.)",
    "2-0": "`messageVersion`",
    "2-1": "The specific version of EMV 3DS that will be used",
    "3-0": "`acsReferenceNumber`",
    "3-1": "Internal use only",
    "4-0": "`threeDSMethodURL`",
    "4-1": "The URL which will determine which 3DS major version is implemented",
    "5-0": "`threeDSServerTransID`",
    "5-1": "The internal transaction ID used by the EMV 3DS service",
    "6-0": "`acsURL`",
    "6-1": "The URL to POST any relevant EMV data to, along with the redirection of your shopper's browser",
    "7-0": "`acsTransID`",
    "7-1": "The internal transaction ID used by the EMV 3DS ACS",
    "8-0": "`directoryServerID`",
    "8-1": "The directory server being used",
    "9-0": "`base64EncodedCReq`",
    "9-1": "A Base64 encoded form of the `CReq` payload (see below)"
  },
  "cols": 2,
  "rows": 10,
  "align": [
    "left",
    "left"
  ]
}
[/block]

**Test cards for use in testing specific scenarios:**

Note that for the expiry date component (`expiry`), any future date is acceptable, and any 3-digit value is acceptable for the CVV/CSC (`cvv`) component of the payment information.

| PAN                | EMV 3DS Mode                      | Outcome                    |
| :----------------- | :-------------------------------- | :------------------------- |
| `2303779999000275` | Frictionless (`transStatus != C`) | Success                    |
| `2303779999000408` | Challenge (`transStatus == C`)    | Success                    |
| `2303779999000291` | Frictionless (`transStatus == N`) | Failed (Not Authenticated) |
| `2303779999000317` | Frictionless (`transStatus == U`) | Failed (Unavailable)       |
| `2303779999000424` | Challenge (`transStatus == N`)    | Failed (Not Authenticated) |
| `2303779999000432` | Challenge (`transStatus == U`)    | Failed (Unavailable)       |

At this point, we must first determine whether this transaction requires an EMV 3DS challenge to be presented to the card-holder/shopper. To check this, interrogate the value of the `transStatus` attribute from the response body. If this value = `C`, then you must present the challenge.

**Example Code** (PHP):

The following code will parse the response from the previous step (Send Device Information) and interpret whether the transaction requires an authentication challenge from the card-holder (`transStatus == C`), or the transaction is considered "frictionless" and has continued for authorization without the challenge (`transStatus != C`).

```php
<?php 

  // collect output from device information post/response and convert to object
  $output = json_decode($json_response);
	$threeds2_data = $output->['3ds2'];
 	
	// check 3ds2.transStatus - if transStatus == "C", invoke challenge
	$emvTransStatus = $threeds2_data->transStatus;
	if ($emvTransStatus == "C") {
  
      // invoke challenge, construct 'creq' value for next step

      $acsURL = $threeds2_data->acsURL;

      $creq = new StdClass();
      $creq->threeDSServerTransID = $threeds2_data->threeDSServerTransID;
      $creq->acsTransID = $threeds2_data->acsTransID;
      $creq->challengeWindowSize = "05"; // see table below for window size options
      $creq->messageType = "CReq";
      $creq->messageVersion = $threeds2_data->messageVersion;

      $creqJson = json_encode($creq);
      $creqJsonB64 = base64_encode($creqJson);

      // post '$creqJsonB64` to $acsURL as form POST: key = creq, value = $creqJsonb64 (next step)

  	} else {
  
      $orderState = $output->state;

      // check the state of the order for frictionless workflows
      if ($orderState == "PURCHASED" || $orderState == "AUTHORIZED" || $orderState == "CAPTURED") {

        // order is complete, and successful

      } else {

        // order failed, or was rejected/declined

      }
  
  }
  
?>
```

Please continue to the next section to learn how to do this.

## Step 2: Invoke EMV 3DS Challenge

In this step, we will gather all the required information to execute the EMV 3DS challenge into the correct structure and format, then POST this information to the supplied `acsURL` whilst redirecting the shopper accordingly.

**HTTP Request Method**: POST\
**Explicit URI**: (various)\
**Document Link**: `3ds2.acsURL`

**Body (Form Data)**:

Only one parameter is required to be posted to the `acsURL` endpoint - this is the `creq` value. The `creq` value is a Base64-encoded form of multiple additional parameters represented in JSON format.

| Form Attribute | Form Attribute Value (Example)                                                                                                                                                                                                                                |
| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `creq`         | `eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImMxOGExZDYwLTI3ZmUtNDZjMC04Y2Q5LWUwMzBmOTg3YzVmYiIsImFjc1RyYW5zSUQiOiJiYjk5MzY4My1lYWIwLTRmNjktOWQ0OC02Y2EwYWM3NGNkNmIiLCJjaGFsbGVuZ2VXaW5kb3dTaXplIjoiMDUiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIn0` |

The following JSON payload/values, when Base64-encoded, will result in a string that looks similar to the above example:

```json
{
  "threeDSServerTransID": "c18a1d60-27fe-46c0-8cd9-e030f987c5fb",
  "acsTransID": "bb993683-eab0-4f69-9d48-6ca0ac74cd6b",
  "challengeWindowSize": "05",
  "messageType": "CReq",
  "messageVersion": "2.1.0"
}
```

* `threeDSServerTransID` - can be retrieved from the EMV `3ds2` response block in the previous step
* `acsTransID` - can be retrieved from the EMV `3ds2` response block in the previous step
* `challengeWindowSize` - a value that determines the size (dimensions of the EMV 3DS challenge window when presented to the shopper. See below for a list of possible values.
* `messageType` - should always be set to `CReq`
* `messageVersion` - can be retrieved from the EMV `3ds2` response block in the previous step

**Choosing a `challengeWindowSize` value**:

| challengeWindowSize Value | Dimensions  |
| :------------------------ | :---------- |
| `01`                      | 250 x 400   |
| `02`                      | 390 x 400   |
| `03`                      | 500 x 600   |
| `04`                      | 600 x 400   |
| `05`                      | Full screen |

Base64 encode the JSON data to obtain the `creq` value, then `POST` the `creq` information as `FORM` data to the specified `acsURL`, thereby simultaneous redirecting the shopper/card-holder to the `acsURL` resource.

The shopper will then complete the EMV 3DS challenge.

Once the shopper/card-holder has completed the challenge (successfully or otherwise), the shopper's browser will be redirected to your nominated `notificationURL` (specified in Step 1) along with `cres` POST data.

## Step 3: Receiving the CRES value

In return, after the challenge process has been completed, the `acsURL` resource will POST the result of the challenge (successful or otherwise) to your nominated `notificationURL` defined in the previous step. This will be `FORM` data, as with the earlier `creq` data you posted to the `acsURL`, but the response form attribute will be `cres` (not `creq`), as it pertains to the (res)ult of the EMV 3DS challenge workflow.

**Body (Form Data)**:

Only one parameter will be returned from the `acsURL` resource - this is the `cres` value. The `cres` value is a Base64-encoded form of outcome-related data, but we recommend that you do not include any decoding in your integration. This value will should be passed on, without amendment, to the `challenge-response` URI.

| Form Attribute | Form Attribute Value (Example)                                                                                                                                                                                                                                |
| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `cres`         | `eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImMxOGExZDYwLTI3ZmUtNDZjMC04Y2Q5LWUwMzBmOTg3YzVmYiIsImFjc1RyYW5zSUQiOiJiYjk5MzY4My1lYWIwLTRmNjktOWQ0OC02Y2EwYWM3NGNkNmIiLCJjaGFsbGVuZ2VXaW5kb3dTaXplIjoiMDUiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIn0` |

## Step 4: Posting the CRES value to N-Genius Online

Now that you have the `cres` value, this can now be passed on, directly, to the N-Genius Online challenge response URI. You can choose to decode this Base64 value, but this is not necessary and is not recommended.

To do so, simply POST the following `cres` value to the challenge authentication API as follows:

**HTTP Request Method**: POST\
**Explicit URI**: `https://api-gateway.ngenius-payments.com/transactions/outlets/{outletId}/orders/{orderRef}/payments/{paymentRef}/card/3ds2/challenge-response`\
**Document Link**: `_links.cnp:3ds2-challenge-response`

**Headers**:

| Header        | Value                              |
| :------------ | :--------------------------------- |
| Authorization | Bearer `access_token`              |
| Content-Type  | application/vnd.ni-payment.v2+json |

**Body**:

Only one value is required to be passed in the body of the `POST` data to this URI:

| Key                 | Value                                          |
| :------------------ | :--------------------------------------------- |
| `base64EncodedCRes` | The `cres` value received in the previous step |

For information only, the `cres` value is a Base64 encoded form of the following variables:

```json
{
  "transStatus": "Y",
  "threeDSServerTransID": "4ac00198-09fb-4966-b2d7-5e9677445394",
  "messageVersion": "2.1.0",
  "challengeCompletionInd": "01",
  "messageType": "01",
  "acsTransID": "544c86b9-7478-4519-b912-fcfc135dc9a1"
}
```

After this step is completed, the N-Genius Online payment gateway will then proceed with the transaction as determined by the outcome of EMV 3DS. If the EMV 3DS challenge was successful, the transaction will be passed on for subsequent authorization. If unsuccessful, it is likely that the transaction will be rejected.

At this point, you may check the response of this request for the final order `state` value for driving the appropriate workflow on your side.