# 在一个账户中区分门店与分支 (/zh/docs/pix-processamento/best-practices/multi-tenant)

<QuickLinks>
  <QuickLink href="/docs/pix-processamento/endpoints/pix-operations/post_pix" title="POST /pix" />

  <QuickLink href="/docs/pix-processamento/endpoints/reports/get_user_transactions" title="GET /user/transactions" />

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

如果您在一个 PayZu 账户下运营多个品牌、门店、分支或合作伙伴，请在每次创建时传入 `virtualAccount`（最多 50 个字符）。该字段：

* **每个 callback 都会返回**，您可立即识别该交易属于哪个租户。
* **可在 `GET /user/transactions` 和 `GET /pix` 中过滤**，按租户隔离列表。
* **无需创建子账户**，一个 PayZu 账户即可服务 N 个租户。

<Mermaid
  chart="`
flowchart LR
  L1[&#x22;里约门店&#x22;] -->|&#x22;virtualAccount=loja-rj-01&#x22;| API[&#x22;PayZu API&#x22;]
  L2[&#x22;圣保罗门店&#x22;] -->|&#x22;virtualAccount=loja-sp-02&#x22;| API
  L3[&#x22;市场平台&#x22;] -->|&#x22;virtualAccount=mkt-acme&#x22;| API
  API --> CB[&#x22;Callback 保留 virtualAccount&#x22;]
  CB --> R[&#x22;您按租户路由&#x22;]

  click API &#x22;/zh/docs/pix-processamento/endpoints/pix-operations/post_pix&#x22; &#x22;POST /pix&#x22;
  click CB &#x22;/zh/docs/pix-processamento/webhooks&#x22; &#x22;Webhooks&#x22;

  style API fill:#14ce71,stroke:#0eb464,color:#ffffff
  style R fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
`"
/>

## 命名约定 [#命名约定]

| 格式                       | 使用场景         |
| ------------------------ | ------------ |
| `tenant-{slug}`          | 多客户 SaaS 平台。 |
| `loja-{cidade}-{numero}` | 拥有实体门店的连锁。   |
| `mkt-{partner}`          | 拥有多个卖家的市场平台。 |
| `filial-{codigo}`        | 同一公司的分支机构。   |
| `branch-{branchId}`      | 通用英文格式。      |

<Callout type="info">
  最大长度：**50 个字符**。请使用稳定且可读的格式。避免使用特殊字符和空格。
</Callout>

## 使用 `virtualAccount` 创建 [#使用-virtualaccount-创建]

<Tabs items="['Request', 'Response', 'Callback']">
  <Tab value="Request">
    ```json
    {
      "amount": 99.90,
      "clientReference": "order-1234",
      "virtualAccount": "loja-rj-01",
      "callbackUrl": "https://seusite.com.br/webhooks/payzu"
    }
    ```
  </Tab>

  <Tab value="Response">
    ```json
    {
      "id": "PAYZU20260811K7M2X9QP4T000000",
      "status": "PENDING",
      "amount": 99.90,
      "clientReference": "order-1234",
      "virtualAccount": "loja-rj-01",
      "qrCodeText": "00020126870014br.gov.bcb.pix..."
    }
    ```
  </Tab>

  <Tab value="Callback">
    ```json
    {
      "id": "PAYZU20260811K7M2X9QP4T000000",
      "type": "DEPOSIT",
      "status": "COMPLETED",
      "amount": 99.90,
      "clientReference": "order-1234",
      "virtualAccount": "loja-rj-01",
      "paidAt": "2026-08-11T10:46:26.986Z"
    }
    ```
  </Tab>
</Tabs>

## 仅列出某个租户的交易 [#仅列出某个租户的交易]

<Tabs items="['curl', 'Node.js']">
  <Tab value="curl">
    ```bash
    curl "https://api.payzu.processamento.com/v1/user/transactions?virtualAccount=loja-rj-01&dateFrom=2025-11-01" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json"
    ```
  </Tab>

  <Tab value="Node.js">
    ```ts
    const url = new URL('https://api.payzu.processamento.com/v1/user/transactions');
    url.searchParams.set('virtualAccount', 'loja-rj-01');
    url.searchParams.set('dateFrom', '2025-11-01');

    const res = await fetch(url, {
      headers: {
        Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
        'Content-Type': 'application/json',
      },
    });
    ```
  </Tab>
</Tabs>

## 路由 callback [#路由-callback]

```ts
async function payzuWebhook(tx: PayzuCallback) {
  const tenantId = tx.virtualAccount;
  if (!tenantId) {
    log.warn('callback 缺少 virtualAccount', { id: tx.id });
    return;
  }

  const handler = tenantHandlers[tenantId];
  if (!handler) {
    log.error('未知租户', { tenantId, id: tx.id });
    return;
  }

  await handler.process(tx);
}
```

## `virtualAccount` 对比 `clientReference` [#virtualaccount-对比-clientreference]

两者是**独立且互补**的字段。请始终同时使用。

| 字段                | 粒度   | 用途           |
| ----------------- | ---- | ------------ |
| `clientReference` | 每笔交易 | 幂等性 + 按订单查询。 |
| `virtualAccount`  | 每个租户 | 路由 + 列表过滤。   |

只需在同一个创建 payload 中同时传入这两个字段，如上方示例所示。

## 常见陷阱 [#常见陷阱]

| 陷阱                                  | 症状             |
| ----------------------------------- | -------------- |
| 使用 `clientReference` 来标识租户          | 无法在列表中过滤，查询复杂化 |
| `virtualAccount` 每次都变化（时间戳、可变 slug） | 列表碎片化          |
| 不处理缺少 `virtualAccount` 的 callback   | 路由在遗留交易上崩溃     |
| 在处理器中硬编码租户                          | 每个新客户都需要手动接入   |