For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主要導覽

結帳 API 參考文件

透過選用的外掛程式 UI 實作結帳功能。

概覽

外掛程式開發人員須自行選擇如何透過所提供的體驗營利。目前, 建議已全面開放 的方式是使用 外部結帳,讓使用者在開發人員自己的網域上完成購買。雖然目前僅核准用於購買實體商品的外掛程式,但我們正積極努力支援更多元的商務使用案例。

我們也正為部分市集合作夥伴開放 使用 ChatGPT 付款面板的嵌入式結帳功能 (Beta 版),並計劃逐步向更多 市集與實體商品零售商開放。在此之前,我們建議 將購買流程導向你原有的外部結帳流程。

外部結帳 是指將使用者從 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 付款面板結帳(私人 Beta 版)

使用 ChatGPT 付款面板結帳的功能目前僅限部分市集使用, 尚未向所有使用者開放。

若要在結帳流程中收集新的付款方式,外掛程式開發人員必須 使用 ChatGPT 付款面板。呼叫 requestCheckout 並傳入結帳工作階段資料 (明細項目、合計金額、已儲存的付款方式),即可開啟面板。當使用者 選擇購買時,ChatGPT 會透過 complete_checkout 工具呼叫,將代表所選付款方式的 Token 傳送至你的 MCP 伺服器。使用你的 PSP 整合功能 透過此 Token 收款,再由 complete_checkout 傳回 最終訂單詳情。

流程概覽

  1. 伺服器準備工作階段:MCP 工具在 structuredContent 中傳回結帳工作階段資料(工作階段 ID、明細項目、合計金額、付款服務供應商)。
  2. 小工具預覽購物車:小工具呈現明細項目與合計金額,供使用者確認。
  3. 小工具呼叫 requestCheckout:小工具呼叫 requestCheckout(session_data)。ChatGPT 會開啟付款面板,顯示應付金額與各種付款方式。
  4. 伺服器完成處理:使用者按下付款按鈕後,小工具會透過 complete_checkout 工具呼叫回呼你的 MCP。MCP 工具會傳回已完成的訂單,並將其作為 requestCheckout 的回應傳回小工具。

結帳工作階段

你須負責建構供主機呈現的結帳工作階段酬載。某些欄位(例如 idpayment_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(checkout_session_id), // Use a unique ID for every checkout session.
  });

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

你可以在元件中,於按鈕點擊時觸發此操作:

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

以下是完整的結帳工作階段範例,小工具可將其傳給 主機。你的外掛程式提供下列結帳工作階段欄位。ChatGPT 會加入 由主機管理的欄位,例如 merchantlogo_urlconversation_idconnector_idecosystem_app_uri。請在 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 Slug,並向你的 PSP 洽詢其 merchant_id 值。

MCP 伺服器:提供 complete_checkout 工具

你可以依循此模式,並換成自己的邏輯:

直接傳回 CallToolResult 時,Python MCP SDK 會使用下方的 Annotated 回傳型別,為 structuredContent 宣告工具的 outputSchema

from typing import Annotated, Any

from pydantic import BaseModel


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]


@tool(description="")
async def complete_checkout(
    self,
    checkout_session_id: str,
    buyer: Buyer,
    payment_data: PaymentData,
) -> Annotated[types.CallToolResult, CompleteCheckoutOutput]:
    return types.CallToolResult(
        content=[],
        structuredContent={
            "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"},
        isError=False,
    )

請調整此範例以:

  • 整合你的付款服務供應商,以便透過 payment_data 中的付款方式收款。
  • 將訂單持久儲存於你的系統中。
  • 傳回可作為準據的訂單/收據資料。
  • 若要呈現確認小工具,請加入 _meta.ui.resourceUri(ChatGPT 也接受 _meta["openai/outputTemplate"] 作為選用的相容性別名)。

下列付款服務供應商支援處理 ChatGPT 付款面板的付款:

選用:接收原始付款方式資料

如果您是持有 PCI DSS Level 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 會作為 payment_data 的一部分傳遞給 complete_checkout

{
  "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_declinedrequires_3ds,該訊息就會顯示在 ChatGPT 付款面板上。所有其他錯誤訊息都會作為 requestCheckout 的回應傳回小工具。小工具可依需求顯示錯誤。

測試付款模式

您可以在呼叫 requestCheckout 時,將 payment_mode 欄位的值設為 test。這會顯示接受測試卡片(例如 4242 測試卡)的 ChatGPT 付款面板。產生的 token 會包含在傳遞給 complete_checkout 工具的 payment_data 中,可由您的 PSP 預備環境處理。如此一來,您就能測試端對端流程,而不必動用實際資金。

請注意,在測試付款模式下,您可能需要為 merchant_id 設定不同的值。如需更多詳細資訊, 請參閱付款服務供應商的營利指南。

實作檢查清單

  1. 定義結帳工作階段模型:納入 ID、付款服務供應商物件、 明細項目、總額及法律資訊連結。
  2. 透過 MCP 工具傳回工作階段 ,將其放在 structuredContent 中,與小工具範本一併傳回。
  3. 在小工具中呈現工作階段 ,讓使用者能檢視項目、總額及條款。
  4. 在使用者操作時呼叫 requestCheckout(session_data) ,並處理傳回的訂單或錯誤。
  5. 實作 complete_checkout MCP 工具來向使用者收款 , 並讓工具傳回符合結帳規格的回應。
  6. 使用符合實際情況的金額、稅額及折扣進行端對端測試 ,確保主機呈現的總額符合預期。