For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション
Theme
概要 ChatGPT と Codex のユーザー向けドキュメント ユースケース

チェックアウト API リファレンス

プラグインに任意で追加できる UI からチェックアウトを開始する方法を説明します。

概要

プラグインの収益化方法は開発者が決めます。現在、推奨され、一般提供されているのは、ユーザーが開発者自身のドメインで購入を完了する外部チェックアウトです。承認の対象は現在、物品を購入するためのプラグインに限られますが、より幅広い取引に対応できるよう取り組んでいます。

一部のマーケットプレイスパートナーには、ChatGPT の決済シートを使った組み込み型チェックアウトもベータ版として提供しています。今後は対象となるマーケットプレイスや物品を扱う小売業者を順次拡大する予定です。それまでは、購入時に自社の通常の外部チェックアウトへユーザーを案内することを推奨します。

推奨する収益化方法

✅ 外部チェックアウト(推奨)

外部チェックアウトでは、ChatGPT から加盟店が自社のウェブサイトやアプリケーションでホストするチェックアウトフローへユーザーを案内します。対象となる物品の価格設定、決済、配送、注文の履行は加盟店が担当します。

ほとんどのプラグイン開発者には、この方法を推奨します。

購入の流れ

  1. ユーザーが ChatGPT でプラグインの UI を操作します。
  2. プラグインの UI に購入対象の物品を表示します。たとえば、商品と一緒に「今すぐ購入」ボタンを表示します。
  3. ユーザーが購入を決めたら、プラグインの UI からリンクまたはリダイレクトで、ChatGPT の外にある自社のチェックアウトフローへ案内します。
  4. 決済、請求、税金、返金、法令遵守への対応はすべて自社のドメインで行います。
  5. 購入後、ユーザーは注文確認情報や配送追跡情報を受け取って ChatGPT に戻れます。

保存済みの支払い方法を使ったチェックアウト

プラグイン開発者は、任意で追加できる UI に、顧客が加盟店に保存済みの支払い方法を使えるチェックアウトフローを実装できます。このフローで表示できるのは保存済みの支払い方法のみです。顧客から新しい支払い方法の認証情報を取得することはできません。

この方法では、顧客は ChatGPT の外にある別の画面へ移動せずに購入を完了できます。

購入の流れ

  1. ユーザーが ChatGPT でプラグインの UI を操作します。
  2. プラグインの UI に購入対象の物品とその合計金額を表示します。
  3. 顧客が自社に保存済みの支払い方法のうち、今回の購入に利用できるものをプラグインの UI に表示します。
  4. 顧客が保存済みの支払い方法を選び、ChatGPT で購入を確定します。
  5. 自社のサーバーが保存済みの支払い方法で購入を処理し、購入の確認情報をプラグインに返します。

ChatGPT の決済シートを使ったチェックアウト(プライベートベータ)

ChatGPT の決済シートを使ったチェックアウトは、現在、一部のマーケットプレイスに限って提供しており、利用できるユーザーも限られています。

プラグイン開発者がチェックアウトフロー内で新しい支払い方法を取得するには、ChatGPT の決済シートを使う必要があります。requestCheckout にチェックアウトセッションのデータ(注文明細、合計金額、保存済みの支払い方法)を渡してシートを開きます。ユーザーが購入を選ぶと、ChatGPT は選択された支払い方法を表すトークンを、complete_checkout ツールの呼び出しを通じて自社の MCP サーバーに送信します。連携先の決済サービスプロバイダー(PSP)でこのトークンを使って決済し、complete_checkout から確定した注文の詳細を返します。

処理の流れ

  1. サーバーでセッションを準備:MCP ツールがチェックアウトセッションのデータ(セッション ID、注文明細、合計金額、決済プロバイダー)を structuredContent に含めて返します。
  2. ウィジェットでカートの内容を表示:ユーザーが確認できるよう、ウィジェットに注文明細と合計金額を表示します。
  3. ウィジェットから requestCheckout を呼び出す:ウィジェットが requestCheckout(session_data) を呼び出します。ChatGPT が決済シートを開き、請求額と利用可能な支払い方法を表示します。
  4. サーバーで注文を確定:ユーザーが支払いボタンをクリックすると、ウィジェットが自社の MCP サーバーの complete_checkout ツールを呼び出します。MCP ツールが確定済みの注文を返すと、その注文が requestCheckout の応答としてウィジェットに返されます。

チェックアウトセッション

ホストが表示するチェックアウトセッションのペイロードは、開発者が構築します。id や payment_provider などのフィールドに設定する値は、利用する決済サービスプロバイダーや販売システムによって異なります。MCP ツールからは次の情報を返してください。

  • ユーザーが購入する商品の明細と数量
  • サーバー側の計算結果と一致する金額の内訳(小計、税額、割引額、手数料、合計)
  • PSP との連携に必要なプロバイダーのメタデータ
  • 利用規約や返金ポリシーなど、法的事項やポリシーへのリンク

ウィジェットからの requestCheckout の呼び出し

ホストは window.openai.requestCheckout を提供します。ユーザーが購入手続きを開始したら、このメソッドで ChatGPT の決済シートを開きます。

例:

async function handleCheckout(sessionJson: string) {
  const session = JSON.parse(sessionJson);

  if (!window.openai?.requestCheckout) {
    throw new Error("requestCheckout is not available in this host");
  }

  // Host opens the ChatGPT payment sheet.
  const order = await window.openai.requestCheckout({
    ...session,
    id: String(session.id), // Use a unique ID for every checkout session.
  });

  return order; // Host returns the order payload.
}

コンポーネントでは、たとえばボタンのクリック時にこの処理を開始できます。

import { useState } from "react";

function CheckoutButton({
  checkoutSessionJson,
}: {
  checkoutSessionJson: string;
}) {
  const [isLoading, setIsLoading] = useState(false);
  const [order, setOrder] = useState<Record<string, unknown> | null>(null);
  const checkoutButton = (
    <button
      onClick={async () => {
        setIsLoading(true);
        try {
          const orderResponse = await handleCheckout(checkoutSessionJson);
          setOrder(orderResponse);
        } catch (error) {
          console.error(error);
        } finally {
          setIsLoading(false);
        }
      }}
    >
      {isLoading ? "Loading..." : "Checkout"}
    </button>
  );
  return (
    <>
      {checkoutButton}
      <pre>{JSON.stringify(order, null, 2)}</pre>
    </>
  );
}

以下は、ウィジェットからホストに渡せるチェックアウトセッションの完全な例です。例に示すチェックアウトセッションのフィールドはプラグイン側で設定します。merchant、logo_url、conversation_id、connector_id、ecosystem_app_uri など、ホスト側で管理するフィールドは ChatGPT が追加します。merchant_id フィールドには PSP が指定する値を設定してください。

const checkoutRequest = {
  id: "checkout_session_123",
  payment_provider: {
    provider: "stripe",
    merchant_id: "merchant_123",
    supported_payment_methods: [
      {
        type: "card",
        allowed_card_brands: ["visa", "mastercard"],
      },
      { type: "apple_pay" },
      { type: "google_pay" },
    ],
    managed_payment_methods: [
      {
        type: "card",
        id: "pm_123",
        display_name: "Visa ending in 4242",
        display_last4: "4242",
        display_brand: "visa",
      },
    ],
  },
  payment_mode: "live",
  status: "ready_for_payment",
  currency: "USD",
  metadata: {
    cart_id: "cart_123",
    merchant_order_reference: "order_ref_123",
  },
  line_items: [
    {
      id: "line_item_123",
      item: {
        id: "item_123",
        quantity: 1,
      },
      name: "Canvas backpack",
      description: "A weather-resistant everyday backpack.",
      images: ["https://merchant.example.com/images/canvas-backpack.png"],
      base_amount: 3000,
      discount: 0,
      subtotal: 3000,
      tax: 300,
      total: 3300,
    },
  ],
  totals: [
    {
      type: "items_base_amount",
      display_text: "Items subtotal",
      amount: 3000,
    },
    {
      type: "subtotal",
      display_text: "Subtotal",
      amount: 3000,
    },
    {
      type: "fulfillment",
      display_text: "Shipping",
      amount: 550,
    },
    {
      type: "tax",
      display_text: "Tax",
      amount: 300,
    },
    {
      type: "total",
      display_text: "Total",
      amount: 3850,
    },
  ],
  fulfillment_options: [
    {
      id: "standard_shipping",
      type: "shipping",
      title: "Standard shipping",
      subtitle: "Arrives in 3-5 business days",
      carrier: "USPS",
      earliest_delivery_time: "2027-01-15T15:00:00Z",
      latest_delivery_time: "2027-01-19T18:00:00Z",
      subtotal: 500,
      tax: 50,
      total: 550,
    },
  ],
  fulfillment_option_id: "standard_shipping",
  fulfillment_address: {
    name: "Jane Customer",
    line_one: "123 Main St",
    line_two: "Apt 4B",
    city: "San Francisco",
    state: "CA",
    country: "US",
    postal_code: "94107",
    phone_number: "+14155550123",
  },
  messages: [
    {
      type: "info",
      param: "fulfillment_address",
      content_type: "plain",
      content: "Free returns within 30 days.",
    },
  ],
  links: [
    { type: "terms_of_use", url: "https://merchant.example.com/terms" },
    { type: "privacy_policy", url: "https://merchant.example.com/privacy" },
    { type: "support_url", url: "https://merchant.example.com/support" },
  ],
};

const response = await window.openai.requestCheckout(checkoutRequest);

実装上のポイント:

  • window.openai.requestCheckout(session) はホストのチェックアウト UI を開きます。
  • 成功すると Promise は注文結果で解決し、エラーまたはキャンセル時には拒否されます。
  • ユーザーが支払い内容を確認できるよう、セッションの JSON をもとに画面を表示してください。
  • すべての金額フィールドには、通貨の最小単位で表した整数を使ってください。
  • payment_provider.managed_payment_methods には、顧客が自社に保存済みの支払い方法を設定してください。
  • metadata の値は文字列にしてください。
  • provider には連携先の PSP が指定するスラッグを使い、merchant_id の値は PSP に確認してください。

MCP サーバーでの complete_checkout ツールの公開

次の例をもとに、処理を自社のロジックに置き換えられます。

この Python の例を実行するには、fastmcp と pydantic をインストールしてください。ツールの output_schema で MCP の outputSchema を宣言します。ToolResult.structured_content の値は structuredContent として、meta の値は _meta として返されます。ローカルのテスト用フィクスチャは example-session と example-payment-token を受け取り、支払い方法への請求や注文の作成を行わずにサンプルの応答を返します。

from typing import Any, Literal

from fastmcp import FastMCP
from fastmcp.tools.tool import ToolResult
from pydantic import BaseModel

server = FastMCP("Checkout response fixture")
META_SESSION_ID = "openai/checkoutSessionId"


class Buyer(BaseModel):
    email: str


class PaymentData(BaseModel):
    # Deliberately accepts only a local fixture token, never real payment credentials.
    token: Literal["example-payment-token"]


class CompleteCheckoutOutput(BaseModel):
    id: str
    status: str
    currency: str
    line_items: list[dict[str, Any]]
    fulfillment_address: dict[str, Any]
    fulfillment_options: list[dict[str, Any]]
    fulfillment_option_id: str
    totals: list[dict[str, Any]]
    order: dict[str, Any]


@server.tool(
    description="Return the local checkout response fixture; does not charge a payment method or create a real order.",
    output_schema=CompleteCheckoutOutput.model_json_schema(),
)
async def complete_checkout(
    checkout_session_id: str,
    buyer: Buyer,
    payment_data: PaymentData,
) -> ToolResult:
    if checkout_session_id != "example-session":
        raise ValueError("This response fixture only accepts example-session")
    return ToolResult(
        content=[],
        structured_content={
            "id": checkout_session_id,
            "status": "completed",
            "currency": "USD",
            "line_items": [
                {
                    "id": "line_item_1",
                    "item": {
                        "id": "item_1",
                        "quantity": 1,
                    },
                    "base_amount": 3000,
                    "discount": 0,
                    "subtotal": 3000,
                    "tax": 300,
                    "total": 3300,
                },
            ],
            "fulfillment_address": {
                "name": "Jane Customer",
                "line_one": "123 Main St",
                "line_two": "Apt 4B",
                "city": "San Francisco",
                "state": "CA",
                "country": "US",
                "postal_code": "94107",
                "phone_number": "+1 (555) 555-5555",
            },
            "fulfillment_options": [
                {
                    "id": "fulfillment_option_1",
                    "type": "shipping",
                    "title": "Standard shipping",
                    "subtitle": "3-5 business days",
                    "carrier": "USPS",
                    "earliest_delivery_time": "2026-02-24T15:00:00Z",
                    "latest_delivery_time": "2026-02-28T18:00:00Z",
                    "subtotal": 0,
                    "tax": 0,
                    "total": 0,
                },
            ],
            "fulfillment_option_id": "fulfillment_option_1",
            "totals": [
                {
                    "type": "items_base_amount",
                    "display_text": "Items subtotal",
                    "amount": 3000,
                },
                {
                    "type": "subtotal",
                    "display_text": "Subtotal",
                    "amount": 3000,
                },
                {
                    "type": "tax",
                    "display_text": "Tax",
                    "amount": 300,
                },
                {
                    "type": "total",
                    "display_text": "Total",
                    "amount": 3300,
                },
            ],
            "order": {
                "id": "order_id_123",
                "checkout_session_id": checkout_session_id,
                "permalink_url": "",
            },
        },
        meta={META_SESSION_ID: "checkout-flow"},
        is_error=False,
    )

この例を調整して、次の処理を実装してください。

  • 決済サービスプロバイダーと連携し、payment_data に含まれる支払い方法で代金を請求します。
  • 注文を自社のシステムに保存します。
  • 自社のシステムで確定した注文・領収書データを返します。
  • 注文確認ウィジェットを表示する場合は _meta.ui.resourceUri を含めます(ChatGPT では、互換性を保つための別名として _meta["openai/outputTemplate"] も使用できます)。

以下の決済サービスプロバイダーは、ChatGPT の決済シートを使った決済処理に対応しています。

支払い方法の生データの受信(任意)

PCI DSS レベル 1 の認証を取得している加盟店は、Agentic Commerce Protocol の Delegate Payment エンドポイントを実装することで、支払い方法の生データを直接受け取れます。委任された決済リクエストには、実際のカード番号、有効期限、CVC、請求先住所、支払いを許可する条件、リスクシグナル、メタデータなど、自社の決済フローで必要となる支払い方法の詳細がすべて含まれます。

以下は、カードの生データを含む決済リクエストの例です。

{
  "payment_method": {
    "type": "card",
    "card_number_type": "fpan",
    "number": "4242424242424242",
    "exp_month": "11",
    "exp_year": "2026",
    "name": "Jane Doe",
    "cvc": "223",
    "checks_performed": ["avs", "cvv"],
    "iin": "424242",
    "display_card_funding_type": "credit",
    "display_brand": "visa",
    "display_last4": "4242",
    "metadata": {}
  },
  "allowance": {
    "reason": "one_time",
    "max_amount": 5000,
    "currency": "usd",
    "checkout_session_id": "cs_01HV3P3ABC123",
    "merchant_id": "acme_corp",
    "expires_at": "2026-02-13T12:00:00Z"
  },
  "billing_address": {
    "name": "Jane Doe",
    "line_one": "185 Berry Street",
    "line_two": "Suite 550",
    "city": "San Francisco",
    "state": "CA",
    "country": "US",
    "postal_code": "94107"
  },
  "risk_signals": [
    {
      "type": "card_testing",
      "score": 5,
      "action": "authorized"
    }
  ],
  "metadata": {
    "session_id": "sess_abc123",
    "user_agent": "ChatGPT/2.0"
  }
}

このリクエストへの応答では、支払い方法を識別する ID を返してください。この ID は complete_checkout に payment_data の一部として渡されます。

{
  "id": "vt_01J8Z3WXYZ9ABC123",
  "created": "2026-02-12T14:30:00Z",
  "metadata": {
    "source": "agent_checkout",
    "merchant_id": "acme_corp",
    "idempotency_key": "idem_xyz789"
  }
}

エラー処理

complete_checkout ツールの呼び出しでは、error 型のメッセージを返せます。エラーメッセージの code が payment_declined または requires_3ds の場合、そのメッセージは ChatGPT の決済シートに表示されます。それ以外のエラーメッセージは、requestCheckout の応答としてウィジェットに返されます。ウィジェット側では必要に応じてエラーを表示できます。

テスト決済モード

payment_mode フィールドを test に設定して requestCheckout を呼び出すと、テストカード(例:4242 のテストカード)を受け付ける ChatGPT の決済シートが表示されます。このとき生成される token は payment_data に含まれて complete_checkout ツールに渡され、PSP のステージング環境で処理できます。これにより、実際に資金を移動せずに一連の購入フローをテストできます。

テスト決済モードでは、merchant_id に本番とは異なる値を設定する必要がある場合があります。詳しくは、ご利用の決済プロバイダーの収益化ガイドを参照してください。

実装チェックリスト

  1. チェックアウトセッションのモデルを定義します。ID、決済プロバイダーオブジェクト、注文明細、合計金額、規約などへのリンクを含めます。
  2. MCP ツールからセッションを返します。セッションは structuredContent に含め、ウィジェットのテンプレートとともに返します。
  3. ウィジェットにセッションの内容を表示します。ユーザーが商品、合計金額、規約を確認できるようにします。
  4. requestCheckout(session_data) を呼び出します。ユーザーの操作をきっかけに呼び出し、返された注文またはエラーを処理します。
  5. ユーザーに代金を請求します。complete_checkout MCP ツールを実装し、チェックアウト仕様に沿った応答を返します。
  6. エンドツーエンドでテストします。実際の取引に即した金額、税額、割引額を使い、ホストに想定どおりの合計金額が表示されることを確認します。