# 身份认证 (/zh/docs/conta-digital/authentication)

<QuickLinks>
  <QuickLink href="/docs/conta-digital/endpoints/authentication/post_oauth_token" title="获取访问令牌" method="POST" path="/oauth/token" />

  <QuickLink href="/docs/conta-digital/security" title="安全" />

  <QuickLink href="/docs/conta-digital/error-codes" title="错误代码" />
</QuickLinks>

凭证是一对 `client_id` 和 `client_secret`，由账户持有人在控制台中用操作 PIN 创建。它只操作一个账户，只能调用其已获作用域对应的路由，并且可以设置允许的 IP 列表。

<Mermaid
  chart="`
flowchart LR
  C[&#x22;client_id + client_secret&#x22;] -->|&#x22;POST /oauth/token&#x22;| T[&#x22;15 分钟令牌&#x22;]
  T -->|&#x22;Authorization: Bearer&#x22;| API[&#x22;/transactions 路由&#x22;]
  C -.->|&#x22;Authorization: Basic&#x22;| API

  click T &#x22;/docs/conta-digital/endpoints/authentication/post_oauth_token&#x22; &#x22;获取访问令牌&#x22;

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

## 获取令牌 [#获取令牌]

把凭证放在 `Authorization: Basic` 中，发送到 [`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"
}
```

* 令牌有效期 15 分钟（`expires_in: 900`）。过期后，API 返回 `401` 和 `TOKEN_INVALID`：在同一路由再获取一个。
* `scope` 列出凭证的作用域，以空格分隔。
* `client_id` 和 `client_secret` 也可以放在请求体中，格式为 `application/x-www-form-urlencoded` 或 JSON。
* 该路由按 `client_id` 和 IP 限制换取次数。超过限制后，返回 `429` 和 `Retry-After`。

curl 和 Node.js 示例见[快速开始](/docs/conta-digital/getting-started#用凭证换取令牌)。

## 其他认证方式 [#其他认证方式]

API 也接受在每次调用中直接发送凭证。三种方式访问的是同一个账户，作用域也相同。

| 方式          | Header                                                 | 密钥的传输                    |
| ----------- | ------------------------------------------------------ | ------------------------ |
| 访问令牌        | `Authorization: Bearer <access_token>`                 | 只在换取令牌时传输。               |
| Basic 方式的凭证 | `Authorization: Basic base64(client_id:client_secret)` | 每次调用都传输。                 |
| 凭证令牌        | `Authorization: Bearer pzu_<prefix>_<secret>`          | 每次调用都传输。控制台在创建凭证时显示这个令牌。 |

控制台的登录不能用于 API 路由，凭证也不能用于控制台。

## 作用域 [#作用域]

每个路由都需要一个作用域，作用域之间互不包含：`PAYMENT_WRITE` 不授予读取权限，读取也不授予写入权限。

| 作用域                      | 允许                             |
| ------------------------ | ------------------------------ |
| `PAYMENT_WRITE`          | 创建收款。                          |
| `PAYMENT_READ`           | 查询和列出收款，下载收款凭证。                |
| `REFUND`                 | 收款退款和退回存款。                     |
| `WITHDRAW`               | 提现到 Pix 密钥，支付 Pix 复制粘贴码。       |
| `WITHDRAW_READ`          | 查询和列出提现，下载提现凭证。                |
| `INTERNAL_TRANSFER`      | 向另一个 PayZu 账户转账。               |
| `INTERNAL_TRANSFER_READ` | 查询和列出发出及收到的转账，下载转账凭证。          |
| `DEPOSIT_READ`           | 查询无收款单的入账 Pix，下载存款凭证。          |
| `STATEMENT_READ`         | 查询余额、账单、限额和指标。                 |
| `PIX_KEY_READ`           | 列出账户的 Pix 密钥。                  |
| `PIX_KEY_WRITE`          | 创建和删除 Pix 密钥，设置默认密钥。           |
| `PIX_DICT_READ`          | 解析 Pix 复制粘贴码，查询收款方。            |
| `INFRACTION_READ`        | 查询 MED 争议。                     |
| `WEBHOOK_READ`           | 列出 Webhook 端点，查看账户是否有回调密钥。     |
| `WEBHOOK_WRITE`          | 注册、修改和删除 Webhook 端点，签发或更换回调密钥。 |

新凭证中，`WITHDRAW`、`INTERNAL_TRANSFER`、`REFUND`、`PIX_KEY_WRITE` 和 `WEBHOOK_WRITE` 从不默认勾选。

## IP 列表 [#ip-列表]

在控制台中填写凭证的 IP 列表后，来自其他 IP 的调用会收到 `403` 和 `TOKEN_IP_NOT_ALLOWED`。这条规则也适用于 `POST /oauth/token` 和令牌的使用：从允许的 IP 获取的令牌，如果从其他 IP 发来，也会被拒绝。列表为空时接受任何 IP。

## 轮换与吊销 [#轮换与吊销]

* `client_secret` 只在创建时显示一次。之后没有任何路由会返回它。
* 轮换会创建一个新凭证，带有另一个 `client_id`、另一个 `client_secret` 和相同的作用域。旧凭证继续有效 **24 小时**。IP 列表不会转到新凭证。
* 吊销会立即使凭证及其签发的令牌失效。
* 创建、轮换和吊销都在控制台中完成。API 没有对应的路由。

## 凭证拒绝 [#凭证拒绝]

适用于所有 API 路由：

| 状态  | `code`                      | 何时                                                     |
| --- | --------------------------- | ------------------------------------------------------ |
| 401 | `TOKEN_INVALID`             | 凭证错误、不存在或已吊销，或令牌已过期或被篡改。请获取新令牌；如果仍被拒绝，请检查凭证。           |
| 401 | `TOKEN_EXPIRED`             | 凭证设有有效期，且已过期。                                          |
| 401 | `JWT_INVALID_AUTH_FORMAT`   | 缺少 `Authorization` header，或方案既不是 `Bearer` 也不是 `Basic`。 |
| 401 | `TOKEN_INVALID_AUTH_FORMAT` | `Basic` 无法解码为 `client_id:client_secret`。               |
| 403 | `TOKEN_MISSING_SCOPE`       | 凭证没有该路由的作用域。`details.scope` 指明缺少哪一个。                   |
| 403 | `TOKEN_IP_NOT_ALLOWED`      | 调用来自凭证 IP 列表之外的 IP。                                    |
| 403 | `TOKEN_HOLDER_BLOCKED`      | 账户持有人被冻结。解除冻结后凭证恢复有效。                                  |

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

在 `POST /oauth/token` 上，缺少凭证或 `Basic` 无法解码时，返回 `401` 和 `TOKEN_INVALID`。该路由还有两种拒绝：

| 状态  | `code`                         | 何时                                               |
| --- | ------------------------------ | ------------------------------------------------ |
| 400 | `TOKEN_UNSUPPORTED_GRANT_TYPE` | 缺少 `grant_type`，或其值不是 `client_credentials`。      |
| 429 | `AUTH_TOO_MANY_REQUESTS`       | 超过了按 `client_id` 和 IP 的换取次数限制。请等待 `Retry-After`。 |