Blog · · 11 min read
Build agentic payments without giving AI agents a blank check

Agentic payments fail when a product treats a model's decision as payment authority. The agent can select the wrong item, accept a changed price, retry a charge, or report success before the payment rail and order system agree. A reusable credential turns one bad decision into an account-wide risk. A safer integration gives the agent a narrow mandate, resolves current product state before purchase, commits through an idempotent payment path, and verifies both payment and order outcomes. The control plane below works with AP2, ACP, or an existing checkout API.
Why the protocol is not your control plane
Payment protocols handle interoperability, but they do not own your user's account, your authorization policy, or your merchant relationship.
Google's Agent Payments Protocol overview separates human-present and delegated purchase flows. It uses signed Intent and Cart Mandates to preserve evidence of what a user requested and what cart they authorized. The AP2 repository supplies schemas and reference scenarios for that exchange.
The Agentic Commerce Protocol repository focuses on agent-facing checkout, payment handlers, order flows, delegated payments, and versioned schemas. Its canonical overview keeps the merchant as merchant of record and describes integration with existing commerce infrastructure.
A protocol defines what crosses an integration boundary. It does not replace a product-owned policy decision, credential broker, transaction identity, order reconciliation process, or refund path. Put the protocol inside the payment state machine rather than building the state machine around protocol messages.
Define the records your product owns
Define the durable records before you touch the prompt. Each one should have an immutable identifier, tenant and user ownership, timestamps, a schema version, and an audit link to the actor or service that changed it.
Payment intent
A payment intent captures the user's job before a merchant cart exists. Record the requested item or outcome, quantity, acceptable substitutions, merchant constraints, maximum total, currency, delivery destination, deadline, and whether the agent may complete the purchase without another prompt.
Retain the user's words as evidence. Typed fields carry the authority. If the user says, "Buy a replacement SSD for under $400 from an approved supplier," store the amount, currency, supplier rule, destination, and substitution policy separately so deterministic code can evaluate them.
User mandate
A mandate is the narrow grant that allows one purchase attempt or a bounded class of attempts. Bind it to the user, agent release, payment intent, tenant, permitted merchant or merchant class, amount ceiling, currency, destination, payment instrument reference, start time, expiry, and revocation state.
AP2's frequently asked questions draws a clear line: deterministic proof of user intent should anchor the purchase instead of an inference that the model probably meant to buy. A product can adopt that principle even when its payment provider does not speak AP2.
Policy decision
The policy decision records the exact inputs and result used immediately before commit. It should answer:
- Is this user, tenant, agent release, and workflow allowed to purchase?
- Does the cart stay inside the mandate's merchant, item, amount, currency, timing, and destination limits?
- Is the payment instrument valid for this merchant and transaction class?
- Does the action require fresh approval because risk or product state changed?
- Is the mandate active, unexpired, and not revoked?
Return a typed result such as allow, deny, or approval_required. Include a reason code and policy version. Do not return a paragraph that downstream code must reinterpret.
Checkout commit and receipts
The checkout commit joins the mandate, authoritative cart, policy decision, idempotency key, merchant checkout, payment-provider request, and final receipts. Store payment credentials only as references to a vault or broker. The model and ordinary tool traces should never receive raw card data, private keys, or reusable payment tokens.
Preserve two distinct outcomes: the payment rail's result and the merchant order's result. A successful authorization with no order, or an accepted order with a failed payment, is not a completed purchase.
Build the agentic payments lifecycle in seven steps
1. Create a typed intent
Parse the user's request into a candidate intent, then require clarification for fields that can change the financial effect. Currency, tax treatment, shipping destination, quantity, substitution, and recurring billing are not cosmetic details.
For human-present checkout, show the normalized intent before shopping. For delegated work, compare it with an existing standing mandate and stop when the requested scope exceeds that grant.
2. Issue or select a mandate
Create a one-time mandate when the user approves a known cart. Use a standing mandate only when the product genuinely needs unattended purchases. Standing grants should have lower ceilings, shorter expiries, narrower merchant rules, and a clear revocation control.
Store the mandate body and signature or verification material outside the model conversation. Put only its stable identifier and non-sensitive limits into the agent run state.
3. Build an authoritative cart
The agent can search and propose products. Merchant and product APIs still decide current price, inventory, tax, shipping, and final line-item identifiers. Build a canonical cart snapshot from those systems, then attach its version or digest to the policy request.
If a price, seller, quantity, subscription term, or delivery date changes after approval, do not silently fit the new cart under the old total. Apply an explicit change policy. Material changes should create a new cart mandate or return approval_required.
4. Evaluate policy immediately before commit
Recheck the user's current authority and the mandate's revocation state just before payment. A long-running agent may have started hours earlier. Account suspension, role changes, incident controls, expired grants, and changed tenant rules must take effect before money moves.
Freeze the policy input and result beside the transaction. That makes a later dispute answerable without reconstructing mutable account state from logs.
5. Commit once with one transaction identity
Generate the idempotency identity in your product, not inside the model. Reuse it across retries for the same authorized cart and create a new identity only after a deliberate material change.
Every mutating boundary should carry that identity where supported: product purchase record, protocol request, merchant checkout, payment provider, and order creation. An ACP issue about its MCP binding reports that mandatory idempotency became optional in one tool surface. Test every adapter because it can weaken an invariant unless the product enforces that invariant before dispatch.
6. Verify rail and order outcomes
Treat a signed application receipt as evidence of what one component said, not as proof that every external effect happened. An AP2 issue about success receipts reports a path that could create a success receipt without payment-rail finality evidence. Require a provider authorization or settlement reference, then query the authoritative merchant order state.
Write completed only when the configured completion rule is true. For a physical order, that may require an accepted payment authorization and a merchant order identifier. For an asynchronous rail, use payment_pending rather than pretending settlement is final.
7. Carry reversal and dispute states
Checkout is only one payment state. Model cancellation before commit, cancellation after authorization, void, refund requested, partial refund, refund completed, chargeback, dispute, and unreconciled states.
Bind each reversal to the original transaction and mandate. Preserve amounts, currencies, provider references, reasons, actors, and timestamps. A refund retry needs its own idempotency identity, not the purchase key reused in a different operation.
Work through a realistic purchase
Suppose a support operations agent must buy a replacement SSD after hardware diagnostics confirm failure. The user has a standing mandate capped at $400, limited to two approved suppliers, with delivery to the company's registered office.
The agent finds a $329 drive and asks the merchant for a checkout session. Tax and shipping bring the authoritative total to $371. The seller, item class, currency, and destination match the mandate, so policy returns allow. The product creates transaction pay_01, calls its credential broker for a transaction-bound payment token, and commits with one idempotency key.
The payment provider authorizes the charge, but the merchant times out before returning an order ID. The product records payment_authorized_order_unknown, not completed. It queries the merchant by checkout ID and idempotency key. If the order exists, it links the order receipt and completes. If the merchant confirms that no order exists, the product voids the authorization and records the reversal.
If the first drive goes out of stock, the agent may choose a $389 substitute. Tax pushes the total above $400. The old mandate does not authorize the new cart, even if the model describes the substitution as equivalent. The product returns approval_required with the cart and price delta. No prompt can override that result.
Encode the invariant before choosing a vendor
A small product-owned function should decide whether payment is possible. Protocol and provider adapters run only after it succeeds.
commit_purchase(intent_id, mandate_id, cart_version, transaction_id):
intent = load_intent(intent_id)
mandate = load_and_verify_mandate(mandate_id)
cart = merchant.get_current_cart(cart_version)
authority = identity.get_current_authority(intent.user_id)
decision = policy.evaluate(intent, mandate, cart, authority)
if decision.result != "allow":
return typed_outcome(decision.result, decision.reason)
existing = payments.find_by_transaction_id(transaction_id)
if existing:
return reconcile(existing)
credential_ref = broker.issue_transaction_credential(decision)
rail_receipt = provider.authorize(cart, credential_ref, transaction_id)
order_receipt = merchant.confirm_order(cart, transaction_id)
return reconcile(rail_receipt, order_receipt)
This function belongs in deterministic application code. The model can recommend products and explain tradeoffs, while ordinary services own limits, current authorization, credentials, retries, and completion.
Handle failures as state transitions
Do not flatten every exception into failed or every signed receipt into success.
- If mandate verification fails, stop before policy evaluation. Record the verification reason without exposing signature material.
- If someone revokes the mandate during a run, deny any commit that has not crossed the irreversible boundary. Cancel queued work and reconcile work already in flight.
- If the broker issues a payment token but the provider call fails, expire or revoke the token. Retry with the same transaction identity only when policy permits it. An AP2 issue about token consumption reports state advancing before settlement with no restoration after failure. Test that partial transition directly.
- If payment succeeds but order creation is unknown, enter an explicit reconciliation state. Query both systems before retrying either effect.
- If the order succeeds after the client disconnects, preserve the durable result. A reconnect should read the existing transaction instead of replaying checkout.
- If a refund request times out, query by refund identity before sending another request.
- If a protocol verifier accepts incomplete evidence, enforce the missing claims at your boundary. An AP2 verifier issue reports missing audience and nonce checks being accepted in a reference path.
Each state needs an owner, retry policy, deadline, alert, and terminal recovery. If operations staff cannot distinguish payment_unknown from order_unknown, they cannot repair the transaction safely.
Choose AP2, ACP, or an existing payment API
The required integration boundary should drive the protocol choice.
Use AP2 when portable proof of user intent and mandate exchange is central, especially for human-not-present purchases across participating agents, merchants, and payment actors. Keep your product's policy and reconciliation records around it.
ACP fits an agent that needs a standardized merchant checkout and order flow, or commerce infrastructure that can expose the protocol without surrendering merchant-of-record control. Treat the current beta schema version as an explicit dependency and test adapter upgrades.
An existing payment API is often enough when the agent operates inside one product and does not need protocol-level interoperability. You still need typed intents, narrow grants, credential isolation, idempotency, rail evidence, order reconciliation, and reversals. A proprietary API does not remove those controls.
A product may support more than one. Keep protocol adapters behind the same internal intent, mandate, policy, transaction, and receipt model so the safety contract does not change with the transport.
Verify the integration before release
Run deterministic tests against the full payment state machine:
- Replay the same commit request concurrently and prove that only one charge and one order exist.
- Revoke a mandate after cart creation but before commit and prove that payment is blocked.
- Change price, currency, seller, quantity, subscription term, and destination independently. Confirm the correct approval or denial result.
- Inject provider success with merchant timeout, merchant success with provider timeout, and client disconnect after commit. Verify reconciliation without duplicate effects.
- Return a signed application receipt without rail evidence and prove that the transaction does not become completed.
- Fail after credential issuance and prove that the credential cannot be reused outside the authorized transaction.
- Exercise void, full refund, partial refund, duplicate refund, and dispute paths.
- Confirm that ordinary traces contain mandate and transaction references but no raw payment credential.
- Upgrade each protocol adapter against recorded contract fixtures and rerun every partial-failure case.
- Ask an operator to resolve an
order_unknowntransaction using only the stored evidence and runbook.
One practitioner project for agent spending asks for transaction caps, recipient rules, duplicate prevention, and fail-closed decisions in its PolicyLayer author report. That is problem language, not prevalence data. Your tests, policy, and receipts must provide the evidence for your own product.
Take the next action
Pick one current purchase flow and draw its payment state machine from user intent through refund. Mark who owns each transition, where authority is checked, which system supplies the authoritative fact, and which idempotency identity crosses each boundary. Then add the three failure states your happy path currently hides. That exercise tells you whether agentic payments can reuse your existing checkout safely or need a new mandate and reconciliation layer before an agent is allowed to spend.
References
- Google Cloud: Powering AI commerce with the Agent Payments Protocol supports AP2's authorization, mandate, evidence, and human-present versus delegated flow model.
- Google Agent Payments Protocol repository supports AP2 schemas and reference scenarios.
- AP2 frequently asked questions supports deterministic proof of user intent and granular user control.
- Agentic Commerce Protocol repository supports ACP checkout, delegated payment, order, handler, and versioned-schema behavior.
- Agentic Commerce Protocol supports merchant-of-record ownership and integration with existing commerce infrastructure.
- ACP issue #295 is an author report about mandatory idempotency becoming optional in an MCP binding.
- AP2 issue #327 is an author report about success receipts without payment-rail finality evidence.
- AP2 issue #308 is an author report about token and order state advancing before settlement.
- AP2 issue #319 is an author report about missing audience and nonce checks in a reference verifier path.
- Hacker News: PolicyLayer spending limits for AI agents supplies practitioner-reported language around transaction caps, recipient rules, duplicate prevention, and fail-closed enforcement.