# Authentication (/en/docs/cartao/authentication)

<QuickLinks>
  <QuickLink href="/docs/cartao/endpoints/token/post_token" title="Get API token" method="POST" path="/token" />

  <QuickLink href="/docs/cartao/getting-started" title="Getting started" />

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

  <QuickLink href="/docs/cartao/webhooks" title="Webhooks" />
</QuickLinks>

Authentication in the **Card API** happens in two layers that work together:

1. **Mutual TLS (mTLS)**: every connection to the API uses a client certificate issued by PayZu, guaranteeing the identity of both the server and the client during communication.
2. **JWT token**: over the mTLS connection, you obtain an `access_token` via [`POST /token`](/docs/cartao/endpoints/token/post_token) and send it in the `Authorization: Bearer` header on all other routes.

## Environments [#environments]

| Environment | Base URL                          |
| ----------- | --------------------------------- |
| Production  | `https://api.payzu.io/v1`         |
| Sandbox     | `https://api.sandbox.payzu.io/v1` |

## Mutual TLS [#mutual-tls]

Before making any call, install the client certificate provided by the PayZu team and configure your system to use it in **all** API calls, always over HTTPS.

In `curl`, the certificate goes in through the `--cert` (client certificate), `--key` (private key), and `--cacert` (certificate authority chain) flags:

```bash
curl --request GET \
     --url https://api.sandbox.payzu.io/v1/charges \
     --header 'accept: application/json' \
     --cert cliente.crt \
     --key cliente.key \
     --cacert ca.pem
```

## Get the token [#get-the-token]

The [`POST /token`](/docs/cartao/endpoints/token/post_token) route returns a JWT token used to authenticate the other routes. It uses **Basic Auth** (your `client_id` as the username and `client_secret` as the password), always over the mTLS connection, and receives the `grant_type` `client_credentials` in the body:

```bash
curl --request POST \
     --url https://api.sandbox.payzu.io/v1/token \
     --user "$CLIENT_ID:$CLIENT_SECRET" \
     --header 'content-type: application/json' \
     --cert cliente.crt \
     --key cliente.key \
     --cacert ca.pem \
     --data '{ "grant_type": "client_credentials" }'
```

In production, switch the base URL to `https://api.payzu.io/v1`.

The response carries the token and its expiration time:

```json
{
  "access_token": "string",
  "token_type": "string",
  "expires_in": 0
}
```

| Field          | What it's for                                                    |
| -------------- | ---------------------------------------------------------------- |
| `access_token` | JWT token used in the `Authorization` header of the other routes |
| `token_type`   | Type of the returned token                                       |
| `expires_in`   | Token validity period, in seconds                                |

## Authenticated calls [#authenticated-calls]

After obtaining the token, every API route receives the `Authorization: Bearer` header, always over the same mTLS configuration:

```bash
curl --request GET \
     --url https://api.sandbox.payzu.io/v1/charges \
     --header 'accept: application/json' \
     --header "Authorization: Bearer $ACCESS_TOKEN" \
     --cert cliente.crt \
     --key cliente.key \
     --cacert ca.pem
```

<Callout type="warn">
  Never expose the `client_secret` or the client certificate's private key. Do not send them to the front-end, do not commit them to a repository, and keep them in a secrets vault. If you suspect they have been compromised, contact the PayZu team for a replacement.
</Callout>

## Next steps [#next-steps]

<QuickLinks>
  <QuickLink href="/docs/cartao/endpoints/token/post_token" title="Get API token" method="POST" path="/token" />

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

  <QuickLink href="/docs/cartao/test-cards" title="Test cards" />
</QuickLinks>