埋め込み型購入手続き

埋め込み型購入手続きの統合により、ウェブベースの購入手続きを Google サービスに埋め込むことができます。ネイティブ API ではサポートできない複雑なロジック(カスタマイズなど)がプロダクトに必要な場合は、このパスを使用します。iframe を介して購入手続きフローに埋め込まれる購入手続き UI を実装します。

埋め込み型購入手続きとは

埋め込み型購入手続き(EC)を使用すると、ホスト(Google 検索や AI エージェントなど)は、既存のウェブベースの購入手続きをアプリケーション内に表示できます(iframe またはウェブビューを使用)。標準のウェブ リダイレクトとは異なり、双方向通信が可能になります。ホストは、保存された住所の選択や保存された認証情報による支払いなどの特定のタスクを「委任」して、より高速でネイティブな感覚の操作を提供できます。この場合、販売者は引き続き記録上の販売者となり、実際の注文作成を処理します。

販売者の実装チェックリスト

埋め込み購入手続きをサポートするには、UCP API とフロントエンドの購入手続きアプリケーション全体で次の要件を実装する必要があります。

1. 検出を有効にする(UCP API)

UCP API レスポンスで、チェックアウトが埋め込み拡張機能をサポートしていることを宣言する必要があります。

  • アクション: dev.ucp.shopping.embedded_checkout 機能オブジェクトを UCP レスポンス機能配列に追加します。
  • 要件: 仕様とスキーマの URL を含めます。
  • 省略可: チェックアウトを読み込むために認証(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. ハンドル URL の初期化(フロントエンド)

ホストが continue_url を読み込むと、特定のクエリ パラメータが付加されます。フロントエンドは、読み込み時にこれらを直ちに解析する必要があります。

  • アクション: 次の URL クエリ パラメータを解析します。
    • ec_version: プロトコル バージョン(例: 2026-01-11)。
    • ec_auth: (該当する場合)auth.required: true を設定した場合は、ホストから提供された認証トークンを検証します。
    • ec_delegate: ホストがネイティブに処理するアクションのカンマ区切りリスト(例: payment.credentialfulfillment.address_changepayment.instruments_change など)。

3. 通信を確立する(フロントエンド)

通信は、JSON-RPC 2.0 形式を使用して postMessage を使用して行われます。

  • アクション: message イベントのリスナーを実装します。
  • 要件: すべてのメッセージの送信元を検証して、ホストと一致することを確認する必要があります。
  • ネイティブ サポート: ネイティブ アプリホストの場合、挿入されたグローバル(postMessage が利用できない場合は window.EmbeddedCheckoutProtocolConsumer)。

4. ハンドシェイクを実行する(フロントエンド)

チェックアウトがレンダリングされたらすぐに、ホストに準備ができたことを伝え、受け入れる委任を確認する必要があります。

  • アクション: 読み込み後すぐに ec.ready リクエストを送信します。
  • ペイロード: ホストに処理させることに同意した機能をリストする delegate 配列を含めます。
  • : リクエストされた URL が 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 認証またはサードパーティの支払いリダイレクトは例外として認められます。