> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lite.sa/llms.txt
> Use this file to discover all available pages before exploring further.

# 3DS Authentication

> Authenticate a cardholder with 3D Secure, then use the result to authorize a payment.

3D Secure (3DS) verifies that the person paying is the real cardholder. It shifts liability for fraudulent chargebacks from you to the card issuer, and for mada scheme and most Saudi card payments it is mandatory under SAMA rules for cardholder present payments.

This is the standalone 3DS API: you run authentication yourself, then pass the result into the payment API. If you use hosted checkout, sdk or payment links; lite runs 3DS in either redirection or embedded mode; you don't need to call the standalone APIs.

You can also let Payment API trigger 3DS for you with `threeds.force`, this standalone flow is for when you want to authenticate before, or separately from, the payment flow.

## How it works

1. **Create** an authentication session against a stored instrument with `POST /v1/threeds/authentications`.
2. **Check the result.** A frictionless authentication returns `AUTHENTICATED` right away. Otherwise the status is `CHALLENGE_REQUIRED`.
3. **Run the challenge.** Send the cardholder to the issuer's challenge using the session's `return_url`. They return to you when done.
4. **Confirm** the challenge with `POST /v1/threeds/authentications/{authentication_id}/confirm`.
5. **Authorize.** Pass the authentication result (`authentication_value`, `eci`, `version`, `ds_transaction_id`, `trans_status`) into the payment's `threeds.data`.

## Authentication status

| Status               | Meaning                                               |
| -------------------- | ----------------------------------------------------- |
| `PENDING`            | Created, awaiting processing.                         |
| `CHALLENGE_REQUIRED` | The cardholder must complete an issuer challenge.     |
| `AUTHENTICATED`      | The cardholder was authenticated. Ready to authorize. |
| `EXPIRED`            | The session expired before completion.                |
| `FAILED`             | Authentication failed or was rejected.                |

## Before you begin

Authenticate with `x-api-key`.

## Create an authentication session

`POST /v1/threeds/authentications`

Required: `instrument_id`, `customer`, `order`, and `return_url` (where the cardholder lands after a challenge). Include the `device` block so the issuer can attempt a frictionless flow.

```bash theme={null}
curl https://{{url}}/v1/threeds/authentications \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "instrument_id": "baf6a8e2-0c89-46ef-9ca5-faa65b99bcd5",
    "customer": { "email": "john.doe@email.com", "first_name": "john", "last_name": "doe" },
    "order": { "reference": "ORD-123456", "amount": 10000, "currency": "SAR" },
    "return_url": "https://example.com/threeds/callback",
    "device": {
      "ip": "192.168.1.100",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
      "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9",
      "language": "en-US",
      "screen_height": 1080,
      "screen_width": 1920,
      "color_depth": 24,
      "timezone": -180,
      "java_enabled": false,
      "java_script_enabled": true
    }
  }'
```

### Response

```json theme={null}
{
  "id": "baf6a8e2-0c89-46ef-9ca5-faa65b99bcd5",
  "merchant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "instrument_id": "baf6a8e2-0c89-46ef-9ca5-faa65b99bcd5",
  "status": "AUTHENTICATED",
  "authentication_value": "AAABBJkZUgAAAAAAAAAAAAAAAAA=",
  "eci": "05",
  "version": "2.1.0",
  "ds_transaction_id": "dstxn_a1b2c3d4e5f6",
  "trans_status": "Y",
  "return_url": "https://example.com/threeds/callback"
}
```

If `status` is `AUTHENTICATED`, skip to authorizing the payment. If it is `CHALLENGE_REQUIRED`, run the challenge next. The response also carries the directory server and ACS identifiers (`threeds_server_trans_id`, `acs_transaction_id`) for diagnostics.

## Run and confirm the challenge

When a challenge is required, send the cardholder to the issuer's challenge screen and have them return to your `return_url`. Then confirm:

`POST /v1/threeds/authentications/{authentication_id}/confirm`

```bash theme={null}
curl https://{{url}}/v1/threeds/authentications/{authentication_id}/confirm \
  -H "x-api-key: $LITE_API_KEY"
```

The session must be in `CHALLENGE_REQUIRED` when you call this, otherwise you get `400` with the current status in the message. On success it returns `200`; re-fetch the session to read the final `AUTHENTICATED` result.

## Get an authentication session

`GET /v1/threeds/authentications/{authentication_id}`

Returns the session in the same shape as create, use it to read the final status and authentication values after a challenge.

```bash theme={null}
curl https://{{url}}/v1/threeds/authentications/{authentication_id} \
  -H "x-api-key: $LITE_API_KEY"
```

## Use the result in a payment

Pass the authenticated values into the payment's `threeds.data`:

```json theme={null}
{
  "amount": 10000,
  "currency": "SAR",
  "payment_instrument": { "id": "baf6a8e2-0c89-46ef-9ca5-faa65b99bcd5" },
  "threeds": {
    "data": {
      "authentication_value": "AAABBJkZUgAAAAAAAAAAAAAAAAA=",
      "eci": "05",
      "version": "2.1.0",
      "ds_transaction_id": "dstxn_a1b2c3d4e5f6",
      "trans_status": "Y"
    }
  },
  "device": { "...": "required" }
}
```

## Errors

| Code  | Meaning                                                            |
| ----- | ------------------------------------------------------------------ |
| `400` | The session is not in `CHALLENGE_REQUIRED` (confirm only).         |
| `401` | Authentication failed. The API key or token is missing or invalid. |
