Inspiration
AI agents now shop and pay for people. Sometimes a buyer later tells PayPal: "I never approved that." The merchant has no proof of what the buyer allowed the agent to buy. So the merchant loses the dispute, and the money. We built the merchant's side of the fix.
What it does
Palisade sits at the merchant's checkout and keeps signed proof of every agent purchase.
- An agent shops. The demo store has a shopping agent that runs on Claude. Any outside agent can shop through the store's MCP endpoint.
- The buyer signs a mandate. A mandate is a short signed record: the items, the price limit, the merchant, and the expiry. It follows the shape of AP2, the Agent Payments Protocol.
- Palisade checks the agent. It checks the agent's signature, the merchant's policy, and the mandate. No signed mandate, no payment.
- PayPal takes the payment. The PayPal order carries the mandate's ID and hash in
custom_id. The proof travels with the payment. - Disputes get an answer. When a buyer opens a dispute, Claude picks one of the four answers PayPal allows: fight, message the buyer, offer a partial refund, or refund in full. Rules in code check the pick. A refund or an offer always waits for the merchant.
- The evidence is filed. To fight, Claude writes the response from the order's facts only. Code checks every sentence against the record. Palisade files it with PayPal, with the signed mandate as a PDF.
- The merchant sees it all. One console shows orders, disputes, agents, analytics, and a check of every payment against PayPal's own records.
How we built it
PayPal (sandbox)
- Orders v2: create and authorize the order.
custom_idholds the mandate's ID and hash. - Payments v2: capture and refund.
- Vault v3: the buyer links a PayPal wallet once.
- Webhooks: every event is signature-checked, stored, and processed by a background job.
- Disputes v1: send a message, make an offer, accept the claim, escalate, and provide evidence with a PDF.
- Shipment Tracking: tracking is added to the payment.
- Transaction Search: every paid order is compared with PayPal's records.
AI (Claude Opus 5.5, through the Anthropic API)
- The shopping agent, with eight tools. It cannot pay without a signed mandate.
- The dispute decision. Claude picks; code allows only valid picks.
- The dispute response. Code removes any sentence that names an ID, amount, date, or hash the record does not hold.
- A custom agent on the analytics dashboard that explains orders, disputes, and mandates.
AG Grid and AG Studio
- The console's tables use AG Grid.
- The analytics page is an AG Studio dashboard. It compares agent orders with orders people placed.
Stack: Python, FastAPI, React, TypeScript, PostgreSQL, Azure Container Apps, Cloudflare. 287 API tests and 16 web tests.
Challenges we ran into
- PayPal accepts the mandate as evidence only after a dispute becomes a claim. Palisade escalates first, then files.
- A new payment can be disputed only after PayPal's reports list it. That can take three hours.
- PayPal's sandbox has no reviewer. A simulator plays that part, and the screen says so.
- Our background worker once stopped quietly for two days. It now restarts itself.
Accomplishments that we're proud of
- The full loop works on PayPal's own records: the order, the payment, and the dispute all point to the same signed mandate.
- Claude decides, code sets the limits, and PayPal carries it out. In our tests, no buyer message tricked the system into a refund.
- Anyone can verify a mandate with a public key, without the console.
What we learned
- PayPal wants most disputes settled early, by a message or an offer. A fight is not always the right answer.
- A mandate proves the buyer approved the purchase. It says nothing about a damaged item, so sometimes the right answer is a refund.
- An AI agent needs hard limits in code. A prompt alone is not enough.
Built With
- ag-grid
- ag-studio
- anthropic-api
- azure-container-apps
- claude
- cloudflare
- docker
- fastapi
- github
- github-actions
- mcp
- paypal
- paypal-disputes-api
- paypal-orders-api
- paypal-payments-api
- paypal-transaction-search
- paypal-vault
- paypal-webhooks
- postgresql
- python
- react
- react-router
- tailwindcss
- typescript