> For the complete documentation index, see [llms.txt](https://helpdocs.ycloud.com/partner-center/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://helpdocs.ycloud.com/partner-center/technology-development-partnern/qian-ru-shi-zhu-ce.md).

# 嵌入式注册

本文档介绍了如何实现嵌入式注册并捕获其生成的数据，以便让新客户通过您的软件创建WABA。

## 步骤1：添加允许的域名 <a href="#step-1--add-allowed-domains" id="step-1--add-allowed-domains"></a>

登录Meta开发者平台 [App Dashboard](https://developers.facebook.com/apps) ， 前往 **Facebook Login for Business** > **Settings** > **Client OAuth settings**:

<figure><img src="https://scontent-hkg4-1.xx.fbcdn.net/v/t39.2365-6/465708937_913631386932225_3931496644600528212_n.png?_nc_cat=110&#x26;ccb=1-7&#x26;_nc_sid=e280be&#x26;_nc_ohc=sIEt9lKGcS0Q7kNvwGwfiiM&#x26;_nc_oc=AdknZNhyb-RbAgoCzMPuc_C2ZXTSMvHYtonp9xEn54zqENctPMonou-BcZlEnKDGm7M&#x26;_nc_zt=14&#x26;_nc_ht=scontent-hkg4-1.xx&#x26;_nc_gid=KewqQkxMs2vkbZVoxnONzg&#x26;oh=00_AfYpn1aFaHjzCdMl8LYvcPZrCj7ONwA7RrwrNNE-Xp_UKw&#x26;oe=68E331CC" alt=""><figcaption></figcaption></figure>

将以下开关设置为 **Yes**：

* **Client OAuth login**
* **Web OAuth login**
* **Enforce HTTPS**
* **Embedded Browser OAuth Login**
* **use Strict Mode for redirect URIs**
* **Login with the JavaScript SDK**

{% hint style="info" %}
**注意**：\
\- 嵌入式注册 (Embedded Signup) 依赖于 JavaScript SDK。\
\- 当企业客户完成嵌入式注册流程时，客户的 **WABA ID**、**企业电话号码 ID**  会返回到触发该流程的窗口，但前提是：该窗口所在页面的域名必须已添加到 **Allowed domains** 和 **Valid OAuth redirect URIs** 字段中。请将你计划部署嵌入式注册的所有域名（包括开发环境下测试流程用的域名）添加到上述字段中。

\- 仅支持启用了 **HTTPS** 的域名
{% endhint %}

## 步骤2: 创建 **Facebook Login for Business** ConfigurationID <a href="#step-2--create-a-facebook-login-for-business-configuration" id="step-2--create-a-facebook-login-for-business-configuration"></a>

Facebook Login for Business 配置定义了在企业客户使用 **嵌入式注册 (Embedded Signup)** 时，需要请求哪些权限以及收集哪些额外信息。

在控制台中导航到 **Facebook Login for Business > Configurations**

<figure><img src="https://scontent-hkg1-2.xx.fbcdn.net/v/t39.2365-6/518383927_1808192009811748_4848992549354412342_n.png?_nc_cat=107&#x26;ccb=1-7&#x26;_nc_sid=e280be&#x26;_nc_ohc=uQCNTsbeOb4Q7kNvwE-6FPf&#x26;_nc_oc=Adn70OzqwRCOY7TveR1wkTMw5EBU6VF_0s8QX2HGwOMiFcXXJow8TaIt5FtcC4AfTvw&#x26;_nc_zt=14&#x26;_nc_ht=scontent-hkg1-2.xx&#x26;_nc_gid=KewqQkxMs2vkbZVoxnONzg&#x26;oh=00_AfaHaf4UsUyZkYEmR2xEKW_XG3Rszd64CgbjgZsjBvVCTQ&#x26;oe=68E33255" alt=""><figcaption></figcaption></figure>

点击 **Create from template** 按钮，选择 **WhatsApp Embedded Signup Configuration With 60 Expiration Token** 模板来创建配置。

该模板会生成一个包含最常用权限和访问级别的配置。

![](https://scontent-hkg4-1.xx.fbcdn.net/v/t39.2365-6/517194886_4216258301935474_6660886375301368534_n.png?_nc_cat=100\&ccb=1-7&_nc_sid=e280be&_nc_ohc=fWICyCQVs6sQ7kNvwFaHNrx&_nc_oc=AdltqNr7IT27q1iAMpRxuSGNExwaaqr4B3XVfv7wmy809b5RPNvqDBXaZhXNJK5SnzU&_nc_zt=14&_nc_ht=scontent-hkg4-1.xx&_nc_gid=KewqQkxMs2vkbZVoxnONzg\&oh=00_AfZZ60ZXSbdSvbi3SW16habeixjyyUGU3vTOuOJsx45MsA\&oe=68E32FD5)

配置完成后，请记录下 **Configuration ID**，因为在下一步中会用到它。

## 步骤3：将嵌入式注册（Embedded Signup）集成到你的网站

把下面的 **HTML** 和 **JavaScript** 代码加入你的网站。这些就是实现 Embedded Signup 所需的完整代码。

我们建议根据您提供的解决方案或企业客户的需求，构建不同的嵌入式注册。它们分别用于：

* [创建WhatsApp API Account ](https://www.ycloud.com/whatsapp-business-api)
* [WhatsApp Business App 共存](https://www.ycloud.com/whatsapp-business-app-coexistence)

### 嵌入式注册 - 用于创建WhatsApp API Account&#x20;

#### 1.创建嵌入式注册按钮

```
<html>
  <head>
    <meta charset="utf-8" />
    <script>
      window.fbAsyncInit = function () {
        // JavaScript SDK configuration and setup
        FB.init({
          appId: '{YOUR-FACEBOOK-APP-ID}', // Facebook App ID
          cookie: true, // enable cookies
          xfbml: true, // parse social plugins on this page
          version: 'v22.0', //Graph API version
        })
      }

      // Load the JavaScript SDK asynchronously
      ;(function (d, s, id) {
        var js,
          fjs = d.getElementsByTagName(s)[0]
        if (d.getElementById(id)) {
          return
        }
        js = d.createElement(s)
        js.id = id
        js.setAttribute('defer', true)
        js.src = 'https://connect.facebook.net/en_US/sdk.js'
        fjs.parentNode.insertBefore(js, fjs)
      })(document, 'script', 'facebook-jssdk')

      // Facebook Login with JavaScript SDK
      function launchWhatsAppSignup() {
        // Launch Facebook login
        FB.login(
          function (response) {
            if (response.status === 'connected' && response.authResponse) {
              const code = response.authResponse.code
              console.log('User authResponse code:', code)
              // The returned code must be transmitted to your backend,
              // which will perform a server-to-server call from there to our servers for an access token
            } else {
              console.log('User cancelled login or did not fully authorize.')
            }
          },
          {
            config_id: '{YOUR-CONFIGURATION-ID}',
            response_type: 'code', // must be set to 'code' for System User access token
            override_default_response_type: true, // when true, any response types passed in the "response_type" will take precedence over the default types
            extras: {
              features: [
                {
                  name: 'marketing_messages_lite',
                },
              ],
              setup: {
                solutionID: '{YOUR-SOLUTION-ID}' // add solution ID here, ensure it is in quotes
              },
              sessionInfoVersion: '3',
            },
          },
        )
      }

      const sessionInfoListener = (event) => {
        if (event.origin == null) {
          return
        }

        // Make sure the data is coming from facebook.com
        if (!event.origin.endsWith('facebook.com')) {
          return
        }

        try {
          const data = JSON.parse(event.data)
          if (data.type === 'WA_EMBEDDED_SIGNUP') {
            // if user finishes the Embedded Signup flow
            if (data.event === 'FINISH') {
              const { phone_number_id, waba_id, businessId } = data.data
              console.log(
                'Business ID ',
                businessId,
                'Phone number ID ',
                phone_number_id,
                ' WhatsApp business account ID ',
                waba_id,
              )
            }
            // if user reports an error during the Embedded Signup flow
            else if (data.event === 'ERROR') {
              const { error_message } = data.data
              console.error('error ', error_message)
            }
            // if user cancels the Embedded Signup flow
            else {
              const { current_step } = data.data
              console.warn('Cancel at ', current_step)
            }
          }
        } catch {
          // Don’t parse info that’s not a JSON
          console.log('Non JSON Response', event.data)
        }
      }

      window.addEventListener('message', sessionInfoListener)
    </script>
  </head>

  <body>
    <button
      onclick="launchWhatsAppSignup()"
      style="
        background-color: #1877f2;
        border: 0;
        border-radius: 4px;
        color: #fff;
        cursor: pointer;
        font-family: Helvetica, Arial, sans-serif;
        font-size: 16px;
        font-weight: bold;
        height: 40px;
        padding: 0 24px;
      "
    >
      Launch Embedded Signup
    </button>
  </body>
</html>
```

{% hint style="info" %}
**注意**

* 请将上面示例代码中的 appId、config\_id、solutionID 替换为实际值
* 前端获取到 waba\_id 和 phone\_number\_id 要传给后端，用于获取 WABA 和注册号码， 详见后文。
  {% endhint %}

更多细节参考：<https://developers.facebook.com/docs/whatsapp/embedded-signup/implementation>

#### 2.绑定WABA 和注册号码

客户完成嵌入式注册后，您的前端会拿到 `waba_id` 和 `phone_number_id` ，将其传给后端用于后续接口调用。

#### 绑定 WABA <a href="#ycloud-ji-shu-ti-gong-shang-he-zuo-huo-ban-ji-cheng-zhi-nan-huo-qu-waba" id="ycloud-ji-shu-ti-gong-shang-he-zuo-huo-ban-ji-cheng-zhi-nan-huo-qu-waba"></a>

调用 YCloud WABA绑定API，然后将其与您系统的客户的账号关联在一起。

请求示例：

```
curl -X POST -H 'X-API-Key: {{YOUR_API_KEY}}' \
    'https://api.ycloud.com/v2/whatsapp/businessAccounts/{wabaId}/tp/bind'
```

成功响应示例：

```
{
    "id": "{{waba_id}}",
    "name": "WABA name",
    "accountReviewStatus": "APPROVED",
    "paymentMethodAttached": true,
    "currency": "AUD",
    "timezoneId": "1"
}
```

**注意**：响应字段 `paymentMethodAttached` 为 `true` 表明 YCloud 已成功关联支付方式给此 WABA，否则，**请联系 YCloud Team解决该问题**。

#### 注册号码 <a href="#ycloud-ji-shu-ti-gong-shang-he-zuo-huo-ban-ji-cheng-zhi-nan-zhu-ce-hao-ma" id="ycloud-ji-shu-ti-gong-shang-he-zuo-huo-ban-ji-cheng-zhi-nan-zhu-ce-hao-ma"></a>

调用 YCloud [Register a phone number](https://docs.ycloud.com/reference/whatsapp_phone_number-register) 接口注册号码，接口响应 HTTP status 200 即成功。

一般地，号码注册成功后状态会由 PENDING 转为 CONNECTED，即可使用该号码发送消息。

请求示例：

```
curl -XPOST 'https://api.ycloud.com/v2/whatsapp/phoneNumbers/{{waba_id}}/{{phone_number_id}}/register' \
-H 'X-API-Key: {{YOUR-API-KEY}}'
```

成功响应示例：

```
{
  "phoneNumber": "{{phonenumber}}",
  "wabaId": "{{waba_id}}",
  "verifiedName": "Phone number name",
  "qualityRating": "GREEN",
  "messagingLimit": "TIER_250",
  "status": "CONNECTED"
}
```

<br>

### 嵌入式注册 - WhatsApp Business App 共存 <a href="#bu-zhou-7-jiang-whatsapp-api-neng-li-ji-cheng-dao-zi-you-ying-yong-zhong" id="bu-zhou-7-jiang-whatsapp-api-neng-li-ji-cheng-dao-zi-you-ying-yong-zhong"></a>

#### 1.创建嵌入式注册按钮 <a href="#bu-zhou-7-jiang-whatsapp-api-neng-li-ji-cheng-dao-zi-you-ying-yong-zhong" id="bu-zhou-7-jiang-whatsapp-api-neng-li-ji-cheng-dao-zi-you-ying-yong-zhong"></a>

```
<html>
  <head>
    <meta charset="utf-8" />
    <script>
      window.fbAsyncInit = function () {
        FB.init({
          appId: '{YOUR-FACEBOOK-APP-ID}',
          cookie: true,
          xfbml: true,
          version: 'v22.0',
        });
      };
      (function (d, s, id) {
        var js,
          fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s);
        js.id = id;
        js.setAttribute('defer', true);
        js.src = 'https://connect.facebook.net/en_US/sdk.js';
        fjs.parentNode.insertBefore(js, fjs);
      })(document, 'script', 'facebook-jssdk');

      function launchWhatsAppSignup() {
        FB.login(
          function (response) {
            if (response.status === 'connected' && response.authResponse) {
              const code = response.authResponse.code;
              console.log('User authResponse code:', code);
            } else {
              console.log('User cancelled login or did not fully authorize.');
            }
          },
          {
            config_id: '{YOUR-CONFIGURATION-ID}',
            response_type: 'code',
            override_default_response_type: true,
            extras: {
              setup: { solutionID: '{YOUR-SOLUTION-ID}' },
              sessionInfoVersion: 3,
              featureType: 'whatsapp_business_app_onboarding',
            },
          },
        );
      }

      const sessionInfoListener = (event) => {
        if (!event.origin?.endsWith('facebook.com')) return;
        try {
          const data = JSON.parse(event.data);
          if (data.type === 'WA_EMBEDDED_SIGNUP') {
            if (data.event === 'FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING' || (data.event === 'FINISH' && data.data.is_wa_login_user)) {
              const { business_id, waba_id, phone_number_id } = data.data;
              console.log('Business ID ', business_id, 'WABA ID ', waba_id, 'Phone number ID ', phone_number_id);
            } else if (data.event === 'ERROR') {
              console.error('error ', data.data.error_message);
            } else {
              console.warn('Cancel at ', data.data.current_step);
            }
          }
        } catch {
          console.log('Non JSON Response', event.data);
        }
      };

      window.addEventListener('message', sessionInfoListener);
    </script>
  </head>
  <body>
    <button
      onclick="launchWhatsAppSignup()"
      style="background-color: #1877f2; border: 0; border-radius: 4px; color: #fff; cursor: pointer; font-family: Helvetica, Arial, sans-serif; font-size: 16px; font-weight: bold; height: 40px; padding: 0 24px"
    >
      Launch Embedded Signup
    </button>
  </body>
</html>
```

#### 2.获取WABA并绑定到YCloud

客户完成嵌入式注册后，您的前端会拿到 `waba_id`  ，将其传给后端用于后续接口调用。

调用 YCloud SMB绑定API，调用成功后将其与您系统的客户的账号关联在一起。

请求示例：

```
curl 'POST /v2/whatsapp/businessAccounts/{wabaId}/smb/bind' \
-H 'X-API-Key: {{YOUR-API-KEY}}'
```

成功响应示例：

```
{
  "id": "{{phonenumber_id}}",
  "phoneNumber": "{{phonenumber}}",
  "wabaId": "{{waba_id}}",
  "qualityRating": "GREEN",
  "messagingLimit": "TIER_1K",
  "verifiedName": "John's Cake Shop",
  "codeVerificationStatus": "VERIFIED",
  "isOfficialBusinessAccount": true,
  "status": "PENDING",
  "nameStatus": "APPROVED",
  "newNameStatus": "APPROVED",
  "decision": "APPROVED",
  "requestedVerifiedName": "string",
  "rejectionReason": "string",
  "qualityUpdateEvent": "ONBOARDING"
}

```

## 常见问题

<details>

<summary>如何判断嵌入式注册配置是否正确？</summary>

您配置了 solutionID，客户在 Facebook 授权时将看到 Solution Partner 对应的真实名称，若没有，说明配置未生效。请确保完成 [App Review](#bu-zhou-8-app-review)。

![](/files/EIWiAJiQehRh9TtwVssL)

</details>

<details>

<summary>什么情况 YCloud 无法给 WABA 关联支付方式？</summary>

用户可能选择了一个原有的 WABA 而非新建的 WABA，而原有的 WABA 可能有支付方式未解除。

</details>

<details>

<summary>嵌入式注册报错 App not active</summary>

打开嵌入式注册页面提示：

*App not active*

*This app is not currently accessible and the app developer is aware of the issue. You will be able to log in when the app is reactivated.*

App 模式为 Development 时，只有测试用户拥有权限时（到 App Dashboard > App roles > Roles / Test Users 查看）才可打开。

解决方案：将 App 模式切换为 **Live**，到 [Meta Apps](https://developers.facebook.com/apps) 点击对应的 App 进入 Dashboard 进行操作；或者为当前用户授权，详见 [Assign business assets to people in your business portfolio](https://www.facebook.com/business/help/325571851329683?id=2190812977867143)。

</details>

<details>

<summary>嵌入式注册报错 Feature unavailable</summary>

打开嵌入式注册页面提示：

*Feature unavailable*

*Facebook Login is currently unavailable for this app as we are updating additional details for this app. Please try again later.*

请到 App Dashboard > App Review > Permissions and Features 申请 **public\_profile** 高级访问权限。<br>

</details>
