Receipts Prove Payment. Nothing Proves Authorization.
Every machine payment protocol handles the forward flow. None of them bind a receipt back to what was authorized.
Your AI agent just paid for something. You pull up the receipt. It says: settlement successful, transaction hash 0xabcd..., timestamp 1726531200, status "success."
What it doesn't say is whether you authorized that payment. Or how much you said the agent could spend. Or which merchants you approved.
The receipt proves the money moved. It's silent on whether the money should have moved.
The obvious assumption is that the receipt should carry authorization details. But receipts in traditional payments don't do this either. Your Visa receipt shows the merchant, the amount, and the date. It doesn't reference the credit limit or the cardholder agreement that authorized the charge.
The difference is that traditional payments have a human in the loop who can call the bank. Agent payments at scale don't have that phone call.
So the question isn't "why don't receipts carry authorization?" It's "what happens when receipts are the only audit trail, and they're missing a leg?"
What MPP's receipt tells you
Stripe's Machine Payments Protocol defines the Payment-Receipt header with four fields: method, reference, status, and timestamp. That's it.
Payment-Receipt: method=tempo,
reference=abc123...,
status=success,
timestamp=1726531200The receipt confirms settlement. The reference is a transaction hash you can verify on-chain or against the payment method's ledger. But there's no field that names the agent, references an authorization, or records the constraints the user set.
MPP's credential (the payment proof the agent sends) does carry an optional source field, a DID identifying who is paying. That tells you who. It tells you nothing about what they were allowed to do. An agent holding a source DID can pay any challenge, for any amount, to any recipient.
The protocol's extension mechanism (§6.1) explicitly allows adding parameters to the receipt: "Method-specific extensions MAY add additional parameters." The slot is there. Nobody has filled it.
What x402's receipt tells you
x402's offer-receipt extension defines a signed receipt with six fields: version, network, resourceUrl, payer, issuedAt, and optionally transaction.
The amount is missing on purpose. Section 5.2 of the spec omits it to reduce correlation risk. A third party examining the receipt can see that a payer accessed a resource, but not how much they paid. That's a deliberate privacy tradeoff.
But it also means you can't verify what was charged from the receipt alone. The offer (the server's price quote) is a signed artifact. The receipt doesn't reference it. You can't prove "I was quoted $0.10 but charged $5.00" without separately retaining the offer and hoping both parties agree on which offer applied.
The spec knows this matters. Three separate sections name the downstream use case:
Section 1: "enable dispute evidence, auditing, and advanced payment flows for both human users and AI agents." Section 5.5: "Signed receipts can serve as evidence in dispute resolution or for auditing purposes." Section 8: "signed offers and receipts provide the building blocks for dispute workflows, including scenarios involving automated purchasers (agents)."
The building blocks exist, but the binding between them doesn't.
x402's PaymentPayload does have an extensions field (Record<string, unknown>) that could carry authorization data. The facilitator's hook system (beforeVerify, afterSettle) could process it without changing the core flow. The infrastructure is ready. The artifact isn't defined.
What ACK has that the others don't
ACK-Pay's v2 proposal adds two fields to the receipt under a single ack object: ack.agent (the agent's DID) and ack.grant (the SHA-256 of the authorization grant's compact serialization).
The grant is a signed JWT from the user. It carries the constraints: max amount, currency, allowed recipients, expiry, and a cryptographic pin to the agent's key. When the payment service issues a receipt, it hashes the grant and records that hash. A third party can later verify that the receipt references a specific, unmodified grant.
This gives you both legs. The grant says what was authorized. The receipt says what happened. The content-hash binding proves they're connected.
The cost: ACK is the only protocol with this structure, and the v2 proposal hasn't shipped. The grant model and receipt binding are still in RFC. But the design shows what the other protocols would need to add.
The two-piece fix
Every protocol needs the same two additions. The shapes differ by protocol, but the pattern is identical.
An authorization scope artifact. A signed object from the principal (the user behind the agent) that carries spending constraints: max amount per transaction, cumulative budget, allowed recipients, allowed networks, validity window. A signature that proves the user issued it.
For MPP, this could travel as a JWT in a new authorization auth-param on the credential, alongside the existing source DID. The credential already supports unknown parameters (§4.2: "Unknown parameters MUST be ignored by clients"), so the addition is backwards-compatible.
For x402, this could travel in PaymentPayload.extensions["agent-authorization"], the existing extension mechanism. The facilitator would verify the principal's signature during its verification step.
A receipt binding. A content-hash reference from the receipt back to the authorization scope that was in effect when the payment settled. The server records the hash at settlement time, attesting "I saw this authorization when I processed this payment." A forged authorization won't match the hash the server recorded.
For MPP, an optional authorization parameter on the Payment-Receipt header. The receipt already allows method-specific extensions. Implementations are already adding fields like challengeId to receipts because the core spec doesn't carry enough context.
For x402, offerRef and authorizationRef fields on the signed receipt. The offerRef binds the receipt to the offer terms. The authorizationRef binds it to the principal's authorization. Both are SHA-256 content hashes, so they don't leak the contents of the underlying artifacts.
That preserves x402's privacy-minimal design.
Neither addition requires changes to the core payment flow. Both are optional parameters that degrade gracefully. Receipts without them work exactly as they do today.
The cost: these are proposals, not shipped features. Adoption requires each protocol's maintainers to accept the extension. The authorization artifact format needs to be standardized per protocol, or at least agreed upon by enough implementations to be useful.
Three problems, one gap
Audit trails, constraint enforcement, and dispute evidence look like separate features. They're three faces of the same structural gap: receipts don't bind back to authorization.
A compliance team auditing agent payments needs to verify that each transaction fell within the user's constraints. Today they'd need to reconstruct that from application logs, if the logs exist. An authorization binding in the receipt makes the audit mechanical.
A runtime policy engine that enforces spending limits needs to reference what the user authorized. Today that's application-level logic with no protocol artifact. An authorization scope artifact makes the constraints portable across implementations.
A dispute evidence layer needs both the authorization and the receipt, bound together. Today, only ACK's v2 proposal provides that binding. The other protocols would need to add it before dispute evidence can work.
Three use cases. One prerequisite. The receipt needs to point back to the authorization.
Sources
- MPP Issue #359: Dispute evidence extension — dispute evidence proposal for Machine Payments Protocol
- x402 Issue #3500: Dispute evidence for agent-initiated payments — dispute evidence proposal for x402
- ACK Issue #217: Dispute evidence for agent payments — dispute evidence proposal for Agent Commerce Kit
- RFC: ACK-ID + ACK-Pay v2 — the grant model and receipt
ackbinding - Agent Commerce Has No Chargeback Code — the reason code gap in agent commerce
- Agent Commerce Needs Evidence, Not a Reason Code — the dispute evidence architecture built on authorization bindings
Built by Trio, a fintech-native engineering partner helping teams build the next generation of financial technology and infrastructure.
Subscribe to Ledger Drift for high-signal insights into how modern fintech is built, from systems to code to teams.