# Zahlung akzeptieren Zahlungen sicher akzeptieren mit Ihrer MCP-App. # Weiterleitung > This is a Weiterleitung for when platform is web and ui is stripe-hosted. View the full page at https://docs.stripe.com/agentic-commerce/apps/accept-payment?platform=web&ui=stripe-hosted. Collect payments outside your app with a prebuilt Stripe-hosted Checkout page. This guide shows how to: - Definieren von Model Context Protocol (MCP)-Tools, um Produkte anzuzeigen und Kundinnen und Kunden die Auswahl der zu kaufenden Posten zu ermöglichen - Zahlungen mit [einer vorgefertigten, von Stripe gehosteten Checkout-Seite](https://docs.stripe.com/payments/checkout.md) einziehen - Überwachen Sie nach erfolgreicher Zahlung die Webhooks ## Stripe einrichten Add the Stripe API library to your back end. #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Produkte und Preise erstellen This example displays a group of products in the MCP app. [Create products and prices in the Dashboard or with the Stripe CLI](https://docs.stripe.com/products-prices/manage-prices.md). ## Registrieren Sie ein Checkout MCP-Tool Registrieren Sie ein MCP-Tool, das eine [Checkout-Session](https://docs.stripe.com/api/checkout/sessions.md) für einen Satz an *Preisen* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) erstellt. Sie rufen dieses Tool in einem späteren Schritt über die MCP-App auf. ```javascript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server"; import { readFileSync } from "node:fs"; import Stripe from "stripe"; import { z } from "zod"; // Follow https://docs.stripe.com/keys-best-practices to protect your Stripe API keys. const stripe = new Stripe(process.env.STRIPE_API_KEY); const server = new McpServer({ name: "my-mcp-server", version: "1.0.0" }); const resourceUri = "ui://list-products.html"; async function createCheckoutSession(priceIds) { const lineItems = priceIds.map((price) => ({ price, quantity: 1 })); const session = await stripe.checkout.sessions.create({ mode: "payment", line_items: lineItems, success_url: "https://example.com/checkout/success", }); return session; } // Register the tool that creates a checkout session server.registerTool( "buy-products", { title: "Buy products", description: "Create a checkout page link for purchasing the selected products", inputSchema: { priceIds: z.array(z.string()) }, }, async ({ priceIds }) => {const session = await createCheckoutSession(priceIds); return { content: [ { type: "text", text: `[Complete your purchase here](${session.url})`, }, ], structuredContent: { checkoutSessionId: session.id, checkoutSessionUrl: session.url, }, }; } ); ``` ## Registrieren Sie ein Tool für die Nutzeroberfläche und eine Ressource Richten Sie die Nutzeroberfläche für Ihre MCP-App ein, indem Sie ein MCP-Tool und eine Ressource registrieren. Diese Nutzeroberfläche: 1. Eine Produktliste wird angezeigt 1. Ermöglicht der Kundin/dem Kunden die Auswahl der zu kaufenden Produkte 1. Weiterleitung an Stripe Checkout, um die Zahlung abzuschließen ### Register a product list MCP tool Create a product list MCP tool. Its callback returns the price IDs for the products to display in the UI. ```javascript registerAppTool( server, "list-products", { title: "List products", description: "List the products available for purchase", _meta: { ui: { resourceUri } }, }, async () => { const suggestedProducts = [ // The price IDs from the earlier step { priceId: "{{PRICE_ID}}", name: "Test product 1" }, { priceId: "{{PRICE_ID}}", name: "Test product 2" }, ]; return { structuredContent: { products: suggestedProducts }, content: [], }; } ); ``` ### Register a product list UI resource Erstellen Sie eine MCP-Ressource für das Produktlisten-Widget. Sie definiert die Nutzeroberfläche, die die Produkte anzeigt. ```javascript // Register the resource that serves the bundled HTML registerAppResource( server, "list-products-widget", resourceUri, { mimeType: RESOURCE_MIME_TYPE }, async () => { const html = readFileSync("dist/ui/list-products.html", "utf8"); return { contents: [ { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html, }, ], }; } ); ``` This example uses minimal markup. In a production app, use a framework such as React. See the [MCP Apps documentation](https://modelcontextprotocol.github.io/ext-apps/) for additional examples. ```html
``` ```js import { App } from "@modelcontextprotocol/ext-apps"; const app = new App({ name: "ProductList", version: "1.0.0" }); // Establish communication with the host await app.connect(); /** * UI markup and event handlers */ const renderProduct = (product) => { return ` `; }; const handleSubmit = async (event) => { // We'll fill this in next } const renderApp = (products) => { const root = document.querySelector("#root"); root.innerHTML = `$${(product.amount / 100).toFixed(2)}
`; }; app.ontoolresult = (params) => { const { productName, amount, priceID } = params.structuredContent ?? {}; product = { name: productName ?? "", amount: amount ?? 0, priceID: priceID ?? "" }; render(); }; render(); ``` ### Versandadresse und Steuer mit Stripe einziehen Sie können die Stripe Tax API verwenden, um Steuern für den nächsten Schritt zu berechnen. Weitere Informationen finden Sie unter [Standalone Tax API verwenden](https://docs.stripe.com/tax/standalone-tax-api.md). ### ChatGPT Instant Checkout-Modal öffnen Dadurch werden Kundinnen und Kunden aufgefordert, eine Zahlungsmethode auszuwählen. Fügen Sie Logik hinzu, um eine Checkout-Sitzung zu erstellen, der der Preis-ID aus dem vorherigen Schritt zugeordnet wird. Der folgende Codeausschnitt fügt der Preis-ID eine UUID hinzu, um eine Checkout-Sitzung-ID zu erstellen. ```javascript const getTax = (priceID) => { // Add your tax integration }; const createCheckoutSession = (priceID) => { const uuid = crypto.randomUUID(); return `${priceID}::${uuid}`; }; const handleSubmit = (e) => { e.preventDefault(); const { name, amount, priceID } = product; const tax = getTax(priceID); window.openai.requestCheckout({// This is priceID passed in from the MCP buy product tool id: createCheckoutSession(priceID), // remove this when you are ready for live mode payment_mode: "test", payment_provider: { provider: "stripe",// Insert your Network ID from the Stripe dashboard merchant_id: networkID, supported_payment_methods: ["card"], }, status: "ready_for_payment", currency: "USD", line_items: [ { id: "line_items_123", item: { id: priceID, quantity: 1, }, base_amount: product.amount, subtotal: product.amount, tax: tax, total: product.amount + tax, }, ], totals: [ { type: "items_base_amount", display_text: product.name, amount: product.amount, }, { type: "subtotal", display_text: "Subtotal", amount: product.amount, }, { type: "tax", display_text: "Tax", amount: tax, }, { type: "total", display_text: "Total", amount: product.amount + tax, }, ], fulfillment_options: [], fulfillment_address: null, messages: [], links: [ { type: "terms_of_service", url: "https://example.com/terms", }, ], }); } ``` ## MCP-Tool registrieren, um Bezahlvorgang abzuschließen When the customer selects a payment method in the ChatGPT payment UI and clicks **Pay**, ChatGPT calls your `complete_checkout` tool and returns the SPT that you use to create a `PaymentIntent`. Registrieren Sie ein `complete_checkout`-MCP-Tool, das ein gewährtes gemeinsames Zahlungstoken als Eingabe nimmt und zur Verarbeitung an die [Payment Intents API](https://docs.stripe.com/api/payment_intents.md) übergibt. ```javascript const retrievePriceID = (checkout_session_id: string) => { const [priceID, uuid] = checkout_session_id.split('::'); return priceID; }; server.registerTool( "complete_checkout", { description: "Complete the checkout and process the payment", inputSchema: { checkout_session_id: z.string(), buyer: z .object({ name: z.string().nullable(), email: z.string().nullable(), phone_number: z.string().nullable(), }) .nullable(), payment_data: z.object({ token: z.string(), provider: z.string(), billing_address: z .object({ name: z.string(), line_one: z.string(), line_two: z.string().nullable(), city: z.string(), state: z.string(), country: z.string(), postal_code: z.string(), phone_number: z.string().nullable(), }) .nullable(), }), }, }, async ({checkout_session_id, buyer, payment_data}) => { const price = (await stripe.prices.retrieve(retrievePriceID(checkout_session_id as string))) // Add your tax logic const tax = getTax() // confirms the SPT stripe.paymentIntents.create({ amount: price.unit_amount + tax, currency: price.currency, shared_payment_granted_token: payment_data.token, confirm: true, }); return { content: [], structuredContent: { id: checkout_session_id, status: "completed", currency: price.currency, buyer, line_items: [], order: { id: "{{ORDER_ID}}", checkout_session_id, permalink_url: "", }, }, }; } ); ``` ## Testen Verwenden Sie den Test-Modus für Zahlungen von ChatGPT mit einer Stripe-Testumgebung, um Ihre App zu testen, ohne echtes Geld zu bewegen. 1. Geben Sie im Stripe-Dashboard eine [Sandbox](https://docs.stripe.com/sandboxes.md) ein. 1. Erstellen Sie ein Stripe-Testprofil, verbinden Sie sich mit ChatGPT in der Testumgebung und kopieren Sie Ihre Test-Netzwerk-ID. 1. Aktualisieren Sie Ihre ChatGPT-App-Einstellungen, um des Test-Modus für Zahlungen zu verwenden, sodass Testkarten erwartet und Test-SPTs generiert werden. 1. Wenn Sie einen Bezahlvorgang anfordern, geben Sie Ihre Testprofil-ID an und legen Sie `payment_mode` auf `test` fest, damit ChatGPT Testkarten erwartet und Test-SPTs generiert. ```javascript window.openai.requestCheckout({ id: priceID,payment_mode: "test", payment_provider: { provider: "stripe",merchant_id: "profile_test", supported_payment_methods: ["card"], }, ``` 1. Verwenden Sie Ihren Test-Stripe-API-Schlüssel in Ihrer MCP-Tool-Implementierung, um Test-SPTs von ChatGPT zu verarbeiten. Befolgen Sie [Best Practices](https://docs.stripe.com/keys-best-practices.md), um den Schlüssel sicher zu verwenden: Betten Sie ihn nicht direkt in Ihren Code ein und verwenden Sie einen Geheimschlüssel-Manager, wenn Ihre Plattform einen bereitstellt. 1. Richten Sie in Ihrer Live- und Testumgebung identische Webhook-Konfigurationen ein und stellen Sie sicher, dass sich Test-Webhook-Handler nicht auf Ihre Produktionssysteme auswirken können. Wenn beispielsweise Ihr Live-Webhook den Versand auslöst, sollte der Test-Endpoint nur protokollieren, dass er im Live-Modus versendet worden wäre. Nachdem Sie diese Schritte ausgeführt haben, bewerten Sie den Zahlungsablauf in Ihrer App, ohne echtes Geld zu bewegen. ### App im Live-Modus veröffentlichen Wenn Sie bereit sind, Ihre App in den Live-Modus zu versetzen: 1. Erstellen Sie einen live [eingeschränkten API-Schlüssel](https://docs.stripe.com/keys-best-practices.md#limit-access) (`rk_live_...`) mit **Payment Intents: Write**-Berechtigungen. Mit einem eingeschränkten Schlüssel können Sie Ihrem MCP-Tool genau die Berechtigungen erteilen, die es benötigt. 1. Aktualisieren Sie Ihr MCP-Tool, um den live eingeschränkten API-Schlüssel zu verwenden. 1. Aktualisieren Sie die Checkout-Anfrage Ihrer App mit Ihrer Live-Profil-ID und entfernen Sie die Testoption `payment_mode`. Your app is then ready to handle live payments. You must complete this step before submitting for ChatGPT app review. > Nachdem Sie Ihre ChatGPT-App eingereicht haben, dürfen Sie den Zahlungsmodus nicht mehr verwenden, da er für Live-Kundinnen und -Kunden sichtbar ist. ## See also - [Modellkontextprotokoll](https://modelcontextprotocol.io/) - [ChatGPT Apps SDK](https://developers.openai.com/apps-sdk)