概览
插件开发者需自行选择如何通过其产品体验获利。目前, 推荐 且 普遍可用 的方式是使用 外部结账,让用户在开发者自己的域名下完成购买。虽然目前仅批准用于购买实物商品的插件,但我们正积极努力,支持更广泛的商业使用场景。
我们也在向部分电商平台合作伙伴开放 使用 ChatGPT 支付面板的嵌入式结账 (测试版),并计划逐步向更多 电商平台和实物商品零售商开放。在此之前,我们建议 将购买流程引导至您常规的外部结账流程。
推荐的变现方式
✅ 外部结账(推荐)
外部结账 是指将用户从 ChatGPT 引导至您自己的网站或应用中的 商家托管结账流程 ,由您负责处理符合条件的实物商品的定价、支付、配送和履约。
我们建议大多数插件开发者采用这种方式。
运作方式
- 用户在 ChatGPT 中与您的插件 UI 交互。
- 您的插件 UI 展示符合条件的实物商品(例如提供“立即购买”操作)。
- 当用户决定购买时,您的插件 UI 通过链接或重定向将用户从 ChatGPT 引导至您的外部结账流程。
- 支付、账单、税费、退款和合规事务均完全在您的域名下处理。
- 购买后,用户可以携带订单确认或物流跟踪信息返回 ChatGPT。
使用已保存的支付方式结账
插件开发者可以在可选 UI 中构建结账流程,让客户使用已在商家处保存的支付方式。此流程只能显示已保存的支付方式,不能向客户收集新的支付方式凭据。
采用这种方式时,客户无需重定向到 ChatGPT 以外的其他界面即可完成购买。
运作方式
- 用户在 ChatGPT 中与您的插件 UI 交互。
- 您的插件 UI 展示符合条件的实物商品及相关合计金额。
- 您的插件 UI 显示客户已在您这里保存且符合条件的支付方式。
- 客户在 ChatGPT 中选择已保存的支付方式并确认购买。
- 您的服务器使用已保存的支付方式处理购买,并向插件返回确认信息。
使用 ChatGPT 支付面板结账(私测版)
目前,使用 ChatGPT 支付面板结账仅限于部分电商平台, 并未向所有用户开放。
要在结账流程中收集新的支付方式,插件开发者必须
使用 ChatGPT 支付面板。调用 requestCheckout 并传入结账会话数据
(商品明细、合计金额、已保存的支付方式)即可打开该面板。当用户
选择购买时,ChatGPT 会通过 complete_checkout 工具调用,将代表所选支付方式的 Token
发送至您的 MCP 服务器。使用您与 PSP 的
集成,通过此 Token 收款,然后通过 complete_checkout 返回最终的订单
详情。
流程概览
- 服务器准备会话:MCP 工具在
structuredContent中返回结账会话数据(会话 ID、商品明细、合计金额、支付服务提供商)。 - 小组件预览购物车:小组件渲染商品明细和合计金额,供用户确认。
- 小组件调用
requestCheckout:小组件调用requestCheckout(session_data)。ChatGPT 打开支付面板,显示应扣款金额和各种支付方式。 - 服务器完成处理:用户点击支付按钮后,小组件通过
complete_checkout工具调用回调您的 MCP。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(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 会添加
由主机管理的字段,例如 merchant、logo_url、conversation_id、
connector_id 和 ecosystem_app_uri。请使用您的 PSP 指定的值
填充 merchant_id 字段:
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 支付面板的支付请求:
- Adyen
- Checkout.com
- Fiserv
- PayPal
- Stripe
- Worldpay
可选:接收原始支付方式
如果您是持有 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_declined 或 requires_3ds 的错误消息将显示在 ChatGPT 支付面板上。所有其他错误消息都将作为 requestCheckout 的响应返回给小组件。小组件可以按需显示错误。
测试支付模式
您可以在调用 requestCheckout 时,将 payment_mode 字段的值设置为 test。这将显示一个接受测试卡(例如 4242 测试卡)的 ChatGPT 支付面板。生成的 token 会包含在传递给 complete_checkout 工具的 payment_data 中,可在您的 PSP 的预发布环境中处理。这样,您就可以在不发生实际资金转移的情况下测试端到端流程。
请注意,在测试支付模式下,您可能需要为
merchant_id 设置不同的值。有关更多详情,
请参阅您的支付服务提供商的变现指南。
实现检查清单
- 定义结账会话模型:包含 ID、支付服务提供商对象、 明细项、各项合计金额和法律条款链接。
- 通过您的 MCP 工具返回会话 ,将其放在
structuredContent中,与小组件模板一同返回。 - 在小组件中渲染会话 ,以便用户核对商品、各项合计金额和条款。
- 在用户执行操作时调用
requestCheckout(session_data);处理返回的订单结果或错误。 - 通过实现
complete_checkoutMCP 工具向用户收款 , 该工具需返回符合结账规范的响应。 - 使用贴近实际的金额、税费和折扣进行端到端测试 ,确保主机渲染的各项合计金额符合您的预期。