Inspiration
AI agents pay for content and APIs on their own over x402, and those payments are final. An agent that pays for a teaser instead of the promised report, for content swapped after the offer, or for a page that hides instructions aimed at the agent, has no way back. The x402 community has an open issue on exactly this (dispute evidence for agent payments, #3500, and delivery conformance, #3678). PayPal has run buyer protection for 25 years. We wanted to see what that looks like when the buyer is an agent.
What it does
Recourse implements x402's own buyer-protection scheme, auth-capture, on PayPal:
- Offers commit to the SHA-256 of the content and a plain-language promise, signed by the publisher.
- The owner connects PayPal once (Vault) and sets a mandate; the agent's purchases are charged with nobody present, cent purchases come from a prepaid balance.
- Settlement happens only after the publisher signs what it delivered. Swapped content is never charged.
- The agent verifies every delivery before it reaches the language model: the hash in code, and two bounded questions to a decision model (Jev): does this deliver the promise, does it contain instructions aimed at an agent. A pure policy function decides.
- Claims carry the signed receipt as evidence. Recourse adjudicates independently and refunds through the PayPal Refund API, also for cent purchases.
- Every receipt and decision is a signed, hash-chained log entry anchored in Bitcoin via OpenTimestamps. A browser verifier checks it without trusting us.
- The same evidence protects honest publishers: false claims fail, payouts go out via PayPal Payouts after the protection window, and PayPal disputes are answered automatically with the delivery proof.
How we built it
TypeScript monorepo. Hono services (Recourse facilitator, publisher gate, research agent), Next.js web app with AG Grid for the publisher dashboard. PayPal: Vault v3, Orders v2 (merchant-initiated vault charges), Refunds, Payouts, Disputes, Webhooks, and the PayPal Agent Toolkit (read-only refund checks by the agent). AI: Jev (TypeSafe) via OpenRouter for decisions with probabilities; Gemini for picking sources and writing the cited answer. Ed25519 + RFC 8785 canonical JSON for signatures, OpenTimestamps for anchoring. 135 tests, including end-to-end runs over HTTP.
Challenges
- Agent payments are tiny and many; PayPal charges are not. Cent purchases come from a prepaid balance, and refunding them meant a partial refund of the original top-up capture.
- The obvious fraud vector: a gate that lies about what it delivered. Settlement now requires a publisher-signed delivery attestation, so a lying gate becomes provable evidence instead of a free pass.
- A decision model gives probabilities, not verdicts. Turning them into money moves needed explicit thresholds, a "judges disagree" outcome and quarantine when the judge is unavailable.
- Sandbox details: a German personal test account first asked for a card and an SMS code that never arrives; disputes can only be opened through the buyer UI, not the API.
- Cloud Run gives no CPU while idle, so payouts and anchoring are triggered by a small external heartbeat.
Accomplishments
- A provable bait-and-switch is stopped before any money moves.
- Every refund is a real PayPal refund the owner can see, including five-cent purchases.
- "The model judges, code decides": no language model ever calls a payment API.
What we learned
- x402 already has the right shape for buyer protection (auth-capture); what was missing was a rail with real refunds and disputes. PayPal fits that slot naturally.
- Keeping the model out of the money path makes the system easier to trust and to test: every money rule is a pure function with a unit test.
- Hash commitments plus signed receipts turn "the content was bad" from an opinion into evidence that a third party, or PayPal's dispute process, can check.
What's next
Propose the PayPal binding and the delivery-conformance evidence upstream to x402 (#3678); move funds to PayPal's platform model so balances never sit with Recourse; publisher reputation from contested claims.
Built With
- ag-grid
- docker
- gemini
- google-cloud-run
- hono
- jev
- next.js
- node.js
- openrouter
- opentimestamps
- paypal-agent-toolkit
- paypal-rest-api
- paypal-vault
- pglite
- postgresql
- react
- typescript
- vitest
- x402
Log in or sign up for Devpost to join the conversation.