內嵌結帳

整合內嵌結帳功能後,網路結帳程序就能內嵌在 Google 平台上。如果產品需要原生 API 無法支援的複雜邏輯 (例如自訂),請使用這個路徑。您將實作結帳 UI,透過 iframe 嵌入結帳流程。

什麼是內嵌結帳?

嵌入式結帳 (EC) 功能可讓主機 (例如 Google 搜尋或 AI 代理程式) 在應用程式中顯示現有的網頁結帳頁面 (使用 iframe 或 WebView)。與標準網頁重新導向不同,這項功能允許雙向通訊。主機可以「委派」特定工作,例如選取已儲存的地址或使用已儲存的憑證付款,提供更快速、更貼近原生的體驗,而您仍是記錄在案的商家,並處理實際的訂單建立作業。

商家導入檢查清單

如要支援嵌入式結帳流程,您必須在 UCP API 和前端結帳應用程式中,導入下列規定。

1. 啟用探索功能 (UCP API)

您必須在 UCP API 回應中聲明結帳程序支援內嵌擴充功能。

  • 動作:將 dev.ucp.shopping.embedded_checkout 功能物件新增至 UCP 回應功能陣列。
  • 規定:請加入規格和結構定義網址。
  • 選用:如要載入結帳頁面,必須先通過驗證 (例如 JWT 權杖),請將 auth.required 設為 true。
"capabilities": [
  {
    "name": "dev.ucp.shopping.embedded_checkout",
    "version": "2026-01-11",
    "spec": "https://ucp.dev/specs/shopping/embedded_checkout",
    "config": {
        "auth": { "required": true }
    }
  }
]

2. 處理網址初始化 (前端)

主機載入 continue_url 時,會附加特定查詢參數。前端必須在載入後立即剖析這些資料。

  • 動作:剖析下列網址查詢參數:
    • ec_version:通訊協定版本 (例如 2026-01-11)。
    • ec_auth:(如適用) 驗證主機提供的驗證權杖 (如果設定 auth.required: true)。
    • ec_delegate:以半形逗號分隔的動作清單,主機要以原生方式處理這些動作 (例如 payment.credentialfulfillment.address_changepayment.instruments_change)。

3. 建立通訊 (前端)

通訊會使用 postMessage,並採用 JSON-RPC 2.0 格式。

  • 動作:實作 message 事件的監聽器。
  • 規定:您必須驗證每則訊息的來源,確保來源與主機相符。
  • 原生支援:如果是原生應用程式主機,請檢查並使用注入的全域變數 (例如 window.EmbeddedCheckoutProtocolConsumer),如果 postMessage 無法使用。

4. 執行交握 (前端)

結帳程序完成後,請立即告知主機您已準備就緒,並確認接受哪些委派項目。

  • 動作:載入後立即傳送 ec.ready 要求。
  • 酬載:加入 delegate 陣列,列出您同意讓主機處理的功能。
  • 範例:如果要求的網址是 ec_delegate=payment.credential,且您接受,請在 ec.ready 酬載中加入 "payment.credential"
// Example: Sending the ec.ready message
const hostWindow = window.parent;
hostWindow.postMessage(JSON.stringify({
  "jsonrpc": "2.0",
  "id": "ready_1",
  "method": "ec.ready",
  "params": {
    "delegate": ["payment.credential"] // List capabilities you accept to delegate
  }
}), "*");

5. 實作委派邏輯 (前端)

如果您在交握中接受委派,就必須修改 UI 行為,以免發生衝突。

  • 動作:隱藏委派工作相關的 UI 元素。
  • 範例:如果 fulfillment.address_change 已委派,請隱藏地址表單,改為顯示「變更地址」按鈕。
  • 動作:使用者點選該按鈕時,傳送 _request 訊息 (例如 ec.fulfillment.address_change_request) 給主機。
  • 動作:等待主辦人回應。回應會包含新資料 (例如所選地址)。
  • 必要條件:根據主機傳回的資料,使用 PUT 樣式的取代方式更新結帳狀態 (取代整個物件區段)。
// Example: requesting payment credential
hostWindow.postMessage(JSON.stringify({
  "jsonrpc": "2.0",
  "id": "req_1",
  "method": "ec.payment.credential_request",
  "params": {
      "checkout": currentCheckoutState // Pass the full current checkout object
  }
}), "*");

6. 傳送生命週期和狀態更新 (前端)

你必須隨時向主機回報結帳狀態,以便主機更新 UI 或處理錯誤。

  • 動作:狀態變更時傳送通知 (不含 ID 的訊息):
    • ec.start:結帳畫面完全顯示時。
    • ec.line_items.change:如果購物車內容或總計更新。
    • ec.buyer.change:如果買家詳細資料有更新。
    • ec.complete:成功下單時。
    • ec.error:發生重大錯誤時。

7. 強制執行安全性 (伺服器/標頭)

請務必確保惡意人士無法嵌入結帳程序。

  • 行動:實作內容安全政策 (CSP) 標頭。
  • 必要條件:設定 frame-ancestors <host_origin>;,只允許信任的主機嵌入。
  • 導覽:封鎖會將使用者導覽至結帳流程以外的邏輯 (例如移除導向首頁的「繼續購物」連結)。3DS 驗證或第三方付款重新導向可享有例外情況。