# 3D Secure

_3D Secure is an online payment security protocol designed to reduce fraud and provide an additional layer of authentication for online transactions._

![An illustration of a 3D Secure authentication process]()

3D Secure is an online payment security protocol designed to reduce fraud and provide an additional layer of authentication for online transactions. When a customer makes an online purchase, 3D Secure requires them to complete an additional verification step with the card issuer, typically through a password, biometric authentication, or a one-time passcode sent over SMS.

> **Pricing**
>
> 3D Secure production usage is covered by the [Platform plan](https://evervault.com/pricing).
>
> You can use [Sandbox apps](/developers/sandbox) to try it for free and test the full 3D Secure Authentication process without using live data. Once you're ready to transition to processing real authentications, please contact our support team at [support@evervault.com](mailto:support@evervault.com).

## The benefits of 3D Secure

Implementing 3D Secure for online payments provides several benefits for both merchants and customers, enhancing overall transaction security and achieving regulatory compliance.

- **Reduced fraud**: By requiring an additional authentication step, 3D Secure significantly decreases the risk of unauthorized transactions. This added security measure helps to ensure that the person using the card online is the legitimate cardholder.
- **Liability shift**: One of the key advantages for merchants using 3D Secure is the liability shift. If a transaction is authenticated using 3D Secure and later turns out to be fraudulent, the liability for the chargeback shifts from the merchant to the card issuer. This can result in substantial cost savings and reduced chargeback rates for merchants.
- **Regulatory compliance**: With the increasing emphasis on online transaction security and regulations such as PSD2/SCA in Europe, implementing 3D Secure helps merchants comply with these regulations and avoid potential fines and penalties.

## How 3D Secure works

3D Secure consists of several steps involving merchants, card networks, and card issuers to allow customers to be authenticated during online purchases. At a high level, a standard challenge flow looks like this.

![A visual flow diagram depicting the 3D Secure payment process in three steps, Payment initialized, Issuer Challenge and Process Payment.]()

1. **Payment initiation**: When a customer initiates an online purchase and enters their card details on the merchant's website, the merchant recognizes that the card is enrolled in 3D Secure and triggers the authentication process.
2. **Issuer challenge**: The customer is redirected to a web page hosted by their card issuer where the customer is asked to authenticate themselves. This can be done through various methods, such as entering a static password, a one-time password (OTP) sent over SMS, or using biometric authentication (e.g., fingerprint or facial recognition).
3. **Process payment**: If the authentication is successful, the merchant processes the authenticated transaction and the customer is redirected back to the merchant's website with a confirmation of their purchase. If the authentication fails or isn't completed, the transaction is typically declined, and the customer is informed of the failure.

3DS supports frictionless authentications as well, which require no interaction from the customer. A frictionless flow is initiated when the issuer determines that a transaction is low-risk, eliminating the need for additional verification steps. Frictionless authentications aren't always possible, but they provide a much smoother customer experience because there's no challenge displayed to the customer, meaning there's no action for them to take.

### 3DS with Evervault

Although the 3DS protocol is known for being difficult to work with, we built our solution from scratch (and we run our own 3DS server). We did this to make our API straightforward to use. We don't wrap other solutions, and our API isn't just a one-to-one mapping of the 3DS protocol. We manage a lot of the complexity for you, and surface just the parts you need to configure and control 3DS the way you want to. Completing a 3DS authentication with Evervault takes three steps:

1. Create the session
2. Run the session on your frontend
3. Retrieve and forward authentication credentials as needed

That last step is an important differentiator. Because our solution is standalone, you can use 3DS authentications with any downstream partner. This is especially important for integrating with multiple payment service providers (PSPs). You could integrate with each PSP and use their 3DS solutions, but there are some issues with that. You're limited on the configuration side to whatever the PSPs allow, and it makes for an inconsistent customer experience because each 3DS implementation is different. Evervault lets you configure your own 3DS flows, and then share the results with any PSP, and customers always see the same interface.

## Get started with 3D Secure

To start, you need to create a [Sandbox app](/developers/sandbox). Sandbox apps allow you to test 3D Secure without affecting live data. When you're ready to go live, [contact our support team](mailto:support@evervault.com) to enable 3D Secure on your production app.

> **Configuring acquirers**
>
> Acquirer details aren't required when testing in [Sandbox](/developers/sandbox) mode. However, you must [configure acquirer details](#configuring-acquirer-details) before moving to production.

### 1. Create a 3DS session

Use the [create session](/api#createThreeDSSession) endpoint by providing the card (in encrypted form using our [card collection](/cards/card-collection), as a network token, or in plaintext), merchant, and payment details. Do this from your backend and then pass the session ID to your client code.

#### Node

```javascript
const response = await fetch("https://api.evervault.com/payments/3ds-sessions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Basic <credentials>"
  },
  body: {
    card: {
      number: "4242424242424242",
      expiry: {
        month: "05",
        year: "25"
      }
    },
    merchant: {
      name: "Ollivanders Wand Shop",
      website: "https://www.ollivanders.co.uk",
      categoryCode: "5945",
      country: "ie"
    },
    payment: {
      amount: 1000,
      currency: "eur"
    }
  }
})

const session = await response.json();

[ANNOTATION lines=9-9]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]

```

#### Ruby

```ruby
response = HTTParty.post(
  "https://api.evervault.com/payments/3ds-sessions",
  headers: {
    "Content-Type" => "application/json",
    "Authorization" => "Basic <credentials>"
  },
  body: {
    card: {
      number: "4242424242424242",
      expiry: {
        month: "05",
        year: "25"
      }
    },
    merchant: {
      name: "Ollivanders Wand Shop",
      website: "https://www.ollivanders.co.uk",
      categoryCode: "5945",
      country: "ie"
    },
    payment: {
      amount: 1000,
      currency: "eur"
    }
  }.to_json
)

session = JSON.parse(response.body)

[ANNOTATION lines=9-9]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]

```

#### Python

```python
import requests
import json

response = requests.post(
  "https://api.evervault.com/payments/3ds-sessions",
  headers={
    "Content-Type": "application/json",
    "Authorization": "Basic <credentials>"
  },
  json={
    "card": {
      "number": "4242424242424242",
      "expiry": {
        "month": "05",
        "year": "25"
      }
    },
    "merchant": {
      "name": "Ollivanders Wand Shop",
      "website": "https://www.ollivanders.co.uk",
      "categoryCode": "5945",
      "country": "ie"
    },
    "payment": {
      "amount": 1000,
      "currency": "eur"
    }
  }
)

session = response.json()

[ANNOTATION lines=12-12]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]

```

#### PHP

```php
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.evervault.com/payments/3ds-sessions",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/json",
    "Authorization: Basic {credentials}"
  ],
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode([
    "card" => [
      "number" => "4242424242424242",
      "expiry" => [
        "month" => "05",
        "year" => "25"
      ]
    ],
    "merchant" => [
      "name" => "Ollivanders Wand Shop",
      "website" => "https://www.ollivanders.co.uk",
      "categoryCode" => "5945",
      "country" => "ie"
    ],
    "payment" => [
      "amount" => 1000,
      "currency" => "eur"
    ]
  ])
]);

$response = curl_exec($curl);
$session = json_decode($response, true);

curl_close($curl);

[ANNOTATION lines=13-13]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]

```

#### Java

```java
URL url = new URL("https://api.evervault.com/payments/3ds-sessions");

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Basic <credentials>");
conn.setDoOutput(true);

String jsonInputString = "{"
    + "\"card\": {"
    + "    \"number\": \"4242424242424242\","
    + "    \"expiry\": {"
    + "        \"month\": \"05\","
    + "        \"year\": \"25\""
    + "    }"
    + "},"
    + "\"merchant\": {"
    + "    \"name\": \"Ollivanders Wand Shop\","
    + "    \"website\": \"https://www.ollivanders.co.uk\","
    + "    \"categoryCode\": \"5945\","
    + "    \"country\": \"ie\""
    + "},"
    + "\"payment\": {"
    + "    \"amount\": 1000,"
    + "    \"currency\": \"eur\""
    + "}"
+ "}";

try(OutputStream os = conn.getOutputStream()) {
    byte[] input = jsonInputString.getBytes("utf-8");
    os.write(input, 0, input.length);
}

try(BufferedReader br = new BufferedReader(
    new InputStreamReader(conn.getInputStream(), "utf-8"))) {
    StringBuilder response = new StringBuilder();
    String responseLine = null;
    while ((responseLine = br.readLine()) != null) {
        response.append(responseLine.trim());
    }
    JSONObject session = new JSONObject(response.toString());
}

[ANNOTATION lines=12-12]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]

```

#### Go

```go
client := &http.Client{}
jsonData := map[string]interface{}{
    "card": map[string]interface{}{
        "number": "4242424242424242",
        "expiry": map[string]interface{}{
            "month": "05",
            "year": "25",
        },
    },
    "merchant": map[string]interface{}{
        "name": "Ollivanders Wand Shop",
        "website": "https://www.ollivanders.co.uk",
        "categoryCode": "5945",
        "country": "ie",
    },
    "payment": map[string]interface{}{
        "amount": 1000,
        "currency": "eur",
    },
}

jsonValue, _ := json.Marshal(jsonData)
req, _ := http.NewRequest("POST", "https://api.evervault.com/payments/3ds-sessions", bytes.NewBuffer(jsonValue))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Basic <credentials>")

resp, _ := client.Do(req)
defer resp.Body.Close()

body, _ := ioutil.ReadAll(resp.Body)
var session map[string]interface{}
json.Unmarshal(body, &session)

[ANNOTATION lines=4-4]
You can also provide an encrypted card number to prevent having plaintext card numbers in your infrastructure.
[/ANNOTATION]
```

#### 3DS Requestor Initiated (3RI) transactions

Merchant-initiated transactions (MIT) are commonly used to charge customers for subscriptions, installment payments, etc. 3RIs are a form of MIT that include a 3DS authentication without the cardholder being present (flows are frictionless and either succeed or fail, there's no challenge involved). These 3RIs are often used instead of standard MITs because they can improve acceptance rates and may still result in liability shift (moving chargeback liability from you to the issuer).

To use 3RIs, you still complete initial 3DS sessions with customers. You keep track of the session ID, and then you use it later to create a 3RI which carries over the authentication. To create a 3RI transaction, set the:

- [Initiator type](/api#createThreeDSSession-request-initiator) to `merchant`
- [initialSession](/api#createThreeDSSession-request-initiator-initialsession) to the [ID returned from the original session](/api#createThreeDSSession-response-initiator-initialsession) or a `threeDSServerTransactionID`
- [Payment type](/api#createThreeDSSession-request-payment) to `recurring` or `installment`

### 2. Run the session on your frontend

After creating the session, use our client-side SDKs to complete the authentication flow on your frontend. If for some reason you can't use our SDKs, you can try [using a redirect](#using-a-page-redirect) but Evervault doesn't generally recommend this (redirects add friction to the customer experience).

#### Browser

#### Install the SDK

Our [JavaScript SDK](/sdks/javascript) is distributed from our CDN, and can be installed by placing this script tag in the head of your HTML file. The SDK must be loaded directly from our CDN and cannot be bundled with your application or self hosted.

```html
<script src="https://js.evervault.com/v2"></script>
```

Once the SDK is installed, initialize it using your Team ID and App ID. You can find these in the [Evervault Dashboard](https://app.evervault.com).

```javascript
const evervault = new Evervault("<TEAM_ID>", "<APP_ID>");
```

You can also install Evervault via the `@evervault/js` package on npm. This package is a light wrapper which handles loading the SDK from our CDN and also provides TypeScript definitions.

```javascript
import { loadEvervault } from "@evervault/js";

const evervault = loadEvervault("<TEAM_ID>", "<APP_ID>");
```

#### Frequently Asked Questions

##### Why does the SDK need to be loaded from the CDN?

The SDK must be loaded directly from our CDN in order to be PCI Compliant.

##### How do I get my Team ID and App ID?

You can find your Team ID and App ID in the [Evervault Dashboard](https://app.evervault.com).

##### Can I load the SDK asynchronously?

You can load the SDK asynchronously using the `async` attribute on the script tag to prevent blocking the loading of your page. However, it is important to note that you will need to wait for the SDK to load before making any API calls.

    ```html
    <!DOCTYPE html>
    <html>
      <head>
        <script src="https://js.evervault.com/v2" onload="onEvervaultReady()" async></script>
        <script>
          function onEvervaultReady() {
            const evervault = new Evervault('<TEAM_ID>', '<APP_ID>');
          }
        </script>
      </head>
    </html>
    ```

#### Start the authentication

The `ThreeDSecure` component can be initiated using the `evervault.ui.threeDSecure` method by passing the session ID obtained in the previous step. After you initialize the `ThreeDSecure` component, call the `.mount()` method to open the 3DS modal in the customer's browser to start the authentication process. The `success` event will be fired after the authentication process completes. The `failure` event will be fired if the authentication process fails (e.g., the customer failed to authenticate). These callbacks occur regardless of whether there was a challenge or if the flow was frictionless.

```javascript
const evervault = new Evervault("{{TEAM_ID}}", "{{APP_ID}}");
const threeDSecure = evervault.ui.threeDSecure("tds_visa_5a9a7b0a574c");

threeDSecure.on("success", () => {
  // 3DS is complete and payment can be finalized
});

threeDSecure.on("failure", () => {
  // 3DS failed. Try again.
});

threeDSecure.mount();
```

Learn more about the [JavaScript SDK](/sdks/javascript).

#### React

#### Install the SDK

Our React SDK is distributed via npm and can be installed using your preferred package manager.

Once installed, Initialize the SDK by wrapping your application with the `EvervaultProvider` component.

```jsx
import { EvervaultProvider } from "@evervault/react";

export default function App() {
  return (
    <EvervaultProvider teamId="<TEAM_ID>" appId="<APP_ID>">
      ...
    </EvervaultProvider>
  );
}
```

#### Start the authentication

The `useThreeDSecure` hook returns a `ThreeDSecure` object you can use to run the authentication. After you initialize the hook, call the start method with the session ID from the previous step to start the authentication process. The `onSuccess` callback will be fired after the authentication process completes. The `onFailure` callback will be fired if the authentication process fails (e.g., the customer failed to authenticate). These callbacks occur regardless of whether there was a challenge or if the flow was frictionless.

```jsx filename='app.jsx'
import { Card, useThreeDSecure } from "@evervault/react";
import { createThreeDSSession, finalizePayment } from "./api";

function Checkout() {
  const threeDSecure = useThreeDSecure();
  const handlePay = async () => {
    const sessionId = await createThreeDSSession();
    threeDSecure.start(sessionId, {
      onSuccess: () => {
        // 3DS is complete and payment can be finalized
      },
      onFailure: () => {
        // 3DS failed.
      },
    });
  };
  return (
    <>
      <Card />
      <button onClick={handlePay}>Pay</button>
    </>
  );
}
```

Learn more about the [React SDK](/sdks/react).

#### React Native

#### Install the SDK

Our React Native SDK is distributed via `npm` and can be installed using your preferred package manager. The [react-native-webview](https://www.npmjs.com/package/react-native-webview) package is a peer dependency and will need to be installed as well.

Once installed, Initialize the SDK by wrapping your application with the `EvervaultProvider` component.

```jsx
import { EvervaultProvider } from "@evervault/react-native";

export default function App() {
  return (
    <EvervaultProvider teamId="<TEAM_ID>" appId="<APP_ID>">
      ...
    </EvervaultProvider>
  );
}
```

#### Start the authentication

The `useThreeDSecure` hook returns a `ThreeDSecure` object you can use to run the authentication. After you initialize the hook, call the start method with the session ID from the previous step to start the authentication process. The `onSuccess` callback will be fired after the authentication process completes. The `onFailure` callback will be fired if the authentication process fails (e.g., the customer failed to authenticate). These callbacks occur regardless of whether there was a challenge or if the flow was frictionless.

```jsx
import { ThreeDSecure, useThreeDSecure } from "@evervault/react-native";
import { createThreeDSSession } from "@your/api";
import { Button, Form, Modal } from "@your/ui";

function CustomCheckout() {
  const tds = useThreeDSecure();

  async function handlePayment() {
    // Create a 3DS session on your backend
    const sessionId = await create3DSecureSession();

    tds.start(sessionId, {
      onSuccess: () => {
        console.log("3DS successful");
      },
      onFailure: (error: Error) => {
        console.error("3DS failed", error);
      },
    });
  }

  return (
    <Form>
      <Button onPress={handlePayment}>Pay</Button>

      <ThreeDSecure state={tds}>
        <Modal onRequestClose={tds.cancel}>
          <ThreeDSecure.Frame />
        </Modal>
      </ThreeDSecure>
    </Form>
  );
}
```

Learn more about the [React Native SDK](/sdks/react-native).

#### Frequently Asked Questions

##### Can I customize the styling for the challenge?

The contents of the modal are controlled by the bank and cannot be
    customized.

### 3. Retrieve and forward authentication credentials

After completing the authentication, you can [retrieve](/api#retrieveThreeDSSession) information about the session as needed. To process the transaction and ensure liability is shifted, pass the raw Electronic Commerce Indicator (ECI) and 3DS cryptogram to your payment gateway or PSP.

#### Node

```javascript
const response = await fetch(
  "https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c",
  {
    headers: {
      Authorization: "Basic <credentials>",
    },
  }
);

const session = await response.json();

console.log(session.cryptogram);
// MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

console.log(session.eci);
// { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

#### Ruby

```ruby
response = HTTParty.get('https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c', {
  headers: {
    'Authorization': 'Basic <credentials>'
  }
})

session = JSON.parse(response.body)

puts session.cryptogram
# MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

puts session.eci
# { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

#### Python

```python
import requests

response = requests.get('https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c', headers={'Authorization': 'Basic <credentials>'})

session = response.json()

print(session.cryptogram)
# MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

print(session.eci)
# { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

#### PHP

```php
$response = Http::get('https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c', [
  'headers' => [
    'Authorization' => 'Basic <credentials>'
  ]
]);

$session = json_decode($response->body());

print($session->cryptogram);
# MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

print($session->eci);
# { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

#### Java

```java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(new URI("https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c"))
    .header("Authorization", "Basic <credentials>")
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

var session = JsonConvert.DeserializeObject<Dictionary<string, object>>(response.Body);

System.Console.WriteLine(session.cryptogram);
// MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

System.Console.WriteLine(session.eci);
// { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

#### Go

```go
client := &http.Client{}
req, _ := http.NewRequest("GET", "https://api.evervault.com/payments/3ds-sessions/tds_visa_5a9a7b0a574c", nil)
req.Header.Set("Authorization", "Basic <credentials>")

resp, _ := client.Do(req)
defer resp.Body.Close()

body, _ := ioutil.ReadAll(resp.Body)
var session map[string]interface{}
json.Unmarshal(body, &session)

fmt.Println(session.cryptogram)
// MTIzNDU2Nzg5MDA5ODc2NTQzMjE=

fmt.Println(session.eci)
// { "value": "05", "descriptor": "fully-authenticated", "liabilityShift": true }
```

In some cases, downstream partners might also require one or more of these IDs:

- [threeDSServer.transactionIdentifier](/api#retrieveThreeDSSession-response-threedsserver-transactionidentifier)
- [directoryServer.transactionIdentifier](/api#retrieveThreeDSSession-response-directoryserver-transactionidentifier)
- [accessControlServer.transactionIdentifier](/api#retrieveThreeDSSession-response-accesscontrolserver-transactionidentifier)

These values are specific to the 3DS protocol, and not Evervault. They're sometimes requested in addition to the ECI and cryptogram, but not every provider requires them.

## Configuring acquirer details

Acquirer details aren't required in [Sandbox](/developers/sandbox) mode but you do need them to use 3DS in production. Evervault automatically passes this information in when 3DS sessions are created, although you can [pass values in manually](#provide-acquirer-details-per-request) yourself.

You can configure acquirers in the [dashboard](https://app.evervault.com/app/payments/acquirers) or with the [API](/api#createAcquirer), and you can set up default acquirers for each card network (Visa, Mastercard, etc.). When creating a 3DS session, Evervault uses the appropriate acquirer configuration based on the card network. Configurations are specific to each app, so you need to configure these for your staging and production apps separately.

### Acquirer info request template

If you need to obtain acquirer information from one of your partners (e.g., PSPs), you can use the template message below to request it. It covers everything you need to configure acquirers within Evervault.

```md
Hi,

We're currently integrating Evervault as our 3D-Secure (3DS) Server provider and need to collect some information related to our merchant account to unblock our integration.
Could you please provide the following details for each network we're set up with? There should be different acquirer BIN values for each of Visa, Mastercard, Discover, and American Express.

- Merchant ID (MID): Our merchant account number/merchant ID.
- Acquirer BIN: The numeric identifier you've received from each card network to represent the underlying acquiring bank. These should be 6-10 digits in length.
- Merchant Name: The official name you have on file for us.
- Merchant Category Code (MCC): Our four-digit business classification assigned by the card networks.

Thank you!
```

### Provide acquirer details per request

Alternatively, you can provide acquirer details when creating each 3DS session by including the [acquirer object](/api#createThreeDSSession-request-acquirer) in your API request. This approach is useful if you work with multiple acquirers or need to specify different acquirer details for different transactions. However, supplying acquirer details per request adds complexity to your integration. You'll likely need to perform a BIN lookup to identify the card network, so that you can then decide which acquirer BIN or MID values to provide for each transaction.

### How Evervault resolves acquirer details

When you create a 3DS session, Evervault follows this process to determine which acquirer configuration to use:

1. If your request includes an `acquirer` object, those details are used.
2. If your request includes an ID of an acquirer configuration in the `acquirer` field, that configuration is used.
3. If no acquirer details are provided in the request, Evervault uses the default acquirer configuration for the card's network, if available.
4. If no acquirer details can be resolved, session creation fails.

## Testing your implementation

Provided you are using a Sandbox app, you can use specific test cards to simulate various real-life scenarios. These cards can be used in conjunction with any valid expiry date or CVC.

| Number | Brand |
| --- | --- |
| **3D Secure challenge flow** | |
| 4242 4242 4242 4242 | Visa |
| 5555 5555 5555 4444 | Mastercard |
| 3714 4963 5398 431 | American Express |
| 6011 1111 1111 1117 | Discover |
| 3622 720627 1667 | Diners Club |
| **Successful frictionless flow** | |
| 4111 1101 1663 8870 | Visa |
| 5555 5501 3065 9057 | Mastercard |
| 3782 8224 6310 005 | American Express |
| 6011 0009 3838 5477 | Discover |
| 3622 720638 3827 | Diners Club |
| **Failed frictionless flow** | |
| 4111 1117 3897 3695 | Visa |
| 5555 5504 8784 7545 | Mastercard |
| 3782 8224 6310 013 | American Express |
| 6011 0009 3838 3100 | Discover |
| 3622 720638 3835 | Diners Club |
| **Attempted authentication** | |
| 4111 1101 4848 6405 | Visa |
| 5555 5588 2481 5604 | Mastercard |
| 3782 8224 6310 021 | American Express |
| 6011 0009 3838 7572 | Discover |
| 3622 720638 3850 | Diners Club |

## Alternative configurations

These alternative configurations mostly relate to using redirects and the `failOnChallenge` flag. Both have somewhat niche use cases but can be useful in the right situations.

### Using failOnChallenge

3DS supports frictionless and challenge flows. Frictionless authentication requires no interaction from the customer (and maintains liability shift). The frictionless flow automatically occurs when the issuer determines that a transaction is low-risk, eliminating the need for additional verification steps. This is a much smoother customer experience.

In challenge flows, customers are required to complete an authentication step to verify their identity. This is higher friction and usually requires a password, biometric authentication, etc.

The issuer decides on the flow, but Evervault provides an additional flag that can reduce friction when a challenge is requested. When you create 3DS sessions, you can set `failOnChallenge` to `true`. If a challenge is requested, Evervault automatically fails the 3DS session which prevents the challenge from ever being shown to the customer. This isn't technically a frictionless flow in terms of 3DS, but it does allow you to skip the challenge.

#### Browser

```javascript
const tds = evervault.ui.threeDSecure("tds_visa_5a9a7b0a574c", {
  failOnChallenge: true,
});
```

#### React

```jsx
const threeDSecure = useThreeDSecure({
  failOnChallenge: true,
});
```

> **EU transactions**
>
> The challenge flow is required for EU transactions and as a result
>   frictionless-only 3D Secure isn't supported by banks in the EU.

### Using a page redirect

The 3D Secure challenge can also be loaded directly—either through a full page redirect or served within an `<iframe>` or mobile web view. In this scenario, fingerprinting and challenge windows are presented directly in the user's browser. Once the 3D Secure authentication has been finalized (with either a success, a failure, or an error) the page is redirected back to a callback URL of your choice.

```text
https://3ds.evervault.com/?team=<TEAM>&app=<APP>&session=session&redirect=redirect
```

Once the 3D Secure session has been finalized, the page will redirect back to the URL provided in the redirect parameter with `status` and `session` appended to the URL parameters. More details about the 3D Secure Session can be retrieved from our API.

**URL Parameters**

- `team` — The Team ID found in the [Evervault Dashboard](https://app.evervault.com).
- `app` — The App ID found in the [Evervault Dashboard](https://app.evervault.com).
- `session` — The 3D Secure session ID.
- `redirect` — The URL to redirect to once the 3D Secure session has been completed. Additional URL parameters will be appended to this URL. Deep links are also supported for mobile implementations. For example, if you provided 'https://3ds-redirect.testmerchant.com' as the redirect, the user's browser would redirect to 'https://3ds-redirect.testmerchant.com/?status=success&session=tds_abc123'. Status can be `success`, `failure`, or `error`

- [Network Tokens](/cards/network-tokens): Learn how to use Network Tokens to enhance your payment security.
- [Card Account Updater](/cards/card-account-updater): Learn how to use Card Account Updater to automatically update card details.

