Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseUse Managed Payments
Use Payment Links
Use a pre-built checkout page
Build a custom integration with Elements
Build an in-app integration
In-person payments
Terminal
Payment Methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
Beyond payments
Incorporate your company
Crypto
Agentic commerce
    Overview
    Key concepts
    Monetise your ChatGPT app
      Accept a payment
    Enable in-context selling on AI agents
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
United States
English (United Kingdom)
HomePaymentsAgentic commerceMonetize your ChatGPT app

Accept a payment

Securely accept payments with your ChatGPT app.

You can collect payments outside your app with a prebuilt Stripe-hosted Checkout page. This guide shows how to:

  • Define Model Context Protocol (MCP) tools to display products and let customers select items to buy
  • Collect payment details with a prebuilt Stripe-hosted Checkout page
  • Monitor webhooks after a successful payment

Set up Stripe

To set up Stripe, add the Stripe API library to your back end.

Command Line
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# Available as a gem sudo gem install stripe
Gemfile
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Create products and prices

In this example, you can display a group of products in the ChatGPT app. Learn how to create products and prices in the Dashboard or with the Stripe CLI.

Register a Checkout MCP tool

Register an MCP tool that creates a Checkout Session for a set of Prices. You call this tool from the ChatGPT app in a later step.

server.js
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { readFileSync } from "node:fs"; import Stripe from "stripe"; import { z } from "zod"; const stripe = new Stripe(
"sk_test_BQokikJOvBiI2HlWgH4olfQ2"
) const server = new McpServer({ name: "my-mcp-server", version: "1.0.0" }); 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; } 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, }, }; } );

Register a ChatGPT UI tool and resource

Set up the UI for your ChatGPT app by registering an MCP tool and resource. This UI:

  1. Displays a list of products
  2. Lets the customer select products to buy
  3. Redirects to Stripe Checkout to complete payment

Register a list products MCP tool

Create a list products MCP tool. Its callback returns the price IDs for the products to display in the UI.

server.js
const listProductsUri = "ui://list-products-v1.html"; server.registerTool( "list-products", { title: "List products", description: "List the products available for purchase", _meta: { "openai/outputTemplate": listProductsUri }, }, 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 list products UI resource

Create an MCP resource for the product list widget. It defines the UI code that displays the products.

server.js
const listProductsHTML = readFileSync("ui/list-products.html", "utf8"); server.registerResource( "list-products-widget", listProductsUri, {}, async (uri) => ({ contents: [ { uri: uri.href, mimeType: "text/html+skybridge", text: listProductsHTML, _meta: { "openai/widgetCSP": { connect_domains: ["https://checkout.stripe.com"], resource_domains: ["https://checkout.stripe.com"], }, }, }, ], }) );

This example uses minimal markup. In a production app, you can use a framework such as React. See the ChatGPT Apps SDK documentation for additional examples.

ui/list-products.html
<div id="root"></div> <script> /** * UI markup and event handlers */ const renderProduct = (product) => { return ` <label> <input type="checkbox" name="cart[]" value="${product.priceId}"> ${product.name} </label> `; }; const renderApp = (products) => { const root = document.getElementById("root"); root.innerHTML = ` <h1>Select products to purchase</h1> <form onsubmit="handleSubmit(event)"> ${products.map(renderProduct).join("")} <button type="submit">Buy</button> </form> `; }; /** * Render the list of products from the tool's structuredContent */ const handleSetGlobal = (event) => { const { products } = event.detail.globals["toolOutput"] ?? []; renderApp(products); }; window.addEventListener("openai:set_globals", handleSetGlobal, { passive: true, }); </script>

Redirect to Checkout

When the customer clicks Buy in the ChatGPT app:

  1. Call the tool that you created that buys product to create a Checkout Session URL.
  2. Open the Checkout Session URL.
ui/list-products.html
const handleSubmit = async (event) => { event.preventDefault(); const formData = new FormData(event.target); const priceIds = Array.from(formData.values()); const { structuredContent } = await window.openai.callTool("buy-products", { priceIds, }); window.openai.openExternal({ href: structuredContent.checkoutSessionUrl }); };

Handle successful orders

You can handle successful orders by listening to checkout.session.completed (and checkout.session.async_payment_succeeded for delayed methods) and calling an idempotent fulfillment function that retrieves the Checkout Session (expand line_items), verifies payment_status, and fulfills the items.

Use a success_url landing page to trigger fulfillment immediately after redirecting, but rely on webhooks to make sure that every payment is fulfilled.

Then, you can test locally with the Stripe CLI, and deploy your webhook endpoint.

Learn more about how to fulfill payments received with the Checkout Sessions API.

See also

  • Collect taxes
  • Collect shipping and other customer info
  • Customize your branding
  • Customize your success page
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc