# Autenticação (/docs/conta-digital/authentication)

<QuickLinks>
  <QuickLink href="/docs/conta-digital/endpoints/authentication/post_oauth_token" title="Obter token de acesso" method="POST" path="/oauth/token" />

  <QuickLink href="/docs/conta-digital/security" title="Segurança" />

  <QuickLink href="/docs/conta-digital/error-codes" title="Códigos de erro" />
</QuickLinks>

A credencial é um par `client_id` e `client_secret`, criado pelo titular no painel com o PIN de operação. Ela opera uma só conta e só as rotas dos escopos que recebeu, e pode ter uma lista de IPs permitidos.

<Mermaid
  chart="`
flowchart LR
  C[&#x22;client_id + client_secret&#x22;] -->|&#x22;POST /oauth/token&#x22;| T[&#x22;Token de 15 minutos&#x22;]
  T -->|&#x22;Authorization: Bearer&#x22;| API[&#x22;Rotas /transactions&#x22;]
  C -.->|&#x22;Authorization: Basic&#x22;| API

  click T &#x22;/docs/conta-digital/endpoints/authentication/post_oauth_token&#x22; &#x22;Obter token de acesso&#x22;

  style T fill:#14ce71,stroke:#0eb464,color:#ffffff
`"
/>

## Obter o token [#obter-o-token]

Mande a credencial em `Authorization: Basic` para [`POST /oauth/token`](/docs/conta-digital/endpoints/authentication/post_oauth_token):

```http
POST /api/v1/oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
```

```json
{
  "access_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..mQ3Zy1hbVhpbXBsZQ.ZXhlbXBsbw.c2lnbmF0dXJl",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "PAYMENT_WRITE PAYMENT_READ STATEMENT_READ"
}
```

* O token vale 15 minutos (`expires_in: 900`). Vencido, a API responde `401` com `TOKEN_INVALID`: peça outro na mesma rota.
* `scope` lista os escopos da credencial, separados por espaço.
* `client_id` e `client_secret` também podem ir no corpo, em `application/x-www-form-urlencoded` ou JSON.
* A rota limita as trocas por `client_id` e IP. Acima do limite, responde `429` com `Retry-After`.

Exemplos em curl e Node.js estão em [Primeiros passos](/docs/conta-digital/getting-started#trocar-a-credencial-por-um-token).

## Outras formas de autenticar [#outras-formas-de-autenticar]

A API também aceita a credencial direto em cada chamada. As três formas dão acesso à mesma conta, com os mesmos escopos.

| Forma               | Header                                                 | O segredo trafega                                                     |
| ------------------- | ------------------------------------------------------ | --------------------------------------------------------------------- |
| Token de acesso     | `Authorization: Bearer <access_token>`                 | Só na troca pelo token.                                               |
| Credencial em Basic | `Authorization: Basic base64(client_id:client_secret)` | Em toda chamada.                                                      |
| Token da credencial | `Authorization: Bearer pzu_<prefixo>_<segredo>`        | Em toda chamada. O painel mostra esse token na criação da credencial. |

O login do painel não vale nas rotas da API, e a credencial não vale no painel.

## Escopos [#escopos]

Cada rota exige um escopo, e nenhum escopo inclui outro: `PAYMENT_WRITE` não dá leitura, e ler não dá escrita.

| Escopo                   | Libera                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| `PAYMENT_WRITE`          | Criar cobrança.                                                                             |
| `PAYMENT_READ`           | Consultar e listar cobranças e baixar o comprovante.                                        |
| `REFUND`                 | Estornar cobrança e devolver depósito.                                                      |
| `WITHDRAW`               | Sacar para chave Pix e pagar Pix copia e cola.                                              |
| `WITHDRAW_READ`          | Consultar e listar saques e baixar o comprovante.                                           |
| `INTERNAL_TRANSFER`      | Transferir para outra conta PayZu.                                                          |
| `INTERNAL_TRANSFER_READ` | Consultar e listar transferências, enviadas e recebidas, e baixar o comprovante.            |
| `DEPOSIT_READ`           | Consultar Pix recebido sem cobrança e baixar o comprovante.                                 |
| `STATEMENT_READ`         | Consultar saldo, extrato, limites e métricas.                                               |
| `PIX_KEY_READ`           | Listar as chaves Pix da conta.                                                              |
| `PIX_KEY_WRITE`          | Criar e apagar chave Pix e definir a chave padrão.                                          |
| `PIX_DICT_READ`          | Ler Pix copia e cola e consultar o destinatário.                                            |
| `INFRACTION_READ`        | Consultar contestações MED.                                                                 |
| `WEBHOOK_READ`           | Listar endpoints de webhook e ver se a conta tem segredo de callback.                       |
| `WEBHOOK_WRITE`          | Cadastrar, alterar e excluir endpoints de webhook e emitir ou trocar o segredo de callback. |

`WITHDRAW`, `INTERNAL_TRANSFER`, `REFUND`, `PIX_KEY_WRITE` e `WEBHOOK_WRITE` nunca vêm marcados numa credencial nova.

## Lista de IPs [#lista-de-ips]

Com a lista de IPs da credencial preenchida no painel, uma chamada de outro IP recebe `403` com `TOKEN_IP_NOT_ALLOWED`. A regra vale também em `POST /oauth/token` e no uso do token: um token obtido de um IP permitido é recusado se vier de outro. Com a lista vazia, qualquer IP é aceito.

## Rotação e revogação [#rotação-e-revogação]

* O `client_secret` aparece uma vez, na criação. Nenhuma rota o devolve depois.
* Rotacionar cria uma credencial nova, com outro `client_id`, outro `client_secret` e os mesmos escopos. A anterior continua valendo por **24 horas**. A lista de IPs não passa para a nova.
* Revogar invalida na hora a credencial e os tokens emitidos por ela.
* Criar, rotacionar e revogar são feitos no painel. A API não tem rota para isso.

## Recusas de credencial [#recusas-de-credencial]

Valem para todas as rotas da API:

| Status | `code`                      | Quando                                                                                                                                     |
| ------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 401    | `TOKEN_INVALID`             | Credencial errada, inexistente ou revogada, ou token vencido ou alterado. Peça um token novo; se a recusa continuar, confira a credencial. |
| 401    | `TOKEN_EXPIRED`             | A credencial tinha data de validade, e ela passou.                                                                                         |
| 401    | `JWT_INVALID_AUTH_FORMAT`   | Faltou o header `Authorization`, ou o esquema não é `Bearer` nem `Basic`.                                                                  |
| 401    | `TOKEN_INVALID_AUTH_FORMAT` | O `Basic` não decodifica para `client_id:client_secret`.                                                                                   |
| 403    | `TOKEN_MISSING_SCOPE`       | A credencial não tem o escopo da rota. `details.scope` diz qual falta.                                                                     |
| 403    | `TOKEN_IP_NOT_ALLOWED`      | A chamada veio de um IP fora da lista da credencial.                                                                                       |
| 403    | `TOKEN_HOLDER_BLOCKED`      | O titular da conta está bloqueado. A credencial volta a valer quando o bloqueio sai.                                                       |

```json
{
  "message": "Esta credencial não tem permissão para esta operação.",
  "code": "TOKEN_MISSING_SCOPE",
  "details": { "scope": "WITHDRAW" }
}
```

Em `POST /oauth/token`, credencial ausente ou `Basic` que não decodifica respondem `401` com `TOKEN_INVALID`. A rota tem mais duas recusas:

| Status | `code`                         | Quando                                                                   |
| ------ | ------------------------------ | ------------------------------------------------------------------------ |
| 400    | `TOKEN_UNSUPPORTED_GRANT_TYPE` | `grant_type` ausente ou diferente de `client_credentials`.               |
| 429    | `AUTH_TOO_MANY_REQUESTS`       | Passou do limite de trocas por `client_id` e IP. Espere o `Retry-After`. |