嵌入式注册

嵌入式注册流程从您的企业客户收集与业务相关的信息,自动生成平台所需的所有 WhatsApp 资产,并授予您的应用访问这些资产的权限,以便您可以快速为您的企业客户提供 WhatsApp 消息服务。

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

步骤1:添加允许的域名

登录Meta开发者平台 App Dashboard , 前往 Facebook Login for Business > Settings > Client OAuth settings:

将以下开关设置为 Yes

  • Client OAuth login

  • Web OAuth login

  • Enforce HTTPS

  • Embedded Browser OAuth Login

  • use Strict Mode for redirect URIs

  • Login with the JavaScript SDK

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

- 仅支持启用了 HTTPS 的域名

步骤2: 创建 Facebook Login for Business ConfigurationID

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

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

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

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

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

步骤3:将嵌入式注册(Embedded Signup)集成到你的网站

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

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

嵌入式注册 - 用于创建WhatsApp API Account

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>

注意

  • 请将上面示例代码中的 appId、config_id、solutionID 替换为实际值

  • 前端获取到 waba_id 和 phone_number_id 要传给后端,用于获取 WABA 和注册号码, 详见后文。

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

2.获取 WABA 和注册号码

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

获取 WABA

调用 YCloud Retrieve a WABA 接口获取 WABA 详情,然后将其与您系统的客户的账号关联在一起。

请求示例:

curl 'https://api.ycloud.com/v2/whatsapp/businessAccounts/{{waba_id}}' \
-H 'X-API-Key: {{YOUR-API-KEY}}'

成功响应示例:

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

注意:响应字段 paymentMethodAttachedtrue 表明 YCloud 已成功关联支付方式给此 WABA,否则,请联系 YCloud Team解决该问题

注册号码

调用 YCloud Register a phone number 接口注册号码,接口响应 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"
}

嵌入式注册 - WhatsApp Business App 共存

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: {
              setup: {
                solutionID: '{YOUR-SOLUTION-ID}' // add solution ID here, ensure it is in quotes
              },
              sessionInfoVersion: 3,
              featureType: 'whatsapp_business_app_onboarding',
            },
          },
        )
      }

      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_WHATSAPP_BUSINESS_APP_ONBOARDING') {
              const { business_id, waba_id, phone_number_id } = data.data
              console.log(
                'Business ID ',
                businessId,
                ' WhatsApp business account ID ',
                waba_id,
                'Phone number ID ',
                phone_number_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>

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"
}

常见问题

如何判断嵌入式注册配置是否正确?

您配置了 solutionID,客户在 Facebook 授权时将看到 Solution Partner 对应的真实名称,若没有,说明配置未生效。请确保完成 App Review

什么情况 YCloud 无法给 WABA 关联支付方式?

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

嵌入式注册报错 App not active

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

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 点击对应的 App 进入 Dashboard 进行操作;或者为当前用户授权,详见 Assign business assets to people in your business portfolio

嵌入式注册报错 Feature unavailable

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

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 高级访问权限。

Last updated