> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用业务范围用户 ID

> 使用 BSUID 发送 WhatsApp 消息和发起通话、请求电话号码、管理 Meta 通讯录条目，以及处理 BSUID Webhook 字段。

## 为什么存在 BSUID

WhatsApp 将于 2026 年逐步推出可选的用户名功能。当用户启用用户名时，WhatsApp 可以显示用户名而不是用户的电话号码，并可能在 Webhook 有效负载中省略电话号码。每个用户均可自主决定是否启用用户名，因此企业不能仅依靠电话号码作为识别客户的唯一方式。Meta 因此要求 WhatsApp Business Platform 企业和合作伙伴以及 Click-to-WhatsApp 广告主支持 BSUID，以便他们能够继续处理来自启用用户名的用户的消息。

为支持此变更，Meta 于 2026 年 4 月初开始在 Webhook 有效负载中添加业务范围用户 ID（BSUID）。BSUID 是一个 Meta 业务资产组合内单个 WhatsApp 用户的后端标识符。无论用户是否启用了用户名，Meta 都会在消息 Webhook 中包含该标识符；当用户的电话号码不可用时，可使用它向该用户发送消息。

用户名和 BSUID 具有不同的生命周期。用户可以更改其用户名而不更改电话号码或 BSUID。如果用户更改电话号码，Meta 会生成一个新的 BSUID。请分别存储这些标识符，并在收到电话号码变更系统事件时更新它们的关联。

如果在过去 30 天内企业电话号码与用户交换过消息或通话，或者 Meta 通讯录中包含该用户，电话号码仍可能会显示。请将电话号码和用户名字段视为条件性字段，并更新解析器和身份存储以接受 BSUID 以及存在的任何其他标识符。

本指南涵盖 BSUID 身份规则、消息和通话请求、Meta 通讯录以及集成需要存储的 Webhook 字段。

![WhatsApp 用户用户名示例](https://files.readme.io/c54a96e597abe46e0f10e95d3844aa9dfdc5f9b2f5d99f27a9fa535c342c190c-image.png)

## 了解各标识符

| 标识符 | 范围 | 示例 | 使用时机 |
| - | - | - | - |
| 电话号码 | 一个 WhatsApp 账户 | `+16315551111` | 在电话号码可用且操作需要时使用。 |
| BSUID | 一个 Meta 业务资产组合和一个 WhatsApp 用户 | `US.13491208655302741918` | 从同一资产组合中的任何企业电话号码使用。 |
| 父 BSUID | 一组关联的 Meta 业务资产组合和一个 WhatsApp 用户 | `US.ENT.11815799212886844830` | 仅在 Meta 为关联资产组合启用父 BSUID 后使用。 |

Meta 会自动生成常规 BSUID。每个 BSUID 均以用户的 ISO 3166 alpha-2 两位字母国家/地区代码开头，后跟一个句点以及最多 128 个字母数字字符。请保留完整的值。不要移除或更改国家/地区前缀、句点或标识符字符。

BSUID 具有以下生命周期规则：

* BSUID 对于单个业务资产组合和用户配对是唯一的。
* 当用户更改电话号码时，用户的 BSUID 会发生变化。
* 父 BSUID 适用于 Meta 为其启用了该功能的已关联资产组合。
* 企业电话号码无法使用限定于其他
  资产组合的常规 BSUID。

<Warning>
  一键式、零点击和复制代码身份验证模板需要电话
  号码。请勿仅使用 BSUID 发送这些模板类型。
</Warning>

如需关联资产组合并使用父 BSUID，请让您的 Meta 联系人检查您的资格。在 Meta 启用父 BSUID 后，您可以继续在其原始资产组合中使用常规 BSUID。

![业务范围用户 ID 示例](https://files.readme.io/c5d4091ce670e159e8d0e82cca1f053a08419c2c3df42b50631e5e163bd88f16-image.png)

## 准备工作

* 将您的 YCloud API 密钥存储在 `YCLOUD_API_KEY` 中。
* 使用由常规 BSUID 所在同一资产组合所拥有的 WhatsApp 企业电话
  号码。
* 让您的 Webhook 端点订阅集成使用的 WhatsApp 事件。
* 在反序列化 Webhook 时，将每个新的 BSUID、父 BSUID、电话号码和用户名字段均
  视为可选字段。
* 当常规 BSUID 和父 BSUID 同时存在时，分别独立存储它们。

## 使用 BSUID 发送消息

两个 WhatsApp 消息端点均接受 `recipient`：

| 端点 | 行为 |
| - | - |
| `POST /whatsapp/messages/sendDirectly` | 同步向 WhatsApp Business API 提交消息。 |
| `POST /whatsapp/messages` | 将消息排队以进行异步提交。 |

将 `recipient` 设置为常规 BSUID 或父 BSUID。当您希望 YCloud 通过 BSUID 寻址用户时，省略 `to`。

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/messages/sendDirectly \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "type": "text",
    "text": {
      "body": "Hello from YCloud!"
    }
  }'
```

在 `POST /whatsapp/messages` 中使用相同的请求体将消息加入队列。

| 输入 | 结果 |
| - | - |
| 仅 `to` | YCloud 发送到该电话号码。 |
| 仅 `recipient` | YCloud 发送到该 BSUID 或父 BSUID。 |
| 同时提供 `to` 和 `recipient` | YCloud 使用 `to` 并忽略 `recipient`。 |
| 两个字段均未提供 | YCloud 拒绝该请求。 |

## 请求获取用户的电话号码

当工作流程需要 Webhook 中未包含的电话号码时，请使用请求联系人信息消息。由用户决定是否共享。

### 使用模板按钮

向功能性模板或营销模板添加 `REQUEST_CONTACT_INFO` 按钮。按钮文本固定为 `Share Contact Info`，且该按钮不接受发送时参数。

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "buttons",
  "buttons": [
    {
      "type": "REQUEST_CONTACT_INFO",
      "text": "Share Contact Info"
    }
  ]
}
```

在发送模板之前创建并批准该模板。有关完整的模板请求，请参阅 [请求电话号码模板](/zh/api-reference/guides/examples/api-examples/whatsapp-template-creation-examples#request-phone-number-template)。

### 使用交互式消息

当您不需要模板时，请发送交互式 `request_contact_info` 消息：

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/messages/sendDirectly \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "type": "interactive",
    "interactive": {
      "type": "request_contact_info",
      "body": {
        "text": "Please share your phone number."
      },
      "action": {
        "name": "request_contact_info"
      }
    }
  }'
```

### 处理联系人响应

当用户共享联系人信息时，YCloud 会发送一个 `whatsapp.inbound_message.received` 事件，其消息 `type` 为 `contacts`。对于针对您请求的响应，`contacts[].origin` 为 `contact_request`。

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "whatsapp.inbound_message.received",
  "whatsappInboundMessage": {
    "fromUserId": "US.13491208655302741918",
    "type": "contacts",
    "contacts": [
      {
        "origin": "contact_request",
        "phones": [
          {
            "phone": "+16315551111",
            "wa_id": "16315551111"
          }
        ]
      }
    ]
  }
}
```

验证事件签名，使用 `2xx` 响应确认收到，并异步处理电话号码。直接从 WhatsApp 共享的联系人还可以包含 vCard。

![请求联系人信息按钮](https://files.readme.io/25f756fa17526a20962fb5984ea8ed13a460bbf4cc241976de79a16ea4e16f1e-image.png)

## 了解 Meta 的联系人通讯录

Meta 的联系人通讯录存储了用户电话号码与 BSUID 之间的关联。启用该功能后，使用用户的电话号码发送或接收消息或呼叫会同时记录这两个标识符。之后，即使该用户启用了用户名，Meta 仍可在 Webhook 中包含该关联。

联系人通讯录归属于各个独立的业务资产组合（Business Portfolio）。关联的资产组合不会共享或同步其条目：请在每个资产组合中独立记录关联。

Meta 会保留条目，直到您停用该功能或停用账户。您可以在 **Meta Business Suite > 业务设置 > 业务信息** 中停用它。停用该功能会删除存储的条目并停止记录新条目。重新启用将开始收集新条目，但不会恢复已删除的数据。

![Meta 联系人通讯录设置](https://files.readme.io/c1465b831ff80153963ef8dac686f92dfbdc2758a8ae93a113c692c5f404b148-image.png)

### 联系人请求与本地存储（Local Storage）

当用户通过请求联系人信息按钮共享其电话号码时，如果已启用该功能，Meta 会将该电话号码添加到联系人通讯录中。对于使用本地存储（Local Storage）的企业，Meta 会从共享的 vCard 中提取电话号码，并存储在 Meta 数据中心的联系人通讯录中。其他 vCard 数据不会保留超过标准保留期。

Meta 已移除了之前需要发送单独消息才能捕获此关联的要求。有关当前的本地存储行为，请参阅 [官方 BSUID 文档](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids#contact-book)。

### 删除 Meta 联系人通讯录条目

通过一个 WhatsApp 商业电话号码删除普通 BSUID 的 Meta 联系人通讯录条目：

`DELETE /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/contactBook/{bsuid}`

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request DELETE \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/WABA_ID/%2B16315551111/contactBook/US.13491208655302741918" \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Accept: application/json"
```

对此操作使用标准 BSUID。不支持包含 `.ENT.` 的父级 BSUID。手动构建路径时，请将电话号码前导的 `+` 进行 URL 编码为 `%2B`。

HTTP `200` 响应始终包含 `success: true`。`deleted` 值为 `true` 表示 Meta 删除了匹配的条目。值为 `false` 表示 Meta 处理了请求但未找到匹配条目。

删除条目不会删除 YCloud 联系人、消息或 BSUID 业务记录。删除后，同一 Meta 业务资产组合中商业电话号码的 Webhook 事件将不再同时包含用户的电话号码和 BSUID。Meta 的 30 天缓存仍可提供这两个标识符，后续的交互可以再次创建联系人通讯录条目。

## 使用 BSUID 发起呼叫

`POST /whatsapp/calls/connect` 也接受 `recipient`。适用相同的目标规则：提供 `to` 或 `recipient`，两者同时存在时以 `to` 为准。

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/calls/connect \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "sdpType": "offer",
    "sdp": "SDP_OFFER"
  }'
```

有关完整的呼叫生命周期，请参阅 [管理 WhatsApp 呼叫](/zh/api-reference/guides/whatsapp-platform/manage-whatsapp-calls)。

## 处理 BSUID Webhook 字段

以下字段是对现有事件载荷的补充。在定义数据模型时，请保留事件的顶级对象。

| 事件 | 可选存储字段 |
| - | - |
| `whatsapp.message.updated` | `whatsappMessage.recipientUserId`, `whatsappMessage.parentRecipientUserId`, `whatsappMessage.customerProfile.name`, `whatsappMessage.customerProfile.username` |
| `whatsapp.inbound_message.received` | `whatsappInboundMessage.fromUserId`, `whatsappInboundMessage.fromParentUserId`, `whatsappInboundMessage.customerProfile.username` |
| `whatsapp.user.preferences` | `whatsappUserPreference.userId`, `whatsappUserPreference.parentUserId` |
| `whatsapp.call.connect` | `callingConnect.toUserId`, `callingConnect.toParentUserId`, `callingConnect.fromUserId`, `callingConnect.fromParentUserId` |
| `whatsapp.call.terminate` | `callingTerminate.toUserId`, `callingTerminate.toParentUserId`, `callingTerminate.fromUserId`, `callingTerminate.fromParentUserId` |
| `whatsapp.call.status.updated` | `callingStatusUpdated.recipientUserId`, `callingStatusUpdated.parentRecipientUserId` |
| `whatsapp.group.participants_update` | `whatsappGroup.recipientUserId`、`whatsappGroup.parentRecipientUserId`、`whatsappGroup.customerProfile.username`，以及 `whatsappGroup.addedParticipants[]`、`whatsappGroup.removedParticipants[]` 和 `whatsappGroup.failedParticipants[]` 中的 `recipientUserId` 和 `parentRecipientUserId` 字段 |
| `whatsapp.smb.history` | `whatsappInboundMessage.fromUserId`, `whatsappInboundMessage.fromParentUserId`, `whatsappInboundMessage.customerProfile.username`, `whatsappMessage.toUserId`, `whatsappMessage.toParentUserId` |
| `whatsapp.smb.app.state.sync` | `whatsappSmbAppStateSync.stateSync[].contact.userId`, `whatsappSmbAppStateSync.stateSync[].contact.parentUserId`, `whatsappSmbAppStateSync.stateSync[].contact.username` |
| `whatsapp.smb.message.echoes` | `whatsappMessage.toUserId`, `whatsappMessage.toParentUserId`, `whatsappMessage.customerProfile.username` |

适用以下省略规则：

* 未启用父级 BSUID 时，父级 BSUID 字段不存在。
* 当您通过电话号码向用户发送消息或发起呼叫时，
  已发送消息或呼叫目标字段可能会缺失。
* `customerProfile` 会出现在 `sent`、`delivered` 和 `read` 消息更新中，
  但不会出现在 `failed` 更新中。
* 当用户未启用用户名时，`customerProfile.username` 不存在。
  它在 `sent` 状态更新中也不存在。
* 即使存在对应的 BSUID，电话号码也可能不存在。

### 处理用户更换电话号码

当入站消息包含 `type: system` 和 `system.type: user_changed_number` 时，请用新值替换旧的身份映射关系。`system` 对象的 BSUID 字段名称保留 Meta 的 snake\_case 格式。

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "system",
  "system": {
    "type": "user_changed_number",
    "wa_id": "16315552222",
    "user_id": "US.13491208655302741919",
    "parent_user_id": "US.ENT.11815799212886844831"
  }
}
```

将 `parent_user_id` 视为可选字段。保留旧值和新值足够长的时间，以便核对现有会话并幂等地更新您的身份存储。

## 商业用户名

商业用户名可帮助客户在 WhatsApp 中找到您的商家。它不会隐藏您的商业电话号码。每个电话号码只能有一个用户名，且两个 WhatsApp 电话号码不能共用一个用户名。

消费者用户名可能会发生变更，但用户的 BSUID 保持不变。请将用户名作为个人资料信息保存，而不是将其用作身份主键。

有关 3–35 个字符的格式规则以及申领和审核流程，请参阅 [申领商业用户名](/zh/documentation/channels/whatsapp-accounts-management/phone-number-management/claim-a-business-username)。

![商业用户名示例](https://files.readme.io/6e95c9da234529464ce05185f1771b12f3afe2c8c9dca9d0d37675f5b9a7950a-image.png)

### 预留用户名

您可以申领 Meta 预留的符合资格的用户名，也可以为您的品牌选择其他用户名。使用 WhatsApp 管理工具、Meta Business Suite 或用户名 API。审核通过本身并不意味着该用户名已对客户生效。

如果预留用户名属于您的 Facebook 公共主页或 Instagram 账户，请在申领前将您的商业电话号码关联到该公共主页或账户。您可以在 Meta Business Suite 或 WhatsApp 管理工具中申领用户名时进行关联，也可以[将电话号码添加到公共主页或账户](https://www.facebook.com/business/help/4631406400243963)。您需要拥有完全控制权或具有 `manage_phone` 权限的基础部分访问权限。

### 聊天窗口显示优先级

WhatsApp 按以下顺序显示商家身份：

1. 保存在客户通讯录中的名称。
2. 已验证的商家名称或官方商业账户名称。
3. 商业用户名。
4. 电话号码。

您的商业电话号码在商业资料中依然可见。

## 迁移清单

1. 将所有与 BSUID 相关的 Webhook 字段添加到您的反序列化模型中作为
   可选字段。
2. 将常规 BSUID 和父级 BSUID 与电话号码和用户名分开存储。
3. 按投资组合和 BSUID 建立客户身份索引。切勿将 BSUID 视为
   全局通用的标识符。
4. 通过 `to` 或 `recipient` 路由消息和通话请求，并测试
   `to` 优先级规则。
5. 测试仅用户名用户、缺失电话号码、电话号码变更、缺失
   父级 BSUID、重复 Webhook 以及通讯录重建等场景。

<CardGroup cols={2}>
  <Card title="消息状态示例" icon="message-check" href="/zh/api-reference/guides/examples/webhook-examples/whatsapp-message-updated-webhook-examples">
    检查已发送、已送达、已读和失败的消息载荷。
  </Card>

  <Card title="入站消息示例" icon="inbox" href="/zh/api-reference/guides/examples/webhook-examples/whatsapp-inbound-message-webhook-examples">
    检查联系人、系统更新及其他入站载荷。
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.