**Last updated**: 22 April 2025 | [**Change log**](/products/3ds/changelog/)

# Device Data

The card issuer uses Device Data Collection (DDC) to fingerprint the customer's device.

Along with the risk data in the [authentication](/products/3ds/web/authentication) request, it's used to decide if a [challenge](/products/3ds/web/challenge-verification) is needed or if the authentication can be frictionless (no challenge displayed to your customer).

Important
Invoke this process immediately upon the customer providing their payment credentials. This ensures that DDC processes asynchronously behind the scenes as the customer completes the remaining checkout process. If a customer changes their card number after the DDC process is started or completed, re-execute the entire DDC process.

## Device data initialization

`POST` your device data initialization request to the `3ds:deviceDataInitialize` action link.

This request creates a JSON Web Token (JWT) that is used as part of the DDC form. The DDC form also requires the first six digits of your customer's card number (BIN). The BIN can be returned if a token resource is provided, see `JWT + BIN (token)` request.

For consistency of integration you can also provide the full card number `JWT + BIN (card)`  or `JWT + BIN (Network Token)`. It is truncated to become the BIN in the response.

### Device data initialization example request

Card (JWT + BIN)
Token (JWT + BIN)
Network Token (JWT + BIN)
JWT only

```json
{
  "$ref": "#/components/schemas/3DS_deviceDataInitialize",
  "components": {
    "schemas": {
      "transactionReference": {
        "maxLength": 64,
        "minLength": 1,
        "pattern": "^[-A-Za-z0-9_!@#$%()*=.:;?\\[\\]{}~`/+]*$",
        "type": "string",
        "description": "A unique reference for authentication. For example, e-commerce order code. Use the same transactionReference across all 3 potential request types (deviceDataInitialization, authentication, verification)."
      },
      "merchant": {
        "required": [
          "entity"
        ],
        "type": "object",
        "description": "An object that contains information about the merchant and API level configuration.",
        "properties": {
          "entity": {
            "maxLength": 64,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9 ]*$",
            "type": "string",
            "description": "Used to route the request in Access Worldpay, created as part of on-boarding."
          }
        }
      },
      "cardHolderName": {
        "maxLength": 255,
        "minLength": 1,
        "type": "string",
        "description": "The name on your customer's card. This is not a mandatory field, however we recommend that you supply this to improve authentication rates."
      },
      "billingAddress": {
        "required": [
          "address1",
          "city",
          "postalCode",
          "countryCode"
        ],
        "type": "object",
        "description": "An object containing the billing address information.",
        "properties": {
          "city": {
            "maxLength": 15,
            "minLength": 1,
            "type": "string",
            "description": "Billing address city"
          },
          "address1": {
            "maxLength": 80,
            "minLength": 1,
            "type": "string",
            "description": "Billing address line 1"
          },
          "postalCode": {
            "maxLength": 15,
            "minLength": 1,
            "type": "string",
            "description": "Billing address postal code, [See country codes with optional postalCode](/products/reference/supported-countries-currencies#postalcode-optional)"
          },
          "countryCode": {
            "maxLength": 2,
            "minLength": 2,
            "pattern": "^[A-Z]{2}$",
            "type": "string",
            "description": "Billing address country code"
          },
          "state": {
            "maxLength": 30,
            "minLength": 1,
            "type": "string",
            "description": "Billing address state. Should only be provided following the `ISO-3611-2` two-character sub division (e.g.“CA” for California). We recommend you provide this for US and China addresses."
          },
          "address2": {
            "maxLength": 80,
            "type": "string",
            "description": "Billing address line 2"
          },
          "address3": {
            "maxLength": 80,
            "type": "string",
            "description": "Billing address line 3"
          }
        }
      },
      "card_front": {
        "required": [
          "type",
          "cardNumber",
          "cardExpiryDate"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "card/front",
            "description": "An identifier for the `paymentInstrument` being used."
          },
          "cardHolderName": {
            "$ref": "#/components/schemas/cardHolderName"
          },
          "cardExpiryDate": {
            "required": [
              "month",
              "year"
            ],
            "type": "object",
            "description": "Object containing card expiry information",
            "properties": {
              "month": {
                "maximum": 12,
                "minimum": 1,
                "type": "integer",
                "description": "Card expiry month"
              },
              "year": {
                "maximum": 9999,
                "minimum": 1,
                "type": "integer",
                "description": "Card expiry year"
              }
            }
          },
          "cardNumber": {
            "maxLength": 19,
            "minLength": 10,
            "pattern": "^[0-9]*$",
            "type": "string",
            "description": "Clear card number (PAN)"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/billingAddress"
          }
        }
      },
      "card_tokenized": {
        "required": [
          "type",
          "href"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "card/tokenized",
            "description": "An identifier for the `paymentInstrument` being used."
          },
          "href": {
            "minLength": 1,
            "type": "string",
            "description": "An `http` address that contains your link to an Access Token"
          }
        }
      },
      "card_networktoken": {
        "required": [
          "type",
          "tokenNumber",
          "cardExpiryDate"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "card/networkToken",
            "description": "An identifier for the `paymentInstrument` being used."
          },
          "cardExpiryDate": {
            "required": [
              "month",
              "year"
            ],
            "type": "object",
            "description": "Object containing card expiry information",
            "properties": {
              "month": {
                "maximum": 12,
                "minimum": 1,
                "type": "integer",
                "description": "Card expiry month"
              },
              "year": {
                "maximum": 9999,
                "minimum": 1,
                "type": "integer",
                "description": "Card expiry year"
              }
            }
          },
          "tokenNumber": {
            "maxLength": 19,
            "minLength": 10,
            "pattern": "^[0-9]*$",
            "type": "string",
            "description": "The network token number"
          },
          "cardHolderName": {
            "$ref": "#/components/schemas/cardHolderName"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/billingAddress"
          }
        }
      },
      "3DS_deviceDataInitialize": {
        "required": [
          "transactionReference",
          "merchant"
        ],
        "type": "object",
        "properties": {
          "transactionReference": {
            "$ref": "#/components/schemas/transactionReference"
          },
          "merchant": {
            "$ref": "#/components/schemas/merchant"
          },
          "paymentInstrument": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/card_front"
              },
              {
                "$ref": "#/components/schemas/card_tokenized"
              },
              {
                "$ref": "#/components/schemas/card_networktoken"
              }
            ],
            "discriminator": {
              "mapping": {
                "card/front": "#/components/schemas/card_front",
                "card/tokenized": "#/components/schemas/card_tokenized",
                "card/networkToken": "#/components/schemas/card_networktoken"
              },
              "propertyName": "type"
            }
          }
        }
      }
    }
  }
}
```

### Device data initialization response

Best practice
Access Worldpay returns a `WP-CorrelationId` in the headers of service responses. We **highly recommend** you log this. The `WP-CorrelationId` is used by us to examine individual service requests.

To understand what these outcomes mean and how to reproduce them for testing purposes see [3DS testing](/products/3ds/testing)

JWT + BIN returned
JWT & BIN returned

```json JWT & BIN returned
  {
      "outcome": "initialized",
      "transactionReference": "Memory265-13/08/1876",
      "deviceDataCollection": {
          "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJPcmdVbml0SWQiOiJPcmdVbml0IiwiaXNzIjoiYXBpSWQiLCJleHAiOjE1NjI5MjMzNDYsImlhdCI6MTU2MjkyMzQwNiwianRpIjoiYTAzMWVhOGEtN2E0Zi00YTQwLWI1NjMtOTUzMzYzMzVhZGNmIn0.0IK74OIXBxFsxqeOURJz1TFnz14ZTbFJTdTWo9cHUJQ",
          "url": "https://ddcUrl.example.com",
          "bin": "555555"
      },
      "_links": {
          "3ds:authenticate": {
              "href": "https://try.access.worldpay-bsh.securedataplatform.com/verifications/customers/3ds/authentication"
          },
          "curies": [
              {
                  "href": "https://try.access.worldpay-bsh.securedataplatform.com/rels/verifications/customers/3ds/{rel}",
                  "templated": true,
                  "name": "3ds"
              }
          ]
      }
  }
```

JWT only
Only JWT returned

```json Only JWT returned
  {
      "outcome": "initialized",
      "transactionReference": "Memory265-13/08/1876",
      "deviceDataCollection": {
          "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJPcmdVbml0SWQiOiJPcmdVbml0IiwiaXNzIjoiYXBpSWQiLCJleHAiOjE1NjI5MjMzNDYsImlhdCI6MTU2MjkyMzQwNiwianRpIjoiYTAzMWVhOGEtN2E0Zi00YTQwLWI1NjMtOTUzMzYzMzVhZGNmIn0.0IK74OIXBxFsxqeOURJz1TFnz14ZTbFJTdTWo9cHUJQ",
          "url": "https://ddcUrl.example.com"
      },
      "_links": {
          "3ds:authenticate": {
              "href": "https://try.access.worldpay-bsh.securedataplatform.com/verifications/customers/3ds/authentication"
          },
          "curies": [
              {
                  "href": "https://try.access.worldpay-bsh.securedataplatform.com/rels/verifications/customers/3ds/{rel}",
                  "templated": true,
                  "name": "3ds"
              }
          ]
      }
  }
```

The `DeviceDataCollection` object will be used for the next step.


```json
{
  "$ref": "#/components/schemas/deviceDataCollection",
  "components": {
    "schemas": {
      "deviceDataCollection": {
        "required": [
          "jwt",
          "url"
        ],
        "type": "object",
        "description": "Object containing device data collection related information",
        "properties": {
          "jwt": {
            "maxLength": 2048,
            "minLength": 1,
            "type": "string",
            "description": "A digitally signed token that contains additional details required for DDC."
          },
          "url": {
            "maxLength": 2048,
            "minLength": 1,
            "type": "string",
            "description": "A `POST` action on the DDC form. Used to redirect to the issuers DDC page."
          },
          "bin": {
            "maxLength": 6,
            "minLength": 6,
            "type": "string",
            "description": "First six digits of the card number (Bank Identification Number), used as part of DDC. Returned if a token resource, network payment token or card number is included in the request."
          }
        }
      }
    }
  }
}
```

Note
In case of an error, you can get further information in our [error reference](/products/reference/worldpay-error-responses).

## Device Data Collection (DDC)

Once you have the `JWT`, `URL` and `BIN` you can create and submit the DDC form.

The issuer uses a `SessionId` representing this collection as part of the risk analysis in the [authentication request](/products/3ds/web/authentication).

### Test Data Collection form

Here's an example of how you would set-up the DDC form in an iframe.

1. Create a hidden iframe and set the `src` attribute with the URL of the page that POSTs the DDC form.
This URL should contain in query string parameters the `deviceDataCollection.jwt`, `deviceDataCollection.bin` and `deviceDataCollection.url` as those are used in the DDC form.


iframe for DDC form

```html iframe for DDC form
<iframe height="1" width="1" style="display: none;" src="replace-this-with-the-url-of-your-page-that-posts-the-ddc-form"></iframe>
```

1. Create and host the page that POSTs the DDC form.


DDC form

```html DDC form
<html>
<head>
</head>
<body>
<!-- Using your preferred programming language, set the 'action' attribute with the value of the query string parameter containing the 'deviceDataCollection.url' from the device data initialization response -->
<form id="collectionForm" name="devicedata" method="POST" action="https://ddcUrl.example.com">

<!-- Using your preferred programming language, set the 'value' attribute with the value of the query string parameter containing the 'deviceDataCollection.bin' from the device data initialization response -->
<input type="hidden" name="Bin" value="555555" />


<!-- Using your preferred programming language, set the 'value' attribute with the value of the query string parameter containing the 'deviceDataCollection.jwt' from the device data initialization response -->

 <input type="hidden" name="JWT" value="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJPcmdVbml0SWQiOiJPcmdVbml0IiwiaXNzIjoiYXBpSWQiLCJleHAiOjE1NjI5MjMzNDYsImlhdCI6MTU2MjkyMzQwNiwianRpIjoiYTAzMWVhOGEtN2E0Zi00YTQwLWI1NjMtOTUzMzYzMzVhZGNmIn0.0IK74OIXBxFsxqeOURJz1TFnz14ZTbFJTdTWo9cHUJQ" />

</form>

<script>
window.onload = function() {
  document.getElementById('collectionForm').submit();
 }
</script>
</body>
</html>
```

### Example device data form

The form below allows you to submit the 3DS device data details provided in the API response. You then receive the sessionId/collectionReference, back in the postMessage, for use in the [authentication](/products/3ds/web/authentication) request. This is useful if using tools such as postman/insomnia to test your integration.

Access 3ds - Device Data Collection form
### Device Data Collection postMessage

Once the DDC form is submitted and is successfully sent to the card issuer, you are notified via a [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) event.

For security, verify the sender's identity using the postMessage `origin` property as detailed [here](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).

| Environment | Origin |
|  --- | --- |
| Try | https://centinelapistag.cardinalcommerce.com |
| Production | https://centinelapi.cardinalcommerce.com |


An example postMessage response:

postmessage

```json postmessage
{
    "MessageType": "profile.completed",
    "SessionId": "0_3XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX6b5",
    "Status": true
}
```

| Key | Value |
|  --- | --- |
| `messageType` | `profile.completed` |
| `SessionId` | UUID, not present or `undefined` |
| `Status` | `true` - Use the `SessionId` value in `deviceData.collectionReference` as part of the [Authentication request](/products/3ds/web/authentication)`false` -  SessionId is empty. Either retry DDC or send the authentication request without the `deviceData.collectionReference`. |


The DDC call typically takes 1-2 seconds, depending on the latency between the customer's device, the Cardinal servers and, in part, the type of device data collection performed by the different issuers. The 3DS specification has the maximum response time at 10 seconds.

Note
If no postMessage is provided either retry DDC or send the [Authentication request](/products/3ds/web/authentication) without the `deviceData.collectionReference`. We **highly recommend** [providing device data](/products/3ds/web/authentication#how-much-data-to-provide) (e.g. browserScreenHeight) in the authentication request as well. This maximizes authentication rates in the case of DDC failure.

**Next steps**

[Authentication](/products/3ds/web/authentication)