A payment firewall for AI agents. One signed proof checks every agent payment against what the user meant before PayPal moves money, then decides who pays when a purchase goes wrong.
AI agents can now spend money, but payment mandates only prove a user approved a scope ("up to $50 of clothing"), not that the cart matches what they meant.
Hidden text on a product page can tell an agent to buy a gift card for a stranger. It's under the cap, so it goes through. In our benchmark, spending caps alone let 92.4% of attacks pass.
When an agent buys the wrong thing within limits, nobody can show whose fault it was, so the merchant pays by default.
What it does
A payment firewall between any AI agent and PayPal, exposed as an MCP server. The agent never holds PayPal credentials and can never sign for the user.
Before payment: the user's request becomes a typed, signed Intent Spec. Every cart is checked against that spec, the spending policy, the catalog, the merchant's quote, and a ledger of where every value came from. A hijacked cart is blocked before any PayPal order exists.
The proof: a passing cart gets an Ed25519-signed Intent-Satisfaction Proof. Its hash goes into the PayPal order's custom_id. Funds are held, the checkout is re-checked, and only then captured. If the merchant adds an extra after the hold, the hold is voided.
After payment: when a dispute arrives, the proof is verified and a fixed procedure decides fault (user, agent, manipulation, merchant or fraud), then contests the claim, accepts it, or flags fraud.
Design rule: LLMs propose, deterministic code decides. No model output can approve a payment.
How we built it
PayPal: Orders v2 (intent: AUTHORIZE, custom_id), Payments v2 (capture, void), the Disputes API and webhook verification. Tested end to end on the real PayPal sandbox: hold, proof hash, capture and void all worked.
Agents: a remote MCP server with seven tools. The agent requests a mandate, the user signs it in the console, then the agent shops. Works with Claude Code, Claude, ChatGPT, Cursor and VS Code.
AI: Claude compiles requests into specs, flags suspicious carts (it can only escalate, never approve) and maps complaint text to an order attribute. Every AI step has a deterministic fallback.
Stack: Python, FastAPI, the MCP SDK, Ed25519, SQLite and a plain HTML/JS console. Hosted on Render, API tested with Postman, plus a live Channel3 catalog, AG Grid tables and AG Studio analytics.
AgentDispute-Bench: our own benchmark of 150 normal tasks, 119 attacks and 200 disputes with known fault.
Challenges we ran into
PayPal only allows custom_id before authorization, so we reordered the flow: check → create order → sign proof → attach hash → hold → re-check → capture.
A hijacked agent would lie about where its data came from, so the proxy records the source of every value itself instead of trusting the agent.
Our India sandbox merchant couldn't receive USD (UNSUPPORTED_PAYEE_CURRENCY), and INR isn't supported, so the demo uses a US sandbox merchant.
Accomplishments that we're proud of
Attack success drops from 100% with no defense (92.4% with caps) to 0% when users decline flagged payments.
Fault decisions reach 0.926 macro-F1, and wrong-item purchases drop from 38% to 8.7% with under one question per task.
The full PayPal sandbox flow works for real, and 99 automated tests pass.
These results come from a scripted agent on our own benchmark; the README says exactly what was and wasn't run.
What we learned
A spending limit isn't intent. You need proof of what the user actually meant.
The most useful record is one that is checked before payment and reused as evidence after it.
Keeping AI out of the final yes/no decision made the whole system easier to trust and test.
What's next for IntentProof
An independent red team to attack it.
Real dispute data to tune the question-asking thresholds.
Running a real Claude agent across the full benchmark.
Proposing the proof as an extension to agent payment protocols like AP2.