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

Checkout-API-Referenz

Implementiere den Checkout über eine optionale Plug-in-Oberfläche.

Übersicht

Wer Plug-ins entwickelt, entscheidet selbst, wie das eigene Angebot monetarisiert wird. Derzeit ist ein externer Checkout der empfohlene und allgemein verfügbare Ansatz. Dabei schließen Nutzende ihre Käufe auf der eigenen Domain der Plug-in-Entwickelnden ab. Aktuell werden nur Plug-ins für den Kauf physischer Waren zugelassen. Wir arbeiten jedoch aktiv daran, weitere Anwendungsfälle im Handel zu unterstützen.

Außerdem ermöglichen wir ausgewählten Marketplace-Partnern einen eingebetteten Checkout mit dem ChatGPT-Zahlungsdialog (Beta). Wir planen, den Zugang nach und nach auf weitere Marktplätze und Handelsunternehmen für physische Waren auszuweiten. Bis dahin empfehlen wir, Kaufvorgänge zu deinem regulären externen Checkout weiterzuleiten.

Bei einem externen Checkout leitest du Nutzende von ChatGPT zu einem vom Handelsunternehmen gehosteten Checkout auf deiner eigenen Website oder in deiner Anwendung weiter. Dort kümmerst du dich um Preisgestaltung, Zahlungen, Versand und Auftragsabwicklung für zulässige physische Waren.

Diesen Ansatz empfehlen wir den meisten Plug-in-Entwickelnden.

So funktioniert es

  1. Eine Person interagiert mit deiner Plug-in-Oberfläche in ChatGPT.
  2. Deine Plug-in-Oberfläche zeigt zulässige physische Waren an, beispielsweise mit einer Aktion „Jetzt kaufen“.
  3. Wenn sich die Person zum Kauf entscheidet, führt deine Plug-in-Oberfläche sie über einen Link oder eine Weiterleitung aus ChatGPT zu deinem externen Checkout.
  4. Zahlungen, Abrechnung, Steuern, Rückerstattungen und Compliance werden vollständig auf deiner Domain abgewickelt.
  5. Nach dem Kauf kann die Person mit der Bestellbestätigung oder den Angaben zur Sendungsverfolgung zu ChatGPT zurückkehren.

Checkout mit gespeicherten Zahlungsmethoden

Plug-in-Entwickelnde können in einer optionalen Oberfläche einen Checkout erstellen, bei dem die Kundschaft bereits beim Handelsunternehmen gespeicherte Zahlungsmethoden verwendet. Dieser Ablauf kann nur gespeicherte Zahlungsmethoden anzeigen und keine neuen Zahlungsdaten von der Kundschaft erfassen.

Bei diesem Ansatz muss die kaufende Person nicht auf eine andere Oberfläche außerhalb von ChatGPT weitergeleitet werden, um den Kauf abzuschließen.

So funktioniert es

  1. Eine Person interagiert mit deiner Plug-in-Oberfläche in ChatGPT.
  2. Deine Plug-in-Oberfläche zeigt zulässige physische Waren mit den zugehörigen Summen an.
  3. Deine Plug-in-Oberfläche zeigt verfügbare Zahlungsmethoden an, die die kaufende Person bereits bei dir gespeichert hat.
  4. Die kaufende Person wählt eine gespeicherte Zahlungsmethode aus und bestätigt den Kauf in ChatGPT.
  5. Dein Server wickelt den Kauf mit der gespeicherten Zahlungsmethode ab und gibt eine Bestätigung an das Plug-in zurück.

Checkout mit dem ChatGPT-Zahlungsdialog (private Beta)

Der Checkout mit dem ChatGPT-Zahlungsdialog ist derzeit auf ausgewählte Marktplätze beschränkt und steht nicht allen Nutzenden zur Verfügung.

Um im Checkout neue Zahlungsmethoden zu erfassen, müssen Plug-in-Entwickelnde den ChatGPT-Zahlungsdialog verwenden. Rufe requestCheckout mit den Daten der Checkout-Sitzung (Bestellpositionen, Summen, gespeicherte Zahlungsmethoden) auf, um den Dialog zu öffnen. Wenn die kaufende Person „Kaufen“ auswählt, sendet ChatGPT über den Tool-Aufruf complete_checkout einen Token für die gewählte Zahlungsmethode an deinen MCP-Server. Verwende deine PSP-Integration, um die Zahlung mit diesem Token einzuziehen. Gib anschließend die endgültigen Bestelldetails über complete_checkout zurück.

Ablauf im Überblick

  1. Der Server bereitet die Sitzung vor: Ein MCP-Tool gibt die Daten der Checkout-Sitzung (Sitzungs-ID, Bestellpositionen, Summen, Zahlungsdienstleister) in structuredContent zurück.
  2. Das Widget zeigt eine Vorschau des Warenkorbs: Das Widget zeigt Bestellpositionen und Summen an, damit die kaufende Person sie bestätigen kann.
  3. Das Widget ruft requestCheckout auf: Das Widget führt requestCheckout(session_data) aus. ChatGPT öffnet den Zahlungsdialog und zeigt den zu zahlenden Betrag sowie verschiedene Zahlungsmethoden an.
  4. Der Server schließt den Vorgang ab: Sobald die kaufende Person auf die Schaltfläche zum Bezahlen klickt, ruft das Widget über den Tool-Aufruf complete_checkout deinen MCP-Server auf. Das MCP-Tool gibt die abgeschlossene Bestellung zurück, die das Widget als Antwort auf requestCheckout erhält.

Checkout-Sitzung

Du bist dafür verantwortlich, die Nutzdaten der Checkout-Sitzung zusammenzustellen, die der Host darstellt. Die genauen Werte bestimmter Felder wie id und payment_provider hängen von deinem Zahlungsdienstleister und deinem Handelssystem ab. In der Praxis sollte dein MCP-Tool Folgendes zurückgeben:

  • Bestellpositionen und Mengen, die die Person kauft.
  • Summen (Zwischensumme, Steuern, Rabatte, Gebühren, Gesamtsumme), die mit den Berechnungen deines Servers übereinstimmen.
  • Metadaten des Zahlungsdienstleisters, die deine PSP-Integration benötigt.
  • Links zu rechtlichen Informationen und Richtlinien (Geschäftsbedingungen, Rückerstattungsrichtlinie usw.).

Widget: requestCheckout aufrufen

Der Host stellt window.openai.requestCheckout bereit. Öffne damit den ChatGPT-Zahlungsdialog, wenn eine Person einen Kauf beginnt:

Beispiel:

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

In deiner Komponente kannst du dies beispielsweise durch einen Klick auf eine Schaltfläche auslösen:

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

Hier siehst du ein vollständiges Beispiel für eine Checkout-Sitzung, das dein Widget an den Host übergeben kann. Dein Plug-in liefert die unten aufgeführten Felder der Checkout-Sitzung. ChatGPT ergänzt vom Host verwaltete Felder wie merchant, logo_url, conversation_id, connector_id und ecosystem_app_uri. Trage in das Feld merchant_id den von deinem PSP vorgegebenen Wert ein:

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

Wichtige Punkte:

  • window.openai.requestCheckout(session) öffnet die Checkout-Oberfläche des Hosts.
  • Das Promise wird mit dem Bestellergebnis erfüllt oder bei einem Fehler bzw. Abbruch abgelehnt.
  • Stelle die Sitzungsdaten aus dem JSON dar, damit Nutzende prüfen können, wofür sie bezahlen.
  • Gib alle Beträge als Ganzzahlen in der kleinsten Währungseinheit an.
  • Verwende payment_provider.managed_payment_methods für Zahlungsmethoden, die die kaufende Person bereits bei deinem Handelsunternehmen gespeichert hat.
  • Belasse die Werte in metadata als Zeichenfolgen.
  • Verwende für provider den PSP-Slug, den deine Integration erfordert. Den Wert für merchant_id erhältst du von deinem PSP.

MCP-Server: Das Tool complete_checkout bereitstellen

Du kannst dieses Muster übernehmen und deine eigene Logik einsetzen:

Wenn CallToolResult direkt zurückgegeben wird, verwendet das Python MCP SDK den unten gezeigten Rückgabetyp Annotated, um das outputSchema des Tools für structuredContent zu deklarieren.

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

Passe das Beispiel für folgende Schritte an:

  • Binde deinen Zahlungsdienstleister ein, um die Zahlungsmethode in payment_data zu belasten.
  • Speichere die Bestellung dauerhaft in deinem System.
  • Gib verbindliche Bestell- und Belegdaten zurück.
  • Füge _meta.ui.resourceUri hinzu, wenn du ein Bestätigungs-Widget anzeigen möchtest (ChatGPT unterstützt _meta["openai/outputTemplate"] als optionalen Alias für die Kompatibilität).

Die folgenden Zahlungsdienstleister unterstützen die Zahlungsabwicklung für den ChatGPT-Zahlungsdialog:

Optional: Rohdaten von Zahlungsmethoden empfangen

Wenn dein Handelsunternehmen ein Zertifikat nach PCI DSS Level 1 besitzt, kannst du die Rohdaten von Zahlungsmethoden direkt empfangen. Implementiere dazu den Endpunkt Delegate Payment des Agentic Commerce Protocol. Die Anfrage für die delegierte Zahlung enthält alle Angaben zur Zahlungsmethode, die dein Zahlungsablauf benötigt, einschließlich der vollständigen Kartennummer, des Ablaufdatums, des CVC, der Rechnungsadresse, der Beschränkungen des Zahlungsrahmens, der Risikosignale und der Metadaten.

Eine Anfrage mit den Rohdaten einer Kartenzahlungsmethode sieht beispielsweise so aus:

{
  "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"
  }
}

Die zugehörige Antwort sollte eine ID zurückgeben, die die Zahlungsmethode repräsentiert. Diese ID wird als Teil von payment_data an complete_checkout übergeben.

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

Fehlerbehandlung

Der Tool-Aufruf complete_checkout kann Nachrichten vom Typ error zurückgeben. Fehlermeldungen, bei denen code auf payment_declined oder requires_3ds gesetzt ist, werden im ChatGPT-Zahlungsdialog angezeigt. Alle anderen Fehlermeldungen werden als Antwort auf requestCheckout an das Widget zurückgesendet. Das Widget kann den Fehler nach Bedarf anzeigen.

Testzahlungsmodus

Du kannst beim Aufruf von requestCheckout das Feld payment_mode auf test setzen. Dadurch wird ein ChatGPT-Zahlungsdialog angezeigt, der Testkarten akzeptiert (etwa die Testkarte 4242). Der daraus resultierende token in payment_data, der an das Tool complete_checkout übergeben wird, kann in der Staging-Umgebung deines PSP verarbeitet werden. So kannst du Abläufe von Anfang bis Ende testen, ohne echtes Geld zu bewegen.

Beachte, dass du im Testzahlungsmodus für merchant_id möglicherweise einen anderen Wert festlegen musst. Weitere Informationen findest du im Leitfaden zur Monetarisierung deines Zahlungsanbieters.

Checkliste für die Implementierung

  1. Definiere dein Modell für Checkout-Sitzungen: Nimm IDs, das Objekt für den Zahlungsanbieter, Einzelpositionen, Summen und Links zu rechtlichen Informationen auf.
  2. Gib die Sitzung aus deinem MCP-Tool zurück , und zwar in structuredContent zusammen mit deiner Widget-Vorlage.
  3. Stelle die Sitzung im Widget dar , damit Nutzende Artikel, Summen und Bedingungen überprüfen können.
  4. Rufe requestCheckout(session_data) auf , wenn Nutzende die entsprechende Aktion ausführen. Verarbeite die zurückgegebene Bestellung oder den Fehler.
  5. Ziehe die Zahlung ein , indem du das MCP-Tool complete_checkout implementierst, das eine Antwort gemäß der Checkout-Spezifikation zurückgibt.
  6. Teste den gesamten Ablauf mit realistischen Beträgen, Steuern und Rabatten, um sicherzustellen, dass der Host die erwarteten Summen anzeigt.