---
title: Integration Steps
slug: integration-steps
docTags: 
createdAt: 2025-01-31T12:01:50.126Z
---

## Integrating via our Transaction API

This guide will take you through steps one to five, to illustrate the [full 3D Secure 2 authentication and authorisation flow](docId\:WpFMF662qaIGEGrpU_Mow) (including the conditional steps), to verify how it relates to the user journey when **integrating directly** with Judopay's Transaction API.

When integrating via our [Web](docId:40dWE6LBub7vdKza1QYDC) and [Mobile SDKs](docId\:FYeF-N37tnL1c5dssCmL3), we handle the 3D Secure flow, including the conditional steps on your behalf.
[Step One: Creating a Payment Session Request](docId\:iUSVPi9-6NDkb4Ow4u_3C) is the only step to be handled with **ALL&#x20;**&#x69;ntegration types.

***

### Prerequisite

:::hint{type="warning"}
Make sure your account has **3D Secure 2 API credentials&#x20;**&#x65;nabled.&#x20;
Contact ​Customer Support​​ to set this up.
:::

For the back-end server integration, make use of our:

- Server SDKs:
  - .NET Integration (version **3.0.0** or higher)

- Call our API directly using JSON (version **6.0.0.0** or higher)

***

### Step One: Create a Payment Request&#x20;

`/payments`, `/preAuths` and `/checkCard` are all supported.

Once you have the card details and device information from your client-side, your back-end server will need to make a payment request to Judopay's Transaction API.

:::hint{type="warning"}
The Cv2 is **not stored** by Judopay's Transaction API.
You will need to store the CV2 for th&#x65;**&#x20;duration of the transaction**, then **delete** it as soon as the transaction has completed.
:::

For the full `/payments` endpoint schema details and descriptions, see our Transaction API Reference [here](https://docs.judopay.com/api-reference/index.html#/Payments/post_transactions_payments).

**Sample Request**:

:::CodeblockTabs
.NET

```apex
// (1) Create an instance of the CardPaymentModel:
var paymentModel = new CardPaymentModel()
{  
     JudoId = "yourJudoId",
       YourConsumerReference = "yourConsumerReference",
       YourPaymentReference = "yourPaymentReference",
       Amount = 12.99,
       CardNumber = "1236358700088456",
       CV2 = "452",
       ExpiryDate = "12/30",
       CardAddress = new CardAddressModel
        {
         PostCode = "postCode"
        }
    CardHolderName = "CHALLENGE",
    MobileNumber = "07999999999",
    PhoneCountryCode = "44",
    EmailAddress = "contact@judopay.com",
    ThreeDSecure = new ThreeDSecureTwoModel
    {
        AuthenticationSource = ThreeDSecureTwoAuthenticationSource.Browser,
        ChallengeRequestIndicator = ThreeDSecureTwoChallengeRequestIndicator.ChallengeAsMandate,
        ScaExemption = ThreeDSecureTwoScaExemption.TransactionRiskAnalysis
    }
};

// (2) Send the 3ds2 request to Judopay
var result = await client.Payments.Create(paymentModel);


// (3) Challenge response example requesting additional device data is needed for 3D Secure 2
{
  "Response": {
    "ThreeDSecure": {
      "methodUrl": "https://example.com/pay-sim/sim/acs",
      "version": "2.1.0",
      "md": "ewogICJ0aHJlZURTU2VydmVyVHJhbnNJRCIgOiAiYjNjY2IxYWItZTk5"
    },
    "receiptId": "68869013641206075392",
    "message": "Issuer ACS has requested additional device data gathering",
    "result": "Additional device data is needed for 3D Secure 2"
  },
```

```json
{
  "cardNumber": 4111111111111111,
  "cv2": 452,
  "expiryDate": "12/30",
  "cardAddress": {
    "address1": "CardHolder House",
    "address2": "1 CardHolder Street",
    "town": "CardHolder Town",
    "postCode": "AB1 2CD",
    "countryCode": 826
  },
  "judoId": "yourJudoId",
  "yourConsumerReference": "yourConsumerReference",
  "yourPaymentReference": "yourPaymentReference",
  "yourPaymentMetaData": {
    "internalLocationRef": "Example",
    "internalId": 99
  },
  "amount": 12.99,
  "currency": "GBP",
  "cardHolderName": "John Doe",
  "mobileNumber": 7999999999,
  "phoneCountryCode": 44,
  "emailAddress": "test.user@judopay.com",
  "shippingAddress": {
    "isBillingAddress": true
  },
  "threeDSecure": {
    "authenticationSource": "Browser",
    "methodNotificationUrl": "https://api.judopay.com/order/3ds/methodNotification",
    "challengeNotificationUrl": "https://api.judopay.com/order/3ds/challengeNotification",
    "challengeRequestIndicator": "challengeAsMandate"
  }
}
```
:::

:::hint{type="info"}
If no additional transaction checks are required, you will receive the usual  **paymentReceipt&#x20;**&#x72;esponse.

If additional transaction checks are required, you will receive the **challenge&#x20;**&#x72;esponse.
:::

**Notification URLs**

You will need to set up two endpoints for your client to receive event notifications from the Issuer's ACS:

- **3DS Method Completion**: Informs your client application that the ACS has completed device detail gathering.
  - methodNotifcationURL
- **ACS Challenge Completion**: Informs your client application that the challenge has been completed by the customer.
  - challengeNotificationURL

Each endpoint should be configured to accept:

- HTTP POST
- Base64 encoded values

***

### Step Two: (Conditional) - Device Detail Gathering

:::hint{type="info"}
Some Issuer ACS’ support device data gathering.
Skip this step if no method URL is provided in the response from the API.
:::

Check the response from [Step One: Create a Payment Request](docId\:iUSVPi9-6NDkb4Ow4u_3C).&#x20;

The following fields in the response will indicate if the device details have been requested by the issuer:

- The **result&#x20;**&#x66;ield:*&#x20;"Additional device data is needed for 3D Secure 2"*
- The **message&#x20;**&#x66;ield:*&#x20;"Issuer ACS has requested additional device data gathering"*
- A **methodURL** will be returned in the response from the initial payment request.

:::hint{type="warning"}
In this instance, the following steps **will need** to be performed.
:::

1. Render a hidden iFrame on the client-side targeting the methodURL

:::CodeblockTabs
Rendering a Hidden iFrame

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
  <title>Sample Open Method URL Page</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script>
    $(document).ready(function() {
      console.log("ready!");
      var form = document.createElement("form");
      form.setAttribute("method", "POST");
      form.setAttribute("action", "https://test.portal.gpwebpay.com/pay-sim-gpi/sim/acs");
      form.setAttribute("target", "hidden_iframe");

      var threeDSMethodData = document.createElement("input");
      threeDSMethodData.setAttribute("type", "hidden");
      threeDSMethodData.setAttribute("name", "threeDSMethodData");
      
      // Set the md returned by the transaction api as the value:
      
      threeDSMethodData.setAttribute("value",
        "ewogICJ0aHJlZURTU2VydmVyVHJhbnNJRCIgOiAiYjA2NmFhYWEtMjQxOS00YzcyLThhMWItYmNjZDg0ZDNiZTA5IiwKICAidGhyZWVEU01ldGhvZE5vdGlmaWNhdGlvblVSTCIgOiAiaHR0cDovL2xvY2FsaG9zdDo4MDAwL21ldGhvZC1ub3RpZmljYXRpb24iCn0");
      form.appendChild(threeDSMethodData);
      document.body.appendChild(form);

      form.submit();
      console.log("form submitted");
    });
  </script>
</head>

<body>
  <iframe id="hidden_iframe" name="hidden_iframe" style="display: none;"></iframe>
</body>

</html>
```
:::

2\. **POST&#x20;**&#x74;he 3DS Method Data (**md**) object to it.
The **md&#x20;**&#x69;s an encoded base 64 value containing the:

- `threeDSServerTransID`&#x20;
  and
- `NotificationURL`&#x20;
  as JSON.

  (It is also returned in the Transaction API response from  [Step One: Create a Payment Request](docId\:iUSVPi9-6NDkb4Ow4u_3C).

3\. Listen for the redirect of the `methodNotificationUrl`

:::hint{type="info"}
We recommend you time-out after **10 seconds&#x20;**&#x69;f you have not received a response from any **NotificationURLs&#x20;**&#x6F;r rendered the **methodURL&#x20;**&#x66;rom [Step Two: (Conditional) - Device Detail Gathering .](docId\:iUSVPi9-6NDkb4Ow4u_3C)&#x20;
:::

***

### Step Three: (Conditional) - Resume Transaction&#x20;

Once the device details have been gathered, the 3D Secure authentication flow needs to be resumed.

1. Render a hidden iFrame on the client-side targeting the methodNotificationURL
2. Listen for the redirect of the methodNotificationUrl where the method completion message is received.
3. Resume the 3D Secure flow by submitting the results of the device detail gathering.

For the full `/resume3ds` endpoint schema details and descriptions, see our Transaction API Reference [here](https://docs.judopay.com/api-reference/index.html#/3DSecure/put_transactions__receiptId__resume3ds).

**Sample Request:**

:::CodeblockTabs
.NET

```apex
// (1) Once the additional device data has been collected, create an instance of the ResumeThreeDSecureTwo Model:

var resumeModel = new ResumeThreeDSecureTwoModel()
{
    CV2 = "452",
    MethodCompletion = MethodCompletion.No
   };

// (2) Resume the transaction flow to Judopay: 
//Use the ReceiptId from the original response

var resumeResult = await client.ThreeDs.Resume3DSecureTwo(result.Response.ReceiptId, resumeModel);

```

```json
// (1) Once the device details have been gathered resume the 3D Secure authentication flow:

{
 "cV2": "452",
 "threeDSecure": {
   "methodCompletion" : "no"
 } 
}
```
:::

**methodCompletion value**:

- methodCompletion = **Yes**
  - If your client received a POST to the methodNotifcationURL
- methodCompletion = **No**
  - If your client did NOT receive a POST to the methodNotifcationURL
- methodCompletion = **Unavailable**
  - If your client was unable to render the methodURL



**primaryAccountDetails Block**:

The **primaryAccountDetails&#x20;**&#x62;lock is optional, however it is **mandatory&#x20;**&#x66;or merchants who have an MCC code of **6012, 6051&#x20;**&#x61;nd **7299&#x20;**&#x74;o submit additional Information about the primary account holder for payment pre-authorisation.

:::CodeblockTabs
Example primaryAccountDetails Block

```json
"primaryAccountDetails": {  
    "name": "Smith", 
    "accountNumber": "1234567890", 
    "dateOfBirth": "1980-01-01", 
    "postCode": "AB1 2CD"
}
```
:::

***

### Step Four: (Conditional) - Render Challenge Page

After you have resumed the transaction, check the response from [Step Three: (Conditional) - Resume Transaction](docId\:iUSVPi9-6NDkb4Ow4u_3C).

:::CodeblockTabs
Sample Response

```json
{
    "challengeUrl": "https://mysampleapp/challenge/",
    "cReq": "ewo8fdhJKESWujmlpsalIiA6ICIwMSIKfQ",
    "version": "2.1.0",
    "receiptId": "123456789",
    "result": "Challenge completion is needed for 3D Secure 2",
    "message": "Issuer ACS has responded with a Challenge URL",
    "md": "zNkcy9tZXRob2ROb3RpZmljYXRp9ojhFSik9"
}
```
:::

The following fields in the response will indicate if your customer's bank may want to challenge:

- The **result** field: *"Challenge completion is needed for 3D Secure 2"*
- The **message&#x20;**&#x66;ield:*&#x20;"Issuer ACS has responded with a Challenge URL"*
- A **challengeURL**: to render the challenge page iFrame for your customer&#x20;

Render the **challengeURL&#x20;**&#x66;or your customer to complete the challenge.

:::CodeblockTabs
Rendering challengeUrl Page Example

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
  <title>Sample Open Challenge URL Page</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script>
    $(document).ready(function() {
      console.log("ready to render challenge")
      var form = document.createElement("form");
      form.setAttribute("method", "POST");
      form.setAttribute("action", "https://test.portal.gpwebpay.com/pay-sim-gpi/sim/acs");
      form.setAttribute("target", "iframe");

      var creqData = document.createElement("input");
      creqData.setAttribute("type", "hidden");
      creqData.setAttribute("name", "creq");
      //add creq object obtained from the server
      creqData.setAttribute("value", "ewogICJtZXNzYWdlVHlwZSIgOiAiQ1JlcSIsCiAgIm1lc3NhZ2VWZXJzaW9uIiA6ICIyLjEuMCIsCiAgInRocmVlRFNTZXJ2ZXJUcmFuc0lEIiA6ICI5NGVjODA4NS02NmIyLTQ2MzQtOTg4Zi04YmYzYjBjMTgxNTMiLAogICJhY3NUcmFuc0lEIiA6ICJiNmI1YTYzOC0wYmE2LTRhYzQtYjA3Ni0zMGVlMmM2MmY1ZWMiLAogICJjaGFsbGVuZ2VXaW5kb3dTaXplIiA6ICIwMSIKfQ==");
      form.appendChild(creqData);

      /* optional parameter to include Session Data

      */
      var sessionData = document.createElement("input");
      sessionData.setAttribute("type", "hidden");
      sessionData.setAttribute("name", "threeDSSessionData");
      sessionData.setAttribute("value", "<some judo specific data here");
      form.appendChild(sessionData);

      document.body.appendChild(form);
      console.log("submitting form")
      form.submit();
      console.log("complete")
    });
  </script>
</head>
<body>
</body>
</html>
```
:::

- **Creq**: Should be set to the cReq received in the response
- **threeDSSessionData**: Can be set to contain any details you would like returned in the post.

Listen for the redirect of the `challengeNotificationUrl`

***

### Step Five: Complete 3DS

Upon receiving a POST back to the `challengeNotificationUrl` send a request to Judopay's Transaction API to complete the transaction.

:::hint{type="info"}
If no additional transaction checks are required, you will receive the usual **paymentReceipt&#x20;**&#x72;esponse.
If additional transaction checks are required, you will receive the **completion&#x20;**&#x72;esponse.
:::

For the full `/complete3ds`endpoint schema details and descriptions, see our Transaction API Reference [here](https://docs.judopay.com/api-reference/index.html#/3DSecure/put_transactions__receiptId__complete3ds).

**Sample Request**:

:::CodeblockTabs
.NET

```apex
// (1) Create an instance of the CompleteThreeDSecureTwo Model:
var completeModel = new CompleteThreeDSecureTwoModel()
{
    CV2 = "452",
    "primaryAccountDetails":{
      "name":"John Smith",
      "accountNumber":"123456",
      "dateOfBirth":"1980-01-01",
      "postCode":"EC2A 4DP"
   }
};

// (2) Complete the transaction flow to Judopay: 
var completeResult = await client.ThreeDs.Complete3DSecureTwo(result.Response.ReceiptId, completeModel);

```

```json
{
   "Cv2": "452",
   "Version": "2.0"
}
```
:::

Judopay's Transaction API will respond with the both the:

- Authentication
- Authorisation status

of the transaction.

