Inside ACP: OpenAI and Stripe's delegated payment for agents
When ChatGPT buys a pair of shoes on your behalf, a payment credential moves through four parties without the agent ever seeing your card number. The protocol that governs that move is worth reading closely.
The Agentic Commerce Protocol (ACP) is the standard OpenAI and Stripe published to let agents complete a purchase against a merchant. It is open source under Apache 2.0, date-versioned, and small enough to read in an afternoon. It is also a different design from the one this platform runs on. We have written about the stablecoin rail — x402, EIP-3009, AP2. ACP is the card rail. Understanding where the two diverge, and where they quietly agree, tells you a lot about how agent payments will actually settle.
What ACP actually is
ACP is two OpenAPI specifications and a governance model, nothing more. The first spec, the Agentic Checkout Specification, defines a REST contract a merchant implements so an agent can build a cart, price it, and place an order. The second, the Delegated Payment Specification, defines how a scoped payment credential is minted and handed off. The founding maintainers are OpenAI and Stripe. Versions are dated: the initial release was 2025-09-29, and the current stable snapshot is 2026-04-17, which added cart, feed, orders, delegated authentication, and an MCP surface.
That MCP surface matters. ACP can be exposed either as a plain HTTP API or as a Model Context Protocol server. The commerce capability becomes just another set of tools the model can call. The transport is interchangeable; the data structures are not.
The governing principle is stated plainly in the spec: the merchant remains the system of record for all orders, payments, taxes, and compliance. The agent orchestrates. It never becomes the merchant of record, and it never holds the raw payment instrument.
The checkout spec: five endpoints
A merchant that wants to sell inside an agent implements five endpoints. Every call runs over HTTPS, returns JSON, and carries an API-Version header. Amounts are always integers in minor units — cents, not dollars — which removes an entire class of floating-point rounding bugs at the protocol boundary.
# Create — returns 201 with a checkout_session_id
POST /checkout_sessions
# Update — replace items, address, or fulfillment option
POST /checkout_sessions/{checkout_session_id}
# Retrieve — authoritative session state (200, or 404)
GET /checkout_sessions/{checkout_session_id}
# Complete — carries the payment token, mints the order
POST /checkout_sessions/{checkout_session_id}/complete
# Cancel — 200 if cancelable, 405 if already terminal
POST /checkout_sessions/{checkout_session_id}/cancel
Every response returns the full cart state: line items, pricing, taxes and fees, shipping options, discounts, totals, and a status. There is no partial state to reconstruct client-side. The agent reads the session; the merchant owns the truth. Updates are total replacements — the items array you send overwrites the entire list, which makes each call idempotent in intent rather than incremental.
Errors follow a fixed shape: { type, code, message, param }, where param is an RFC 9535 JSONPath pointing at the offending field. The type is drawn from a closed set — invalid_request, request_not_idempotent, processing_error, service_unavailable. Order lifecycle events (order_create, order_update) are pushed to the agent platform's webhook receiver with an HMAC signature header. This is a boringly conventional REST API, and that is the point. The novelty is not in the checkout surface. It is in how the money moves.
The delegated payment spec: a scoped vault token
The complete call needs a payment credential. ACP refuses to let the agent carry a card number. Instead it defines a single mandatory endpoint that turns a real credential into a narrowly scoped token:
POST /agentic_commerce/delegate_payment
The call goes from the agent platform to a payment provider, and it is the most security-sensitive request in the protocol. So it is signed. The client computes a detached signature over the request body with its private key, base64url-encodes it, and sends it in a Signature header. The provider advertises acceptable algorithms out of band — Ed25519 or ES256. The request also carries a Timestamp in RFC 3339, an Idempotency-Key, a Request-Id for tracing, a bearer Authorization token, and the same API-Version pin.
POST /agentic_commerce/delegate_payment
Authorization: Bearer <psp_api_key>
API-Version: 2025-09-29
Signature: <base64url ed25519 over body>
Timestamp: 2026-07-18T14:03:11Z
Idempotency-Key: 5f2b9c1a-...
{
"payment_method": {
"type": "card",
"card_number_type": "network_token",
"number": "...", "exp_month": 11, "exp_year": 2028,
"cryptogram": "...", "eci_value": "05"
},
"allowance": {
"reason": "one_time",
"max_amount": 4999,
"currency": "usd",
"checkout_session_id": "cs_...",
"merchant_id": "acme",
"expires_at": "2026-07-18T14:18:11Z"
},
"risk_signals": [ { "type": "...", "score": 12, "action": "authorized" } ],
"metadata": { }
}
The response, on 201, is deliberately thin: an id that begins with vt_, a created timestamp, and a metadata echo. That vt_ value is the vault token. It is the only payment artifact the agent ever touches, and its power is bounded entirely by the allowance object it was minted with.
Read the allowance closely, because it is the whole security model. reason is one_time — the only value the spec accepts today. max_amount caps the charge. currency fixes the denomination. expires_at sets a hard wall: the token must become invalid at or after that instant. And merchant_id binds the token to a single business. A vault token is a card credential wrapped in a spend envelope that names the merchant, the ceiling, and the deadline. Steal it and you can do exactly one thing the buyer already approved, to exactly one merchant, for a few minutes.
One credential type is supported today: card. The card_number_type can be an fpan — the real primary account number — or a network_token, the card networks' own tokenized rail. That second option is the tell. ACP is built to ride on top of Visa and Mastercard's agentic tokenization, not around it.
Shared Payment Token: Stripe's implementation
The spec defines the shape; a payment provider fills it in. Stripe's Shared Payment Token (SPT) is the first Delegated Payment Spec-compatible implementation. It carries the same properties the spec demands: single-use, time-limited, scoped to one business, monitored through webhook events, and revocable. The underlying credential is never exposed to the agent, and Stripe designed the token to be compatible with the card networks' agentic tokens.
On the merchant side, accepting one is a small change. The vault token becomes the payment_method on a PaymentIntent, with confirm set to true and request_delegated_payment enabled on the card options. The merchant never stores the token. Crucially, a business that does not process with Stripe can still forward the token to its own vault or another processor — the credential is portable across the merchant's existing rails.
ACP is not x402, and the difference is the point
It is tempting to file ACP and x402 under one heading — "agent payments" — and move on. Do not. They solve different problems on different rails, and the gaps between them define where each belongs.
ACP is a card rail. The buyer's funding instrument is a Visa or Mastercard credential held at a PSP. Settlement runs on the existing card network, with its interchange, its chargebacks, its dispute windows, and its human-in-the-loop approval — today, every ACP charge still expects buyer review. The merchant of record is the store. The agent is a well-behaved shopper that never touches the money directly. It is optimized for retail: a person tells an assistant to buy a physical good, and the assistant completes a checkout the merchant already understands.
x402 is a stablecoin rail. The agent holds a wallet. Payment is an HTTP 402 response, a signed EIP-3009 authorization, and an on-chain transfer settled by a facilitator — no card network, no interchange, no custodian moving funds on anyone's behalf. It is optimized for machine-to-machine: an agent pays a fraction of a cent to call an API, read a page, or run a model, thousands of times, with no human in the loop at all.
The contrast is sharp on four axes. Custody: ACP delegates a custodial card credential; x402 moves self-custodied stablecoins. Human involvement: ACP assumes review per purchase; x402 assumes none. Amount profile: ACP is built for discrete retail totals; x402 is built for sub-cent, high-frequency draws. Reversibility: card settlement can be disputed and clawed back; a settled stablecoin transfer is final. Neither is strictly better. A shopping agent buying a sweater wants the card rail's dispute protection. A research agent paying per API call wants the stablecoin rail's finality and near-zero fee.
Where they converge
The rails differ, but the security architecture is converging on the same primitive. Look again at the ACP allowance — max_amount, expires_at, merchant_id, single use. Now look at the spend permissions we described in account abstraction for agent wallets: a scoped authorization with a cap, an expiry, and a bound counterparty. They are the same idea expressed on different infrastructure. ACP writes the envelope in a vault token; ERC-7715 and session keys write it in a signed on-chain permission; x402's per-request authorization writes it in an EIP-3009 signature. Every serious agent payment design has independently arrived at the same conclusion: never hand an agent a standing credential; hand it a token scoped to one intent.
The second convergence is the keys-out-of-the-model rule. ACP keeps the PAN at the PSP. x402 keeps the private key in a wallet the LLM cannot read. Both treat the language model as an untrusted orchestrator that arranges payments it can never unilaterally execute. That is the correct threat model, and both camps landed on it.
What it means for LLM4Agents
LLM4Agents settles on the stablecoin rail. Agents fund a balance and pay per model call over an OpenAI-compatible gateway, with x402 and EIP-3009 underneath. ACP does not compete with that — it addresses retail checkout, a different job. But it is a signal worth acting on for three reasons.
First, ACP validates the allowance-scoped-token pattern at the scale of OpenAI and Stripe. The vault token is, functionally, a per-intent spend authorization — exactly the shape our gateway already issues when an agent draws against its balance. A protocol backed by the largest AI platform and the largest payments company converging on the same envelope is confirmation that our primitive is the right one, not an idiosyncrasy.
Second, ACP's dual HTTP-or-MCP transport is the model to follow. Commerce as an MCP tool set is exactly how agents will reach services, and it mirrors the MCP surface we already ship. The lesson: expose capability through both a plain REST contract and an MCP server, and let the agent pick.
Third, the two rails will meet at the buyer. A single agent will pay for its API and model consumption in stablecoins while completing retail purchases on cards. The platform that lets an operator reason about both spend streams — the machine-to-machine draws and the delegated card charges — under one budget and one audit trail wins the operator's trust. That is a position worth building toward.
Staying on the frontier
Concrete steps, in order. First, formalize our spend authorization as an explicit, inspectable object with the same fields ACP standardized — cap, expiry, bound counterparty, single-use flag — so an operator can read exactly what each agent draw was allowed to do. Borrow the allowance vocabulary; it is now an industry lingua franca.
Second, adopt ACP's request-signing discipline on our most sensitive internal calls: detached Ed25519 signatures, RFC 3339 timestamps, mandatory idempotency keys, and a pinned API version. These are cheap to add and they harden the settlement path against replay and confused-deputy attacks — the same failure modes we flagged in the MCP authorization deep dive.
Third, ship an ACP-shaped adapter. When an agent on our platform needs to complete a retail purchase, it should be able to speak the checkout_sessions contract and hand off a delegated token, while continuing to fund its API consumption in stablecoins. One agent, two rails, one balance. Build the bridge before operators ask for it.
Fourth, publish the audit trail as a first-class artifact. ACP pushes order_create and order_update webhooks; x402 leaves an append-only settlement record. An operator running a fleet across both rails needs a single reconciled ledger. That ledger is a product, not a log file.
Build on the rail agents already run on
Per-call stablecoin settlement, scoped authorizations, OpenAI-compatible. Point your agent at the gateway and pay only for what it uses.
Register your agent