# 身份认证 (/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": "不允许从此 IP 地址访问。",
  "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": "需要身份验证或令牌无效。",
  "statusCode": 401,
  "requestId": "cmou00000abcdef01s6ghij1k2lm"
}
```

### 403 Forbidden [#403-forbidden]

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

## 轮换 [#轮换]

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

## Pix 付款与转账的 IP 白名单 [#pix-付款与转账的-ip-白名单]

为资金流出账户的操作提供额外一层保护。白名单启用后,`POST /v1/withdraw`、`POST /v1/withdraw/qrcode` 和 `POST /v1/internal-transfer` 仅接受来自已登记 IP 的调用。其他任何 IP 都会收到 `403`,`errorCode` 为 `PZA203`,即使 token 有效。这些路由的 `GET` 查询也经过同样的校验。

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

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

限制:

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

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

### 最佳实践 [#最佳实践]

* 登记基础设施的 **固定出口 IP**(NAT/egress)。本地机器的动态 IP 会在第一次变化时失效。
* 迁移基础设施时,**先添加新 IP,再删除旧 IP**,这样过渡期间 Pix 付款不会中断。
* 在代码中将 `PZA203` 视为配置错误而非业务错误:应通知基础设施团队,而不是重试。