# 身份认证 (/zh/docs/pix-processamento/authentication)

<QuickLinks>
  <QuickLink href="/docs/pix-processamento/endpoints" title="API 参考" />

  <QuickLink href="/docs/pix-processamento/best-practices/security" title="安全" />

  <QuickLink href="/docs/pix-processamento/glossary" title="术语表" />
</QuickLinks>

<Mermaid
  chart="`
flowchart LR
  A[&#x22;您的应用&#x22;] -->|&#x22;Authorization: Bearer SEU_TOKEN&#x22;| B[&#x22;API PayZu&#x22;]
  B --> C{&#x22;校验&#x22;}
  C -->|Token 有效| OK[&#x22;200 OK&#x22;]
  C -->|Token 缺失/无效| E1[&#x22;401 Unauthorized&#x22;]
  C -->|无权限| E2[&#x22;403 Forbidden&#x22;]

  click OK &#x22;/zh/docs/pix-processamento/endpoints&#x22; &#x22;endpoint 列表&#x22;
  click E1 &#x22;#401-unauthorized&#x22; &#x22;解决 401&#x22;
  click E2 &#x22;#403-forbidden&#x22; &#x22;解决 403&#x22;
  click A &#x22;/zh/docs/pix-processamento/best-practices/security&#x22; &#x22;Token 存储位置&#x22;

  style A fill:#f59e0b,stroke:#d97706,color:#ffffff
  style OK fill:#14ce71,stroke:#0eb464,color:#ffffff
  style E1 fill:#ef4444,stroke:#dc2626,color:#ffffff
  style E2 fill:#ef4444,stroke:#dc2626,color:#ffffff
`"
/>

## 如何发送 [#如何发送]

每次调用都需要**两个必填 header**:

```http
Authorization: Bearer SEU_TOKEN
Content-Type: application/json
```

带认证的余额查询调用示例:

<Tabs items="['curl', 'Node.js', 'Python', 'Go', 'PHP']">
  <Tab value="curl">
    ```bash
    curl https://api.payzu.processamento.com/v1/user/balance \
      -H "Authorization: Bearer $PAYZU_TOKEN" \
      -H "Content-Type: application/json"
    ```
  </Tab>

  <Tab value="Node.js">
    ```ts
    const res = await fetch('https://api.payzu.processamento.com/v1/user/balance', {
      headers: {
        Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
        'Content-Type': 'application/json',
      },
    });
    const balance = await res.json();
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import os
    import requests

    res = requests.get(
        'https://api.payzu.processamento.com/v1/user/balance',
        headers={
            'Authorization': f'Bearer {os.environ["PAYZU_TOKEN"]}',
            'Content-Type': 'application/json',
        },
    )
    balance = res.json()
    ```
  </Tab>

  <Tab value="Go">
    ```go
    req, _ := http.NewRequest("GET", "https://api.payzu.processamento.com/v1/user/balance", nil)
    req.Header.Set("Authorization", "Bearer " + os.Getenv("PAYZU_TOKEN"))
    req.Header.Set("Content-Type", "application/json")
    res, err := http.DefaultClient.Do(req)
    ```
  </Tab>

  <Tab value="PHP">
    ```php
    <?php
    $ch = curl_init('https://api.payzu.processamento.com/v1/user/balance');
    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('PAYZU_TOKEN'),
        'Content-Type: application/json',
      ],
    ]);
    $balance = json_decode(curl_exec($ch), true);
    ```
  </Tab>
</Tabs>

## 存储位置 [#存储位置]

<Callout type="warn">
  绝不要将 token 暴露在前端、公开仓库或日志中。
  请把它当作密码:存放于密钥库,通过环境变量注入。
</Callout>

推荐方案:

* **Google Secret Manager**,如果您已在使用 GCP,这是理想选择。
* **HashiCorp Vault**,适用于自托管环境。
* **AWS Secrets Manager**,AWS 的等价方案。
* **CI 环境变量**,切勿提交到代码库。

## 错误格式 [#错误格式]

**PayZu 所有的错误响应**(4xx 和 5xx)都遵循同一格式。最重要的字段是 `requestId`,它在 PayZu 内部日志中唯一标识该次调用。

```json
{
  "errorCode": "PZA203",
  "message": "Acesso não permitido a partir do endereço de IP 203.0.113.10.",
  "statusCode": 403,
  "requestId": "cmp70zh4008dx01s6bwjb5bez"
}
```

| 字段           | 用途                                           |
| ------------ | -------------------------------------------- |
| `errorCode`  | 目录中的稳定代码(例如 `PZA203`)。用它而非消息来编写你的逻辑。         |
| `message`    | 葡萄牙语描述错误内容。用于日志记录,而非展示给最终用户。                 |
| `statusCode` | 响应的 HTTP 状态码(与 status 一致)。                   |
| `requestId`  | **PayZu 中该次调用的唯一 ID**。开支持工单时附上此 ID,他们可以直接追溯。 |

完整目录(含可选字段 `details[]` 和 `retryAfterSeconds`)见[错误代码](/docs/pix-processamento/error-codes)。

**请始终在错误日志中记录 `requestId`**:这是支持团队首先要的信息;日志片段和完整的重试策略见[错误处理](/docs/pix-processamento/best-practices/errors)。

### 通过 requestId 开启支持 [#通过-requestid-开启支持]

<QuickLinks>
  <QuickLink href="https://suporte.payzu.com.br/portal/pt-br/newticket?departmentId=1103699000000006907&layoutId=1103699000000074011" title="提交工单" />
</QuickLinks>

## 令牌作用域 [#令牌作用域]

每个 token 带有一个或多个作用域,它们决定该 token 可以调用哪些路由。同一个 token 可以同时拥有 `DEPOSIT` 和 `WITHDRAW`。

| 作用域        | 可调用的路由                                                                                                                                                                 |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEPOSIT`  | Pix 收款:`POST /v1/pix`、`GET /v1/pix` 和 `GET /v1/pix/qr-code/:transactionId`。                                                                                            |
| `WITHDRAW` | 付款与资金流出:`POST /v1/withdraw`、`POST /v1/withdraw/qrcode`、`GET /v1/withdraw`、`POST /v1/internal-transfer`、`GET /v1/internal-transfer` 和 `POST /v1/refund/:transactionId`。 |

DICT 查询(`GET /v1/pix/key` 和 `POST /v1/pix/qrcode/read`)接受这两个作用域中的任意一个。

缺少路由所需作用域的 token 会收到 `403`,`errorCode` 为 `PZA200`。

## 错误排查 [#错误排查]

### 401 Unauthorized [#401-unauthorized]

最常见的原因,按顺序排列:

1. **Token 缺失**,未发送 `Authorization` header。
2. **Token 错误**,拼写错误、多余空格、编码错误。
3. **Token 已吊销**,已轮换但您仍在使用旧 token。

响应示例:

```json
{
  "errorCode": "PZA100",
  "message": "Autenticação necessária ou token inválido.",
  "statusCode": 401,
  "requestId": "cmou00000abcdef01s6ghij1k2lm"
}
```

### 403 Forbidden [#403-forbidden]

Token 有效,但无权执行该操作。请检查
endpoint 是否需要额外作用域,或您的账户是否已开通该
功能(例如内部转账可能需要预先审批)。

## 轮换 [#轮换]

如果 token 泄露,请立即联系 PayZu 支持,以便签发
新 token 并吊销旧 token。

## IP 白名单 [#ip-白名单]

IP 白名单决定账户接受来自哪些地址的调用。所有通过 token 认证的 `/v1` 路由都会执行该校验，包括查询和资金流动操作，校验依据是请求的公网来源 IP。

| 账户情况                                     | 结果                                                                       |
| ---------------------------------------- | ------------------------------------------------------------------------ |
| 已登记 IP                                   | 仅接受来自已登记 IP 的调用。来自其他 IP 的调用会收到 `403`，`errorCode` 为 `PZA203`，即使 token 有效。 |
| 未登记 IP，且有带 `WITHDRAW` 作用域（提现权限）的有效 token | 拒绝所有调用，返回 `403`，`errorCode` 为 `PZA205`，无论使用账户的哪个 token，直到登记 IP 为止。       |
| 未登记 IP，且没有带 `WITHDRAW` 作用域的 token        | 接受来自任何 IP 的调用。                                                           |

`PZA203` 和 `PZA205` 的消息中包含到达 PayZu 的来源 IP。新的出口 IP 只有在登记后才会被接受，旧 IP 在删除之前仍然被接受。

删除最后一个已登记的 IP 时，会在同一操作中吊销账户所有带 `WITHDRAW` 作用域的 token。此后，使用这些 token 的调用会收到 `401`，账户使用剩余的 token 可以从任何 IP 发起调用。

### 如何管理 [#如何管理]

在 Web 面板中自助管理，位于 **安全** 菜单的 **IP 白名单** 部分。每次添加或删除都需要 step-up 确认（操作密码），所有变更均记录审计。

限制：

* 每个账户最多 **20 个生效 IP**。
* 每 5 分钟最多 **5 次添加**。

<Callout type="warn">
  被锁定禁止变更的账户在尝试添加或删除 IP 时会收到 `403`，`errorCode` 为
  `PZA204`。此时请联系支持团队。
</Callout>