AP2 agent payments protocol: a developer guide with 60+ partners
Google shipped the Agent Payments Protocol (AP2) with 60+ partners including Mastercard, Visa (via Worldpay), American Express, PayPal, Coinbase, Salesforce, ServiceNow, Adyen, and JCB. The spec answers one question: when an AI agent pays for something on your behalf, who signed what, and how does a card network resolve a chargeback three weeks later?
Stripe Checkout and Apple Pay assume a human clicked a button. Agent commerce breaks that assumption. If your shopping agent books a hotel at 3am while you sleep and the room has bedbugs, the dispute process has to reconstruct whether you authorized that purchase or gave the agent a blank check. AP2 answers with signed Mandates: small, structured objects that bind an agent to a user intent with cryptographic proof.
Here is the six-part breakdown developers need to wire AP2 into an agent, plus the crypto path via the A2A x402 extension that is already live in production.
Part 1: Mandates are the atomic unit
A Mandate is a JSON object the user's identity provider signs when the human authorizes a class of purchases. Every downstream payment references the Mandate by ID; merchants verify the signature, check constraints, and settle. Here is what one looks like on the wire:
{
"mandate_id": "mnd_01HX9Y2K3F4G5H6J",
"user_id": "usr_bob_42",
"agent_id": "agent_shopping_v3",
"intent": {
"category": "footwear",
"constraints": {
"max_amount": 200.00,
"currency": "USD",
"size": "11",
"brand_allowlist": ["hoka", "brooks", "new-balance"]
}
},
"valid_until": "2026-04-22T00:00:00Z",
"issued_at": "2026-04-15T14:00:00Z",
"signature": "ed25519:0xMEUCIQD..."
}
Four fields carry weight. intent is the plain-English thing the user asked for.
constraints is the machine-readable envelope: max amount, currency, brand allowlist,
category. valid_until caps how long the agent can act on the Mandate.
signature is an Ed25519 or ECDSA proof that the issuer (Google Pay, Auth0 for
Agents, a bank's identity service) actually signed the payload.
Constraints are where product work happens. A Mandate with
max_amount: 10000 and no brand allowlist is an agent-shaped blank check. A Mandate
with max_amount: 200, brand_allowlist: [...], category: "footwear" is a scoped
authorization a merchant can reason about. Treat Mandate constraint design the same way you treat
OAuth scope design: the tightest set the product allows.
Part 2: AP2 runs as an A2A extension
AP2 does not reinvent transport. It rides on Agent2Agent, the open JSON-RPC protocol Google
published in 2025 for agent-to-agent communication. An A2A task with payment intent carries the
Mandate inside the extensions.ap2 field of the envelope:
{
"jsonrpc": "2.0",
"method": "agent.task.create",
"id": "task_42",
"params": {
"recipient": "merchant-shoes.com/agent",
"message": {
"role": "user",
"parts": [{ "type": "text", "text": "Buy size 11 Hoka Clifton 9" }]
},
"extensions": {
"ap2": {
"mandate_id": "mnd_01HX9Y2K3F4G5H6J",
"settlement": "card",
"presentment_amount": { "value": 145.00, "currency": "USD" }
}
}
}
}
The recipient agent (here, the merchant's shopping agent) reads the A2A task, sees the
ap2 extension, verifies the Mandate through its PSP, and either accepts the task or
returns a signed rejection. For developers who already speak A2A, adding AP2 is one extension key
in the task envelope plus a verification call; it is not a parallel stack.
Part 3: x402 handles crypto payments today
Card rails are still negotiating chargeback liability. Crypto moved faster. The A2A x402 extension (co-designed with Coinbase, the Ethereum Foundation, and MetaMask) is production-ready and reuses HTTP 402 Payment Required to negotiate settlement:
# 1. Agent requests a resource; merchant returns 402 with payment requirements
curl -X POST https://merchant-api.example.com/v1/cart/checkout \
-H "Authorization: Mandate mnd_01HX9Y2K3F4G5H6J"
HTTP/1.1 402 Payment Required
X-Payment-Accept: x402
X-Payment-Amount: 145.00
X-Payment-Currency: USDC
X-Payment-Recipient: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7
X-Payment-Nonce: 0x9a3f...
# 2. Agent signs a USDC transfer tying the nonce to the Mandate
# 3. Agent retries with the signed transaction as X-Payment-Receipt
# 4. Merchant verifies on-chain, returns 200 with the order The flow is four steps: request, 402 with payment requirements, signed transfer tying the nonce to the Mandate, retry with the receipt. Merchants verify the on-chain transfer before releasing the resource. Settlement is USDC on Base or Optimism today; stablecoin rails keep the UX close to card purchases without floating-currency drift between signing and confirmation.
The x402 status code was in the original HTTP/1.1 spec in 1997 and sat unused for 29 years. Coinbase revived it in 2024 for micropayments; AP2 adopted it as the agent payment handshake. This is why your old client libraries already know how to parse 402 responses.
Part 4: Request a Mandate from Python
Here is what the agent side looks like in Python using the reference AP2 SDK. The agent asks the user's identity provider for a Mandate, receives a signed object, and threads it through an A2A task to the merchant:
from ap2 import MandateClient, AgentIdentity
from ap2.extensions import a2a
# Load the signing key; in production use a KMS, never a file
agent = AgentIdentity.from_kms("projects/acme/keys/shopping-agent")
client = MandateClient(agent=agent)
# Ask the user once; reuse the Mandate across many merchants
mandate = client.request_mandate(
user_id="usr_bob_42",
intent={
"category": "footwear",
"constraints": {
"max_amount": 200.00,
"currency": "USD",
"size": "11",
"brand_allowlist": ["hoka", "brooks", "new-balance"],
},
},
valid_for_hours=168,
)
# Dispatch an A2A task that carries the Mandate via the ap2 extension
result = a2a.send(
recipient="merchant-shoes.com/agent",
message="Find and buy size 11 Hoka Clifton 9 under $200",
extensions={"ap2": {"mandate_id": mandate.id, "settlement": "card"}},
)
print(result.order_id, result.receipt_url)
Two details matter. The signing key lives in a KMS (Google Cloud KMS, AWS KMS, HashiCorp Vault)
so an exfiltrated agent binary cannot forge identity. The Mandate is reusable across merchants
during valid_until; the user authorizes once, the agent shops many places. That
reuse is the whole UX reason AP2 exists; without it, every merchant re-prompts the user and the
agent experience collapses.
Part 5: Verify a Mandate from your merchant backend
The merchant side is where most of the fraud surface sits. Verification has to cover four things: signature validity, issuer trust, constraint match, and expiry. Cut corners on any of them and you ship a hole:
// Merchant side: verify the Mandate before charging
import { verifyMandate } from "@ap2/sdk";
async function handlePayment(req, res) {
const { mandate_id, amount, currency } = req.body;
const mandate = await verifyMandate(mandate_id, {
issuerAllowlist: ["google-pay", "apple-pay", "auth0-agents"],
clockSkewSeconds: 30,
});
if (!mandate.valid) return res.status(402).json({ error: mandate.reason });
// Check the Mandate constraints against the proposed charge
if (amount > mandate.intent.constraints.max_amount) {
return res.status(402).json({ error: "amount exceeds mandate cap" });
}
if (currency !== mandate.intent.constraints.currency) {
return res.status(402).json({ error: "currency mismatch" });
}
// Settle the payment through your PSP; store the chain for dispute replay
const charge = await stripe.paymentIntents.create({
amount: Math.round(amount * 100),
currency,
metadata: {
ap2_mandate_id: mandate.id,
ap2_agent_id: mandate.agent_id,
ap2_user_id: mandate.user_id,
},
});
return res.json({ order_id: charge.id });
}
Three patterns worth copying. Keep an issuerAllowlist; do not accept Mandates from
any issuer that shows up. Enforce clockSkewSeconds; agents on flaky networks send
timestamps 15 seconds in the future routinely. Store the Mandate ID, agent ID, and user ID in
your PSP metadata so a chargeback dispute three weeks from now can replay the chain without a
support engineer diving into logs.
Part 6: Build a multi-currency cart around the Mandate
Agent buyers cross currencies constantly. A user in Tokyo hands an agent a USD Mandate; the agent finds a deal at a European merchant priced in EUR. The merchant needs to know what USD cap converts to in EUR before accepting the Mandate. A currency conversion call keeps the math honest:
curl -X POST https://api.botoi.com/v1/currency/convert \
-H "Content-Type: application/json" \
-d '{"from": "USD", "to": "EUR", "amount": 145.00}' {
"data": {
"from": "USD",
"to": "EUR",
"amount": 145.00,
"result": 133.40,
"rate": 0.92,
"rate_date": "2026-04-15"
}
} Cache the rate for the lifetime of the Mandate. If the rate moves more than a configured band (typical: 2%), ask the user to re-sign. Settling against a stale rate is how agents produce support tickets.
What AP2 changes about your stack
| Layer | Pre-AP2 | With AP2 |
|---|---|---|
| Authorization | Checkout button click | Signed Mandate with constraints |
| Credential handling | Agent holds a card number | Agent holds a Mandate ID |
| Dispute resolution | Support guesses who clicked | Replay signed Mandate chain |
| Cross-merchant reuse | Re-prompt per merchant | One Mandate, many merchants |
| Crypto settlement | Ad-hoc wallet handoff | HTTP 402 via x402 extension |
| Issuer trust | PCI DSS plus fraud heuristics | Issuer allowlist and signature check |
Key takeaways
- Mandates replace bearer credentials. The agent carries a signed intent, not a card number; the merchant verifies scope before it charges.
- AP2 runs on A2A. One extension key in the JSON-RPC envelope, not a new transport; if your agent already speaks A2A, you are one verification call away.
- x402 is the crypto path in production today. HTTP 402 plus USDC on Base or Optimism, with Coinbase and MetaMask already shipping clients.
- Constraint design is scope design. Treat
max_amount, allowlists, andvalid_untilas the OAuth scopes of agent payments. - Store the Mandate chain in your PSP metadata. A chargeback three weeks out cannot dispute what you did not record.
Botoi provides the supporting endpoints an AP2 merchant flow leans on: currency conversion, country lookup, IP and VPN detection, address validation, and BIN lookup for card metadata. One API key, 5 req/min on the free tier. Browse the interactive docs or wire the MCP server into your agent so Claude or Cursor can call the same endpoints from inside the editor.
Frequently asked questions
- What is AP2 and how does it differ from A2A?
- AP2 (Agent Payments Protocol) is an open payments protocol Google announced for agent-led commerce. A2A (Agent2Agent) is the transport for agents talking to agents. AP2 runs as an extension on top of A2A so any A2A-capable agent can initiate a payment through a signed Mandate without reinventing the messaging layer. Think A2A as the highway and AP2 as the toll booth.
- Is AP2 production-ready in April 2026?
- The crypto path via the A2A x402 extension is production-ready; Google, Coinbase, the Ethereum Foundation, and MetaMask shipped it as a supported extension. Card-based flows through AP2 partners (Mastercard, Visa via Worldpay, PayPal, American Express) are in pilot through Q2 2026 with broader merchant rollout targeted later in the year. The spec is stable; the card rails are still maturing.
- What is a Mandate in AP2?
- A Mandate is a cryptographically signed object that binds an agent to a user intent: "spend up to $200 on a pair of size-11 running shoes before Friday." Merchants verify the signature, check the constraints (cap, expiry, category), and either settle the payment or decline. Mandates let an agent pay without being handed a bearer credit card number.
- Do I need AP2 if I already accept Stripe Checkout?
- Not for human-initiated checkouts; Stripe Checkout handles those. You need AP2 when an AI agent is the buyer. The difference is intent capture and authorization: a human clicks "Pay" and authorizes in the moment; an agent needs to carry a pre-authorized Mandate that proves the human approved this class of purchase. Without it, fraud disputes cannot resolve who authorized the charge.
- How does AP2 handle fraud and chargebacks for agent purchases?
- Every AP2 payment ties back to three signed objects: the user Mandate (what the human authorized), the agent delegation (which agent is acting), and the merchant acceptance (what was charged). Payment networks can replay the chain during a dispute and see who signed what. This is the piece Visa and Mastercard insisted on before signing up; existing chargeback rules assumed a human clicked, and without signed Mandates the liability model breaks.
Try this API
Crypto Price API — interactive playground and code examples
More guide posts
Start building with botoi
150+ API endpoints for lookup, text processing, image generation, and developer utilities. Free tier, no credit card.