Inspiration

Small merchants spend hours on back-office money tasks: refunding a broken order, paying the photographer, invoicing a wholesale customer. An AI agent with PayPal access could do this in seconds, but one hallucinated amount or one convincing "CEO" email and the money is gone. We wanted an agent that is useful and safe enough that a shop owner would actually switch it on.

What it does

Countersign reads the shop inbox and drafts the right PayPal action for each message (refund, payout or invoice). It also shops: when the stock system says a supply is running low, the agent proposes a purchase from a human-vetted supplier catalogue, paid through a PayPal checkout order. It never executes anything itself. Each action becomes a decision card showing the amount, the counterparty, the agent's reasoning and a PASS/FAIL list of checks. A signed-in approver approves or rejects with one click (their identity comes from the login, not a text box), and a blocked card says why in plain English. Approved cards execute once against PayPal, idempotently. Everything lands in a tamper-evident audit log.

How we built it

  • PayPal REST APIs (sandbox): OAuth2, Payments v2 (captures, refunds), Payouts v1, Invoicing v2 (create + send), Orders v2 (checkout orders for agent-proposed supplier purchases, with the supplier as payee and the owner paying at PayPal; also demo seeding). Every money call carries a PayPal-Request-Id, so retries never double-pay.
  • Claude (Anthropic Messages API, tool use) is the planner when an API key is set. It has read-only tools (lookup_order, list_vetted_payees, list_supplier_catalog) and propose tools. There is no execute tool. In the demo video Claude (Opus 5.5) runs live against the PayPal sandbox. Without a key a built-in deterministic planner drafts the same kinds of proposals, so anyone can run it offline, and a recorded Claude run (docs/claude_run.json) replays through the same checks.
  • Boundary rules in plain Python: per-action limits, daily outflow cap, human-vetted payee list, a human-vetted supplier catalogue (SKU, supplier, price, max quantity), refund ≤ refundable amount per PayPal, duplicate detection.
  • A verifier checks the agent's claims against PayPal (does this capture belong to that order? does the captured amount match?) and checks that its evidence quote appears verbatim in the customer's message.
  • Approvers sign in with local accounts (salted scrypt hashes, created on the command line). The approver's identity comes only from the server-side session. The approval digest is an HMAC-SHA256, under a server key (data/audit.key, mode 600, never committed), over card, shown digest, approver, auth method and time; it is in the audit log, whose entries are HMAC-signed with the same key. Rewriting who approved fails verify-audit even if every later hash is recomputed, unless the editor also holds the key file.
  • Approval is bound to a SHA-256 digest of exactly what the human saw. Rules and claims are re-checked with fresh PayPal data right before execution.
  • A zero-dependency Python web UI and a hash-chained audit log, with 62 tests. Every Claude run is recorded and can be replayed offline through the same checks. It runs fully offline with a mock PayPal, so judges can try it in a minute.

Challenges

Keeping the safety properties out of the prompt. Time-of-check versus time-of-use: two refunds that are each fine can together exceed a capture, so we re-check at execution.

Accomplishments

In the demo, Claude refuses a social-engineering "CEO" payment and an over-claimed refund on its own, and the rules in code would block both anyway, whatever the model says. The legitimate refund, payout and invoice go through with one human click each. Supply purchases (in the code, not in the video) need two signatures: the card, then paying at PayPal.

What we learned

The best place for an LLM in payments is drafting and explaining. Money movement belongs behind deterministic checks and a signature.

What's next

Webhook-driven status updates, dispute responses (PayPal Disputes API), multi-approver thresholds, and packaging as a PayPal Agent Toolkit / MCP-server policy layer that other agents can sit behind.

Demo

The video runs against the PayPal sandbox (Refunds, Payouts, Invoicing; captures checked via Payments v2). Narration is the author's own voice.

Built With

  • anthropic-claude
  • paypal
  • paypal-payouts
  • paypal-rest-api
  • python
  • tool-use
Share this project:

Updates

Submission history