尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Four AI agents that quote a job, bill it through PayPal, chase the payment, and release the work only when PayPal says it's paid. Your clients' AI assistants can hire you too.
Built for the PayPal AI Hackathon. Sandbox only. No real money moves.
Live demo: https://branch-pay.onrender.com (free Render instance: the first load after a quiet spell can take about a minute while it wakes up).
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.
Branch Pay hands that loop to a crew of AI agents, and keeps a human on every decision that moves money.
Client (a person in the dashboard, or their AI assistant over MCP)
|
v
[Scoper agent] --> fixed-price quote. Price cap enforced in code; injected instructions reported and ignored
|
APPROVE <-- a human (bill in full, or 50% deposit first), or a spending limit the human set
|
v
[Biller agent] --> creates + sends a PayPal invoice (tool calling; it cannot choose amounts or recipient)
|
| not paid yet? [Collector agent] --> writes a reminder, PayPal emails it (on its own, max 3)
v
PayPal --> client pays (webhook INVOICING.INVOICE.PAID, polling as a fallback)
|
|-- deposit paid --> [Builder agent] builds the site; client gets a WATERMARKED preview
| balance paid --> final files unlocked + downloadable
'-- paid in full --> [Builder agent] builds and unlocks the site
REFUND (human only) --> money back through PayPal, the deliverable locks again
Until PayPal confirms payment, the deliverable answers HTTP 402 Payment Required with a machine-readable PayPal payment link.
| What it does here | |
|---|---|
| PayPal Invoicing API v2 | Create, send, remind, cancel, read status, record payments and refunds. The deposit plan uses native partial payments (allow_partial_payment + minimum_amount_due) where PayPal offers them, and otherwise a deposit invoice plus a balance invoice (PayPal limits partial payments by the merchant's country). Hand-written REST in src/paypal.ts, so every call is visible. |
| PayPal Payments API v2 | Refunds money the client paid through PayPal (/v2/payments/captures/{id}/refund). |
| PayPal Webhooks | INVOICING.INVOICE.PAID / CANCELLED trigger an instant check. Signatures verified with verify-webhook-signature when PAYPAL_WEBHOOK_ID is set. |
| PayPal OAuth 2.0 | Client-credentials token, cached until near expiry. |
| Gemini (Vercel AI SDK) | Scoper: structured quote + a list of injection attempts it ignored. Biller: tool calling. Collector: reminders whose tone fits how long the client has waited and what payment unlocks. Builder: the HTML deliverable. |
| Model Context Protocol | /mcp/<workspace> is an MCP server (Streamable HTTP). A client's AI assistant can request_quote, get_job and list_jobs. It cannot approve, pay or refund. |
| AG Grid | The Ledger: every quote, invoice and payment with filters, sorting, quick search, a totals row and CSV export. |
| Render | One-click deploy from render.yaml. |
Open Connect an AI agent in the app to get your workspace's MCP URL, then:
claude mcp add --transport http branch-pay <your MCP URL>npx @modelcontextprotocol/inspector, choose Streamable HTTP, paste the URL.Then ask: "Use Branch Pay to get me a quote for a one-page website for my bakery. Bill Jane Doe at <sandbox buyer email>." The job appears in your pipeline. You approve; the agent can then fetch the PayPal pay link for its human, and the deliverable link once PayPal reports payment.
People stay in charge on both sides: the agency approves, the buyer's human pays. Optionally set AUTO_APPROVE_UNDER_USD to let small jobs run end to end within a limit you chose in advance (a spending mandate, enforced in code).
| Guardrail | How |
|---|---|
| The AI never chooses who is billed or how much | The Biller's tools accept only a note and payment terms. Amounts, deposit and recipient come from the approved quote on the server. |
| Hard price cap | Any quote is scaled under MAX_QUOTE_USD in code, rounding included (npm test). |
| Humans own the money moves | Nothing is invoiced until a person (or their pre-set limit) approves. Refund and cancel have no AI tool at all. |
| Prompt injection can't reach an action | The client text is untrusted data. The Scoper reports injected instructions, but safety never depends on that: the text can only influence a quote that code clamps and a human approves. Try Try a prompt injection in the app. |
| Webhooks are a nudge, not the truth | A webhook only makes the server re-read the invoice from PayPal, so a forged event can't unlock anything. |
| No reminder spam | The Collector writes; code decides when, max 3 per payment. |
| Idempotency | The job id is the PayPal-Request-Id, so a retry never creates a second invoice. Refunds use one key per payment. |
| AI-written HTML is sandboxed | Served with Content-Security-Policy: default-src 'none' in a sandboxed iframe. Everything in the UI is HTML-escaped. |
| Public-demo hygiene | Each browser gets its own workspace; quotes are rate limited per visitor and per day; sandbox only (the server refuses the live PayPal API). |
| Crash-safe | A job interrupted mid-step goes back to a retryable state on restart. |
You need Node 20+.
https://www.sandbox.paypal.com.git clone https://github.com/shrestha-droid/branch-pay
cd branch-pay
npm install
cp .env.example .env # then fill in the keys
npm start
Open http://localhost:3000. Run npm test for the payment-rule tests.
Click Deploy to Render above, paste your PayPal sandbox and Gemini keys when asked, and you get a public URL. Then, optionally, add a sandbox webhook in the PayPal developer dashboard pointing at https://<your-app>.onrender.com/api/paypal/webhook with INVOICING.INVOICE.PAID and INVOICING.INVOICE.CANCELLED, and set its id as PAYPAL_WEBHOOK_ID.
On Render's free plan the instance sleeps after 15 minutes idle and its disk is not persistent, so demo jobs are cleared on restart.
AUTO_REMIND_MINUTES=2), or click Send reminder now.src/config.ts settings, price cap, limits, sandbox-only guard
src/paypal.ts PayPal OAuth, Invoicing, Payments (refunds), webhook verification
src/agents.ts Scoper, Biller, Collector, Builder
src/mcp.ts MCP server for buyers' AI agents
src/store.ts jobs in data/jobs.json, plus the pure payment rules
src/server.ts HTTP routes, webhooks + polling, auto-reminders, rate limits, the 402 gate
src/*.test.ts npm test: price cap, deposit, payment transitions, reminder schedule
public/index.html the web UI (plain HTML + AG Grid from a CDN, no build step)
render.yaml Render Blueprint
MIT. See LICENSE.