# 3D Secure

[3D Secure](https://www.emvco.com/emv-technologies/3-d-secure/) (3DS) is a protocol governed by EMVCo that lets you verify a cardholder's identity before a card payment is authorized. Unlike card authorizations, 3DS follows a strict state machine with well-defined stages. When a merchant initiates a 3DS authentication attempt, Increase creates a `card_authentication` entry on the [Card Payment](/documentation/api/card-payments).

The 3DS API is composed of a few parts:

- **Card Payments API:** The `card_authentication` element under a Card Payment covers the lifecycle of a 3DS authentication attempt.
- **Real-Time Decisions API:** Two real-time decision categories, `card_authentication_requested` and `card_authentication_challenge_requested`, let you control the authentication flow.
- **Simulations API:** Sandbox endpoints for testing the full authentication flow.

## Authentication lifecycle

![3D Secure authentication statuses](/images/3ds.png)

A `card_authentication` progresses through a series of statuses as the authentication attempt is processed. Here is a typical challenge-based flow:

1. We receive an authentication request from Visa with metadata about the purchase. You receive a `card_authentication_requested` [real-time decision](/documentation/real-time-decisions) and decide to request a challenge. The authentication moves to `awaiting_challenge`.
2. The cardholder's client (a browser or app) connects to Increase to initiate the challenge. We generate a one-time code and send you a `card_authentication_challenge_requested` real-time decision containing the code. You deliver it to your cardholder via text message or email. The authentication moves to `validating_challenge`.
3. The cardholder enters the one-time code. If correct, the authentication moves to `authenticated_with_challenge`. We generate a cryptographic Cardholder Authentication Verification Value (CAVV) that is sent to the acquirer through Visa.
4. The acquirer kicks off the card authorization, including the CAVV in the authorization message to tie it to the successful authentication. The Card Payment now has both a `card_authentication` and a `card_authorization` element.

If at step 1 you are confident in the transaction, you can approve the authentication directly. This results in a status of `authenticated_without_challenge` and skips the challenge steps entirely.

### Statuses

| Status                            | Description                                                                                   |
| --------------------------------- | --------------------------------------------------------------------------------------------- |
| `authenticated_without_challenge` | Approved without requiring a challenge.                                                       |
| `awaiting_challenge`              | A challenge has been requested and we are waiting for the cardholder's client to initiate it. |
| `validating_challenge`            | The challenge is in progress and the cardholder is entering their one-time code.              |
| `authenticated_with_challenge`    | The cardholder successfully completed the challenge.                                          |
| `denied`                          | The authentication attempt was denied.                                                        |
| `canceled`                        | The authentication was canceled.                                                              |
| `timed_out_awaiting_challenge`    | The cardholder's client did not initiate the challenge in time.                               |
| `exceeded_attempt_threshold`      | The cardholder exceeded the maximum number of challenge attempts.                             |
| `errored`                         | An error occurred during the authentication.                                                  |

## Real-time decisions

We recommend first reading our [Real-Time Decisions guide](/documentation/real-time-decisions) for background on how real-time webhooks work.

### Responding to authentication requests

![card_authentication_requested real-time decision](/images/card_authentication_requested.png)

When a merchant attempts to authenticate a purchase, Increase creates a Real-Time Decision with `category: card_authentication_requested`. This comes with metadata about the purchase including merchant details and the purchase amount. Your application decides how to proceed:

- **`approve`**: Authenticate the transaction without a challenge (frictionless).
- **`challenge`**: Request the cardholder to verify their identity with a one-time code.
- **`deny`**: Deny the authentication attempt outright.

To action the decision, `POST` to the Real-Time Decision action endpoint:

```curl
curl -X "POST" \
  --url "https://api.increase.com/real_time_decisions/${REAL_TIME_DECISION_ID}/action" \
  -H "Authorization: Bearer ${INCREASE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "card_authentication": {
      "decision": "challenge"
    }
  }'
```

### Delivering the challenge

![card_authentication_challenge_requested real-time decision](/images/card_authentication_challenge_requested.png)

If you request a challenge, the cardholder's client (browser or app) will connect to Increase to start the challenge process. Increase creates a second Real-Time Decision with `category: card_authentication_challenge_requested`. This decision includes a `one_time_code` that you must deliver to your cardholder via text message or email.

Once you've delivered the code, action the decision with the result:

```curl
curl -X "POST" \
  --url "https://api.increase.com/real_time_decisions/${REAL_TIME_DECISION_ID}/action" \
  -H "Authorization: Bearer ${INCREASE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "card_authentication_challenge": {
      "result": "success"
    }
  }'
```

If your application is unable to deliver the one-time code, respond with `"result": "failure"`.

After the challenge is delivered, Increase renders an interface to the cardholder where they enter the one-time code. We validate their attempts and update the `card_authentication` status accordingly.

## Testing in sandbox

You can simulate the end-to-end authentication flow using three sandbox endpoints.

### 1. Simulate an authentication attempt

[Create a simulated 3DS authentication request](/documentation/api/card-payments#sandbox-create-a-card-authentication-attempt) for a card:

```curl
curl -X "POST" \
  --url "${INCREASE_URL}/simulations/card_authentications" \
  -H "Authorization: Bearer ${INCREASE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "card_id": "card_oubs0hwk5rn6knuecxg2"
  }'
```

This returns a Card Payment with a `card_authentication` element. If you have a `card_authentication_requested` real-time decision subscription, you'll receive the webhook and can action the decision.

### 2. Simulate initiating a challenge

After requesting a challenge, [simulate the cardholder's client connecting](/documentation/api/card-payments#sandbox-create-an-initial-card-authentication-challenge) to start the challenge:

```curl
curl -X "POST" \
  --url "${INCREASE_URL}/simulations/card_authentications/${CARD_PAYMENT_ID}/challenges" \
  -H "Authorization: Bearer ${INCREASE_API_KEY}"
```

This triggers the `card_authentication_challenge_requested` real-time decision with the one-time code.

### 3. Simulate a challenge attempt

[Simulate the cardholder entering the one-time code](/documentation/api/card-payments#sandbox-create-a-card-authentication-challenge-attempt):

```curl
curl -X "POST" \
  --url "${INCREASE_URL}/simulations/card_authentications/${CARD_PAYMENT_ID}/challenge_attempts" \
  -H "Authorization: Bearer ${INCREASE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "one_time_code": "123456"
  }'
```

Alternatively, you can navigate to `https://dashboard.increase.com/card_authentication_simulation/${CARD_PAYMENT_ID}` and enter the one-time code directly.

If the code matches, the `card_authentication` status moves to `authenticated_with_challenge`.
