How to give your AI agent a checkout tool
Your Claude or GPT agent can decide what to buy. Giving it a tool to actually place the order — safely, without double-charging on a retry — is the part most teams underestimate. Here's what a real checkout tool needs, and how to add one in about 5 minutes.
What a "checkout tool" actually needs
A single "charge a card" function isn't a checkout tool. For an agent to transact, the tool needs four things behind it:
- A catalog — products/SKUs the agent can reference by ID.
- A checkout session — a place to gather line items, buyer, and payment.
- An order record — a durable result your systems can act on.
- Idempotency — because an autonomous agent will retry, and a retry must not create a second order.
The retry problem (why this is hard)
Agents retry tool calls on timeouts and errors. If your "complete checkout" endpoint isn't idempotent, a network blip after the charge succeeds — but before your agent sees the response — leads the agent to call it again, creating a duplicate order and a duplicate charge. Building this correctly means keys, dedup, and careful edge-case testing on top of Stripe and your own order database.
Two ways to build it
Roll your own: wire Stripe PaymentIntents, design an order schema and DB, implement idempotency keys and dedup, add signed webhooks, and write per-model tool schemas. Doable — it's just a project, not an afternoon.
Use OrderCore: four ready-made tools (create_checkout_session,
update_checkout_session, create_payment_intent,
complete_checkout_session) over REST or an MCP server,
with idempotent orders and webhooks built in. Full comparison:
OrderCore vs Stripe + a custom backend.
The flow, in code
Create a session for catalog line items, then complete it into an idempotent order:
const BASE = 'https://api.ordercore.ai'; // short-lived public checkout token (the agent/MCP flow) const { token } = await (await fetch(BASE + '/v1/account/checkout-access-tokens', { method: 'POST', headers: { 'X-API-Key': process.env.ORDERCORE_API_KEY } })).json(); const H = { 'Content-Type': 'application/json', 'X-Checkout-Token': token }; const { session_id } = await (await fetch(BASE + '/ucp/public/checkout/sessions', { method: 'POST', headers: H, body: JSON.stringify({ line_items: [{ item: { id: SKU }, quantity: 1 }], currency: 'USD' }) })).json(); // safe to retry: the same session always resolves to the same order const order = await (await fetch(BASE + `/ucp/public/checkout/sessions/${session_id}/complete`, { method: 'POST', headers: H, body: JSON.stringify({ session_id, payment_data: { handler_id: 'card', payment_intent_id: 'pi_...' } }) })).json();
Expose those calls to your model as tools — or point Claude/GPT at the ready-made MCP server. Machine-readable schemas for OpenAI, Claude, Gemini, DeepSeek, and Grok live at /direct-ai/tooling.
See it prove idempotency (no signup)
The runnable demo completes the same session twice and asserts you get one order, not two. It runs offline in mock mode — no key, no signup — so you can judge it in 30 seconds:
Related
- Agent commerce quickstart — JS + curl, idempotency, troubleshooting
- OrderCore vs Stripe + a custom order backend
- Claude / MCP quickstart
- Full API docs