Inspiration

Freelancers and small agencies don't lose money on the work. They lose it on the loop around the work: writing the quote, sending the invoice, chasing late payments, and deciding when it's safe to hand over the files. Hand over too early and you might never get paid. Hold on too long and the client walks.

And the buyer is changing: more and more, the "client" asking for a quote will be someone's AI assistant. We wanted an agency that AI agents could run and hire, without any agent ever being trusted with the money.

What it does

A client describes what they need, either in the dashboard or through their own AI assistant. Then:

  1. Scoper agent turns the request into a fixed-price quote. A hard price cap is enforced in code, and the Scoper reports any instructions hidden in the request that it ignored.
  2. A human approves it: bill in full, or ask for a 50% deposit first. (Optionally, a spending limit set in advance auto-approves small jobs.)
  3. Biller agent creates and sends a real PayPal invoice with tool calls. The deposit plan uses PayPal's native partial payments where they're available, and otherwise sends a deposit invoice plus a balance invoice.
  4. Collector agent chases the unpaid invoice on its own, with reminders whose tone fits how long the client has waited, sent through PayPal's reminder API.
  5. Builder agent starts the moment PayPal reports payment (webhook, with polling as a fallback). After the deposit, the client sees a watermarked preview; when the balance is paid, the final files unlock for download.
  6. A human can refund with one click. Money goes back through PayPal and access is revoked.

Agentic commerce: Branch Pay is also an MCP server. A client's AI assistant (Claude, ChatGPT, any MCP client) can request a quote, track the job, and fetch the PayPal pay link for its human. It can't approve, pay or refund. People stay in charge on both sides.

Until PayPal confirms payment, the work answers HTTP 402 Payment Required, with a machine-readable PayPal payment requirement an agent can act on.

The Ledger (AG Grid) is the receivables desk: quick views for what's awaiting approval or payment, aging buckets that show how long each amount has been owed, reminder counts, a totals row that follows whatever view and filters are on, and CSV export. Tick several unpaid rows and press Remind selected, and the Collector agent writes each client a reminder that PayPal sends.

How we built it

  • TypeScript + Express, plain HTML front end. AG Grid runs the ledger: column groups, external filters for the quick views, custom cell renderers and class rules, a pinned totals row recomputed from the filtered rows, row selection for bulk reminders, and CSV export, themed to match the app. Deployed on Render from a one-click Blueprint.
  • PayPal Invoicing API v2: create, send, remind, cancel, partial payments, record payments and refunds. Payments API v2: refund PayPal captures. Webhooks with signature verification. OAuth 2.0 client credentials. Hand-written REST in one file, so every request is easy to inspect.
  • Gemini via the Vercel AI SDK: structured output for the Scoper and Collector, tool calling for the Biller, generation for the Builder. A fallback chain across three Gemini models keeps the agents answering when one model is overloaded.
  • Model Context Protocol (official TypeScript SDK, Streamable HTTP) for buyers' agents.
  • Pure, tested payment rules: deposit amount, price cap, every payment-state transition, and the reminder schedule are pure functions covered by npm test.

The rule that shaped everything: the AI proposes, the code enforces, a human approves

We built on two 2025 papers on securing LLM agents. Design Patterns for Securing LLM Agents against Prompt Injections argues that once an agent has read untrusted input, that input must not be able to trigger consequential actions. Defeating Prompt Injections by Design (CaMeL) separates control flow from data flow. In Branch Pay:

  • The Biller follows plan-then-execute: one forced tool call drafts the invoice, then the code sends it. Its tool takes only a note and payment terms. Amounts, deposit and recipient flow from the approved quote in server state, so nothing the model reads can redirect money, whether that's a client's text, a buyer agent's request, or an injection.
  • The Scoper reads untrusted text, but its output is clamped by code and approved by a human before anything happens.
  • The Builder gets context minimization: it sees the request, has no tools, and its HTML is served under a strict Content-Security-Policy in a sandboxed iframe.
  • Refund and cancel have no AI tool at all.
  • Webhooks are a nudge, not the truth: every webhook triggers a fresh read from PayPal, so a forged event can't unlock anything.
  • The job id is the PayPal-Request-Id, so retries never double-invoice.

Challenges we ran into

  • Trusting an LLM near money. The obvious design is to hand the model a full invoicing toolkit. We went the other way: every money field lives in server state, and each agent gets only the narrowest tools its job needs.
  • Partial payments. Deposit → preview → balance → final meant modelling payment state carefully. Then the live sandbox told us partial payments aren't available in our merchant country, so the Biller now falls back to a deposit invoice plus a balance invoice, read by the server as one payment. The transition logic is a pure function with tests for both shapes, including a client paying everything at once.
  • Rounding. Our own test caught that a $1 minimum per line item could push a scaled quote $2.51 over the cap. Now the code takes the excess off the biggest line.
  • Letting outside agents in safely. Giving buyers' AI agents an MCP interface meant deciding exactly what they may do. They can ask and look; only people approve, pay and refund.
  • Public demo hygiene. A hosted demo needs per-visitor workspaces and rate limits on AI calls, so judges don't see each other's jobs and nobody can burn the quota.
  • Overloaded models. On the live site the main Gemini model often answered "high demand" or hung, and a quote once took 47 seconds. Each agent now gives a model a short first try, falls back to the next model, and rests a failing model for 15 minutes. Quotes came down to 2 to 5 seconds.
  • Our own bugs, found live. Testing on the real PayPal sandbox caught an invoice field PayPal rejected and a lighter model that answered in text instead of calling its tools. The second one led us to fix the Biller's tool order in code, and on the night of the deadline an overloaded model stranding drafted invoices led us to cut the Biller to a single AI step, with the code doing the send.

Accomplishments that we're proud of

  • The full loop, from request to quote, invoice, reminder, deposit, preview, balance, delivery and refund, runs on real PayPal sandbox APIs.
  • An AI assistant can hire the agency over MCP, and the money still only moves when a person pays a PayPal invoice.
  • A safety design grounded in current research, that you can attack live with the Try a prompt injection button.
  • HTTP 402, finally used for what it was designed for.

What we learned

  • The best place for AI in payments is everything around the money: scoping, writing, chasing, building. The money itself belongs to code and people.
  • PayPal's Invoicing API does more than most people use: partial payments, reminders, cancellations and webhooks are all built in.

What's next for Branch Pay

  • Change orders: the client asks for more, the Scoper prices the change, a new invoice unlocks it.
  • A client portal, so clients accept a quote and pay without the agency in the loop.
  • Signed spending mandates for buyer agents (in the spirit of AP2), so an assistant can pre-authorize a budget its human signed.
  • Non-copyable previews, rendered as screenshots on the server, and deliverables beyond websites.

Tools: which AI, and how

  • Google Gemini (gemini-flash-latest, falling back to gemini-flash-lite-latest and gemini-3.8-flash, via the Vercel AI SDK) runs all four agents: structured JSON output (Scoper, Collector), tool calling (Biller), and HTML generation (Builder).
  • Model Context Protocol lets external AI assistants call Branch Pay as a tool provider.
  • Claude (Anthropic) was used as a coding assistant while building.

Try it

Built With

Share this project:

Updates

Submission history