# 3-D Secure (3DS) (/en/docs/cartao/three-d-secure)

<QuickLinks>
  <QuickLink href="/docs/cartao/endpoints/charges/post_charges" title="Create charge" method="POST" path="/charges" />

  <QuickLink href="/docs/cartao/test-cards" title="3DS test cards" />

  <QuickLink href="/docs/cartao/antifraud" title="Antifraud" />
</QuickLinks>

**3DS** confirms with the issuing bank that the person paying really is the cardholder. Authenticating the transaction reduces fraud and, when authentication completes successfully, shifts chargeback liability to the issuer or the card brand.

During the 3DS authentication process, buyer information is shared with
the card networks and the issuing bank, which assess the transaction risk
and decide whether a **challenge** (such as an SMS code or authentication
in the bank's app) is required to validate the cardholder's identity.

### Benefits [#benefits]

* Fraud reduction
* **Liability shift** on authenticated transactions: the issuer or the
  card network takes responsibility in case of chargeback
* Simple integration via JavaScript
* Support for **frictionless** authentication (no visible challenge for
  the buyer) when the transaction risk is considered low

## Authentication flow [#authentication-flow]

<Mermaid
  chart="`
flowchart TD
  A[&#x22;Load and initialize the 3DS script&#x22;]
  A --> B[&#x22;payzu3DS.checkout(paymentObject)&#x22;]
  B --> C{&#x22;Card eligible?&#x22;}
  C -->|No| D[&#x22;unenrolled event: only Eci is returned&#x22;]
  C -->|Yes| E[&#x22;Network and issuer assess the risk&#x22;]
  E --> F{&#x22;Challenge required?&#x22;}
  F -->|No| G[&#x22;Frictionless authentication&#x22;]
  F -->|Yes| H[&#x22;Cardholder challenge&#x22;]
  G --> I[&#x22;success event: Cavv, Xid and Eci&#x22;]
  H --> J{&#x22;Authentication completed?&#x22;}
  J -->|Yes| I
  J -->|No| K[&#x22;failure event: only Eci&#x22;]
  I --> L[&#x22;Charge with externalAuthentication&#x22;]
  K --> M[&#x22;Liability stays with the merchant&#x22;]
  D --> M

  style I fill:#14ce71,stroke:#0eb464,color:#ffffff
  style L fill:#14ce71,stroke:#0eb464,color:#ffffff
  style K fill:#f59e0b,stroke:#d97706,color:#ffffff
  style M fill:#ef4444,stroke:#dc2626,color:#ffffff
`"
/>

<Callout type="info">
  When the transaction is authorized with the variables returned in the
  `success` event, liability shifts to the card issuer. In every other
  scenario, liability stays with the merchant.
</Callout>

## Step-by-step integration [#step-by-step-integration]

<Steps>
  <Step>
    ### Initialize the script [#initialize-the-script]

    Include the following script in your web page to load the script
    responsible for communicating with the card networks and the issuing
    banks:

    ```html
    <script src="https://static.payzu.io/scripts/3ds20.min.js"></script>
    ```

    After loading the script on your page, you must initialize it as
    follows:

    ```javascript
    const config = {
      amount: 350,
      currency: 'BRL',
      options: {
        enabled: true,
        sandbox: true,
        debug: true,
        suppressChallenge: false
      }
    };

    payzu3DS.init(config);
    ```

    | Parameter                   | Description                                                                                                                                           | Type           |
    | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
    | `amount`                    | Total transaction amount in cents                                                                                                                     | integer        |
    | `currency`                  | Currency code                                                                                                                                         | Fixed as "BRL" |
    | `options.enabled`           | Defines whether the transaction will be submitted to the 3DS authentication process                                                                   | boolean        |
    | `options.sandbox`           | Defines whether the execution environment will be sandbox or production                                                                               | boolean        |
    | `options.debug`             | When enabled, logs and reports will be emitted to the browser console                                                                                 | boolean        |
    | `options.suppressChallenge` | Determines whether the challenge will be suppressed. If the challenge is skipped and the transaction is authorized, liability stays with the merchant | boolean        |
  </Step>

  <Step>
    ### Register the authentication events [#register-the-authentication-events]

    Register the event listeners to handle each possible authentication
    result:

    ```javascript
    payzu3DS.on("ready", function (e) {

    });
    ```

    #### ready [#ready]

    This event fires when all script loading procedures have completed
    successfully, including the access token validation. It indicates that
    the checkout is ready to start the authentication process.

    #### Authentication results [#authentication-results]

    The liability shift happens only when authentication completes
    successfully: in that case, chargeback liability shifts to the issuer or
    the card network. In every other scenario, liability stays with the
    merchant.

    | Event        | Scenario and return                                                                                            | Liability               | Recommended action                                                                                   |
    | ------------ | -------------------------------------------------------------------------------------------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------- |
    | `success`    | Card eligible and authentication completed successfully. Returns `Cavv`, `Xid` and `Eci`.                      | Shifts to the issuer    | Include `Cavv`, `Xid` and `Eci` in the authorization request.                                        |
    | `failure`    | Card eligible, but authentication failed. Returns only `Eci`.                                                  | Stays with the merchant | If you decide to proceed with the authorization, include `Eci` in the request.                       |
    | `unenrolled` | Card not eligible: the cardholder and/or the issuer do not participate in the 3DS program. Returns only `Eci`. | Stays with the merchant | Advise the buyer to check with the issuer whether the card is enabled for e-commerce authentication. |
    | `disabled`   | Merchant chose not to authenticate, with `options.enabled` set to `false`.                                     | Stays with the merchant | -                                                                                                    |
    | `error`      | Systemic error in the authentication process.                                                                  | Stays with the merchant | -                                                                                                    |

    #### unsupportedBrand [#unsupportedbrand]

    This event fires when the card network of the card being used is not
    compatible with the 3DS protocol. In this case, authentication is not
    performed.

    #### Returned attributes [#returned-attributes]

    | Attribute       | Description                                       | Type                                  | Required? |
    | --------------- | ------------------------------------------------- | ------------------------------------- | --------- |
    | `Cavv`          | Data that represents the authentication signature | string                                | Yes       |
    | `Xid`           | Identifier of the authentication transaction      | string                                | No        |
    | `Eci`           | Code that represents the authentication result    | [ECI table](#eci-table)               | Yes       |
    | `Version`       | Version of the 3DS protocol used                  | string                                | Yes       |
    | `ReferenceId`   | Identifier of the authentication request          | string                                | Yes       |
    | `ReturnCode`    | Authentication return code                        | [3DS return codes](#3ds-return-codes) | Yes       |
    | `ReturnMessage` | Authentication return message                     | [3DS return codes](#3ds-return-codes) | Yes       |
  </Step>

  <Step>
    ### Request the challenge [#request-the-challenge]

    Instantiate the `paymentObject`, paying attention to the fields that are
    strictly required in the table below. When the checkout runs, the
    authentication process starts and its result is returned through the
    events.

    ```javascript
    const paymentObject = {
      installments: '01',
      cardnumber: '4000000000001091',
      cardexpirationmonth: '01',
      cardexpirationyear: '2027',
      cardalias: 'JOAO SOUZA',
      paymentmethod: 'Credit'
    }

    payzu3DS.checkout(paymentObject)
    ```

    If authentication completes successfully, the `success` event fires. In
    that case, the `Cavv`, `Xid` and `Eci` variables are returned: they must
    be sent to your backend and later included in the request at
    authorization time. In this case, the liability shift goes to the
    issuer.

    <Accordions type="single">
      <Accordion title="paymentObject fields">
        | Attribute name                   | Description                                                                                                      | Type                                                                                                  | Length | Required |
        | -------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------ | -------- |
        | `installments`                   | Number of installments of the transaction                                                                        | number                                                                                                | 2      | Yes      |
        | `cardnumber`                     | Card number                                                                                                      | number                                                                                                | 19     | Yes      |
        | `cardexpirationmonth`            | Card expiration month                                                                                            | number                                                                                                | 2      | Yes      |
        | `cardexpirationyear`             | Card expiration year                                                                                             | number                                                                                                | 4      | Yes      |
        | `cardalias`                      | Cardholder name printed on the card                                                                              | string                                                                                                | 128    | No       |
        | `paymentmethod`                  | Type of card to be authenticated. For a multi-function card, one of the types must be specified, Credit or Debit | Credit: credit card. Debit: debit card                                                                | 6      | Yes      |
        | `default_card`                   | Indicates whether it is the customer's default card in the store                                                 | boolean                                                                                               | -      | No       |
        | `recurring_enddate`              | Identifies the recurrence end date                                                                               | string (YYYY-MM-DD)                                                                                   | 10     | No       |
        | `recurring_frequency`            | Indicates the recurrence frequency                                                                               | number: 1 = Monthly, 2 = Bimonthly, 3 = Quarterly, 4 = Every four months, 6 = Semiannual, 12 = Annual | -      | No       |
        | `recurring_originalpurchasedate` | Date of the first transaction that originated the recurrence                                                     | string (YYYY-MM-DD)                                                                                   | 10     | No       |
        | `order_recurrence`               | Indicates whether it is an order that generates future recurrences                                               | boolean                                                                                               | -      | No       |
        | `order_productcode`              | Purchase type (PHY, CHA, ACF, QCT, PAL)                                                                          | string                                                                                                | -      | Yes      |
        | `order_countlast24hours`         | Orders placed in the last 24h                                                                                    | number                                                                                                | 3      | No       |
        | `order_countlast6months`         | Orders placed in the last 6 months                                                                               | number                                                                                                | 4      | No       |
        | `order_countlast1year`           | Orders placed in the last year                                                                                   | number                                                                                                | 3      | No       |
        | `order_cardattemptslast24hours`  | Transactions with the same card in the last 24h                                                                  | number                                                                                                | 3      | No       |
        | `order_marketingoptin`           | Opted in to receive marketing offers                                                                             | boolean                                                                                               | -      | No       |
        | `order_marketingsource`          | Source of the marketing campaign                                                                                 | string                                                                                                | 40     | No       |
        | `billto_customerid`              | Buyer's CPF/CNPJ                                                                                                 | string                                                                                                | 11-14  | No       |
        | `billto_contactname`             | Billing address contact name                                                                                     | string                                                                                                | 120    | Yes      |
        | `billTo_phonenumber`             | Billing address phone number                                                                                     | string                                                                                                | 15     | Yes      |
        | `billTo_email`                   | Billing address email                                                                                            | string                                                                                                | 255    | Yes      |
        | `billTo_street1`                 | Billing address street and number                                                                                | string                                                                                                | 60     | Yes      |
        | `billTo_street2`                 | Billing address complement and district                                                                          | string                                                                                                | 60     | Yes      |
        | `billTo_city`                    | Billing address city                                                                                             | string                                                                                                | 50     | Yes      |
        | `billTo_state`                   | Billing address state abbreviation                                                                               | string                                                                                                | 2      | Yes      |
        | `billto_zipcode`                 | Billing address postal code                                                                                      | string                                                                                                | 8      | Yes      |
        | `billto_country`                 | Billing address country                                                                                          | string Ex: BR                                                                                         | 2      | Yes      |
        | `shipto_sameasbillto`            | Billing and shipping address are the same                                                                        | boolean                                                                                               | -      | No       |
        | `shipto_addressee`               | Shipping address contact name                                                                                    | string                                                                                                | 60     | No       |
        | `shipTo_phonenumber`             | Shipping address phone number                                                                                    | string                                                                                                | 15     | No       |
        | `shipTo_email`                   | Shipping address email                                                                                           | string                                                                                                | 255    | No       |
        | `shipTo_street1`                 | Shipping address street and number                                                                               | string                                                                                                | 60     | No       |
        | `shipTo_street2`                 | Shipping address complement and district                                                                         | string                                                                                                | 60     | No       |
        | `shipTo_city`                    | Shipping address city                                                                                            | string                                                                                                | 50     | No       |
        | `shipTo_state`                   | Shipping address state abbreviation                                                                              | string                                                                                                | 2      | No       |
        | `shipto_zipcode`                 | Shipping address postal code                                                                                     | string                                                                                                | 8      | No       |
        | `shipto_country`                 | Shipping address country                                                                                         | string Ex: BR                                                                                         | 2      | No       |
        | `shipTo_shippingmethod`          | Shipping method type (lowcost, sameday, oneday, twoday, etc.)                                                    | string                                                                                                | -      | No       |
        | `shipto_firstusagedate`          | Date the shipping address was first used                                                                         | string (YYYY-MM-DD)                                                                                   | 10     | No       |

        <Callout type="info">
          The Type column reproduces the source documentation. In the official example above, `installments`, `cardnumber`, `cardexpirationmonth` and `cardexpirationyear` are sent as strings; follow the example, especially for `cardnumber`, to avoid numeric precision loss.
        </Callout>
      </Accordion>
    </Accordions>
  </Step>

  <Step>
    ### Use the result in the charge [#use-the-result-in-the-charge]

    To create a charge using 3DS, you must set the `authenticate` field to
    `true` and provide the `externalAuthentication` field inside
    `creditCardPayment`:

    ```json
    {
      "creditCardPayment": {
        "authenticate": true,
        "externalAuthentication": {
          "cavv": "Ag5zZ2ElCIUbLFj6gS0J9gByv//rRg5qGTqWqf8vTjt5",
          "xid": "198b924ea7db1014b64c8b426a0e6f1e",
          "eci": "05",
          "version": "2.2",
          "referenceId": "abcd1234-efgh-5678-ijkl-9012mnopqrst"
        }
      }
    }
    ```

    See [Create charge](/docs/cartao/endpoints/charges/post_charges)
    for the remaining request fields.
  </Step>
</Steps>

## Return codes and ECI [#return-codes-and-eci]

### 3DS return codes [#3ds-return-codes]

Codes returned in the 3DS authentication flow.

| 3DS code | Description                                                | Possible action                                                                                     |
| -------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `100`    | Transaction completed successfully.                        | -                                                                                                   |
| `101`    | One or more required fields are missing from the request.  | Check the fields `missingField_0` through `missingField_N` in the response. Send the request again. |
| `102`    | One or more request fields contain invalid data.           | Check the fields `invalidField_0` through `invalidField_N` in the response. Resend the request.     |
| `150`    | Error: general system failure.                             | Wait a few minutes and send the request again.                                                      |
| `151`    | Error: the request was received, but the server timed out. | Wait a few minutes and send the request again.                                                      |
| `152`    | Error: the request was received, but a service timed out.  | Wait a few minutes and send the request again.                                                      |
| `234`    | There is a problem with your merchant configuration.       | Do not send the request again. Contact support.                                                     |
| `475`    | The customer is enrolled in payer authentication.          | Authenticate the cardholder before proceeding with the transaction.                                 |
| `476`    | The customer cannot be authenticated.                      | Review the customer's order.                                                                        |
| `MPI901` | Unexpected error.                                          | -                                                                                                   |
| `MPI902` | Unexpected authentication response.                        | -                                                                                                   |
| `MPI900` | An error occurred.                                         | -                                                                                                   |
| `MPI601` | Challenge skipped.                                         | -                                                                                                   |
| `MPI600` | Brand does not support authentication.                     | -                                                                                                   |

### ECI table [#eci-table]

The ECI table indicates, per brand, the authentication result and who bears the chargeback risk:

| Mastercard                     | Visa                     | Elo                      | Amex                     | Authentication result                                                                            | Was the transaction authenticated? |
| ------------------------------ | ------------------------ | ------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------- |
| `02`                           | `05`                     | `05`                     | `05`                     | Authenticated by the issuer: chargeback risk shifts to the issuer.                               | Yes                                |
| `01`                           | `06`                     | `06`                     | `06`                     | Authenticated by the brand: chargeback risk shifts to the issuer.                                | Yes                                |
| Other than `01`, `02` and `04` | Other than `05` and `06` | Other than `05` and `06` | Other than `05` and `06` | Not authenticated: chargeback risk stays with the merchant.                                      | No                                 |
| `04`                           | `7`                      | -                        | -                        | Not authenticated, transaction classified as Data Only: chargeback risk stays with the merchant. | No                                 |

<Callout type="warn">
  When the transaction is not authenticated, the chargeback risk stays with the merchant. Check the ECI values in the table above before deciding to proceed with the charge.
</Callout>

## References [#references]

* Cards to simulate 3DS authentication scenarios in the sandbox:
  [Test cards](/docs/cartao/test-cards)