← 所有文章
教學

WhatsApp Passkey QR 認證:安全完成 Webhook 接入

WhatsApp QR 配對有時會要求 Passkey 身分確認。如果狀態變成 passkey_required,唔好重開帳號,亦唔好建立第二條 WhatsApp 連線;應該繼續同一個認證 session,讓帳號持有人完成瀏覽器內的 WebAuthn credential prompt,再把 response 交給 UnifyPort,等待 authorized 以及之後的簽名 Webhook 事件。

重點

  • WhatsApp 官方 Help Center 說明,Passkey 會把帳號連到手機安全系統,例如指紋、Face ID 或螢幕鎖,用作身分確認。
  • WhatsApp Business linked-device 流程支援 QR code 掃描及 8 字元電話號碼 code;兩者都可能要求在主手機上確認身分。
  • 在 UnifyPort,Passkey 是 WhatsApp QR 認證的延續狀態:passkey_requiredpasskey_pending → 可選 passkey_confirmationauthorized
  • 先登記 Webhook,再做認證,才不會漏接 account.auth.requiredaccount.auth.succeeded 和之後的 message.received
  • 如果接收端仍未完成,先看 webhook-first inbound checklist;簽名排查可參考 HMAC replay protection guide

WhatsApp 其實要求你做甚麼

這不是新的 messaging API credential,而是 WhatsApp 帳號存取流程中的用戶身分確認。

WhatsApp 官方 Passkey 文件說,Passkey 使用裝置安全系統,並可在 WhatsApp 需要驗證身分時使用。官方 linked-device 文件亦說明 WhatsApp Business 可用 QR code 或電話號碼 code 配對,並可能要求用 biometric authentication 或手機解鎖 PIN 確認。換言之,當 UnifyPort QR 流程到達 Passkey 分支,應把它視為需要用戶參與的認證步驟,而不是後端可自行產生的 secret。

後端負責保存 UnifyPort messaging account 狀態與 Webhook receiver;帳號持有人負責在 browser 或已授權手機上完成 WebAuthn prompt。請勿在 log 保存完整 authorize_urlauth_payload.public_key 或 serialized credential response。

UnifyPort 流程

實作時請打開 Create provider authorization sessionSubmit Passkey credential response。核心狀態如下:

狀態意思要做的事
awaiting_qr_scanQR code 有效顯示給帳號持有人,並輪詢 GET /v1/accounts/{account_id}/authPOST /v1/accounts/{account_id}/auth/qr/check
passkey_requiredWhatsApp 需要 WebAuthn credential開啟 hosted authorize_url,讓持有人完成 browser prompt。
passkey_pendingCredential 已提交繼續輪詢 auth state,不要啟動新流程。
passkey_confirmation需要額外確認持有人確認後呼叫 POST /v1/accounts/{account_id}/auth/passkey-confirm
authorized認證完成runtime 通常自動啟動;觀察 account.auth.succeededaccount.started

步驟 1:先建立 Webhook

curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://ops.example.com/unifyport/webhook",
  "status": "active",
  "subscribed_events": ["account.auth.required", "account.auth.succeeded", "message.received"],
  "signing_secret": "stored-in-your-secret-manager",
  "retry_policy": { "max_attempts": 3 }
}'

正式環境 receiver 應使用 raw body 驗證 X-Device-Signature。完整規則見 Webhook delivery:HMAC-SHA256 input 是 X-Device-Timestamp + "." + raw request body

步驟 2:建立 WhatsApp messaging account

curl -X POST https://api.unifyport.ai/v1/accounts \
  -H "X-Api-Key: $UNIFYPORT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "WhatsApp Support Passkey Test",
  "provider": "whatsapp",
  "region": "global",
  "status": "active",
  "auth_mode": "qrcode",
  "capabilities": ["send_message", "receive_message"],
  "provider_data": { "device_os": "Chrome", "device_platform": "web" },
  "metadata": { "environment": "staging" }
}'

保存回傳的 account_id。Account object 會顯示 runtime_status;auth state、QR code 和 Passkey payload 則透過 authentication endpoint 讀取。

步驟 3:啟動 QR 認證並接續 Passkey

curl -X POST https://api.unifyport.ai/v1/accounts/acc_whatsapp_passkey_test/auth-sessions \
  -H "X-Api-Key: $UNIFYPORT_API_KEY"

如果 response 或後續檢查顯示 passkey_required,把 authorize_url 交給帳號持有人開啟。Browser 會產生 WebAuthn credential response;你的可信交接層再把它提交到 POST /v1/accounts/{account_id}/auth/passkey-response。若狀態變成 passkey_confirmation,確認後呼叫 /auth/passkey-confirm,再輪詢 /authauthorizedfailed

步驟 4:確認第一條入站事件

認證成功後,通常會先有 account event,然後是普通入站訊息:

{
  "id": "evt_2f9c1a4b7e",
  "type": "message.received",
  "provider": "whatsapp",
  "account_id": "acc_whatsapp_passkey_test",
  "occurred_at": "2026-09-10T08:15:21Z",
  "data": {
    "conversation": { "id": "8613912345678@s.whatsapp.net", "type": "user" },
    "sender": { "id": "8613912345678@s.whatsapp.net", "type": "user", "name": "Jordan Lee" },
    "message": { "id": "wamid.HBgM", "text": "Can you confirm my order?", "direction": "inbound", "sent_at": "2026-09-10T08:15:20Z" },
    "event": { "kind": "message_received" }
  }
}

之後 Passkey 分支已完結,按一般 WhatsApp inbound 流程儲存和 route 即可。如仍在設計整體方案,可參考連接 Telegram user account 到 Webhook第一個 API key 的 Webhook 測試清單

限制與取捨

若需要官方 business identity、templates、官方 analytics 或 Meta 管理的完整 policy surface,WhatsApp Business Platform 會較合適。若目標是把既有普通 WhatsApp inbox 接到簽名 Webhook,UnifyPort 的非官方接口更適合細團隊快速建立入站流程。

Passkey 不會取消用戶確認。它只是把確認步驟放進 runbook:用戶完成 credential prompt,server 不記錄敏感認證資料,Webhook 在帳號上線前已準備好。

FAQ

passkey_required 是錯誤嗎?

不是。它是 WhatsApp QR 認證中的正常延續狀態。繼續同一 session,提交 browser 產生的 credential response。

QR 進入 Passkey 後要建立新帳號嗎?

不要。新帳號可能造成重複 provider identity conflict。請繼續輪詢目前 auth state。

應保存甚麼?

保存 account_id、auth state、Webhook event ID 和收到的訊息。不要把完整 authorization URL 或 WebAuthn credential response 寫入 log。

2026-09-10 核對來源

UnifyPort API

令訊息接入變成一條穩定嘅產品管線。

先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。