Inspiration
Small businesses lose hours chasing late invoices and guessing their cash position. Customers do not pay on the due date: some pay early, some are weeks late. A simple "total owed" number hides that, so the owner cannot tell which money is realistic and which invoices need attention first.
What it does
- Reads the invoices of a PayPal Sandbox merchant (PayPal Invoicing v2) and shows what is owed in a separate card per currency (EUR, USD and GBP are never mixed), with late invoices and each one's chance of being paid within 30 days.
- Forecasts income for the next 8 weeks. It learns how fast each customer actually pays and runs 2,000 simulated futures to give an expected amount per week and a likely range. Invoices that are far later than a customer's habit are treated cautiously.
- Lets you talk to an assistant: "Which invoices are late?", "Remind my late customers", "Prepare an invoice for Lumen Architects, [email protected]: 1 item, Floor plan review, 60 EUR, due in 14 days".
- Turns those requests into proposal cards. Nothing leaves the app until a person reviews the exact content and clicks Send.
How Claude and PayPal are used
- PayPal Invoicing v2 (Sandbox): the source of truth. The app lists, reads, searches, creates, sends and re-reads invoices through the PayPal API, and uses PayPal's own outstanding balance rather than guessing.
- Claude (Anthropic API, tool use, model
claude-sonnet-5-5): the reasoning layer. Claude calls read tools (list invoices, cash-flow forecast, receivables aging, list proposals) and two proposal tools (propose an invoice, propose a reminder). Claude receives a minimized view of the data: IDs, amounts, dates and statuses, never customer names or emails. Before a reply is shown, any PayPal ID in it is replaced with the invoice number the owner sees. In Sandbox, PayPal writes the reminder email itself, so Claude is not offered a custom note.
The human approval boundary (our main design decision)
The agent proposes. A person decides. Claude has no tool that sends, confirms, pays, cancels or deletes anything, and a test checks that. Beyond that:
- What is sent is exactly what was reviewed: confirmation recomputes the payload hash and rejects any change.
- A double click or two browser tabs send once.
- If PayPal's answer is lost after sending, the proposal is marked "unverified" and the app looks the invoice up in PayPal by its reference before any retry, so a lost answer does not turn into a second invoice.
- Missing, refunded or inconsistent data is blocked for manual review instead of being guessed: the app shows an error and clears old figures rather than leaving stale numbers on screen.
- Sandbox writes are off by default and need an explicit local opt-in. The model gets no access to customer free text.
How we built it
Python 3.11+, FastAPI, SQLite, httpx, the PayPal Invoicing v2 REST API and the Anthropic Claude API. Clean layers (core / persistence / ui) are enforced by an automated architecture test. 505 automated tests, lint, formatting and strict type checks run in CI on Python 3.11 and 3.12. Built with AI coding assistants (Claude Code).
Challenges
Making an AI agent useful without making it dangerous around money. We spent most of our effort on the failure cases: lost responses, partial payments, refunds, incomplete PayPal pagination, stale data and untrusted text.
Accomplishments
A working assistant where every external action requires explicit human approval, with duplicate-send protection and honest handling of unknown states. Verified end to end against a real PayPal Sandbox merchant with Claude: it read invoices in three currencies, prepared reminders and a new invoice as pending cards, and on one approval created, sent and read back that invoice through the PayPal API.
What we learned
Safety for financial agents lives in the tools and the approval step, not in the prompt.
Limitations (honest scope)
- One PayPal Sandbox merchant and app; it shows only what that app can see, not a complete accounting ledger.
- Sandbox only: no real money, no production merchant onboarding.
- Localhost only, no user login. It is designed to be run on your own computer.
- No webhooks or continuous sync: invoices are read on demand.
- A built-in offline demo (synthetic data and a fake PayPal) lets anyone run it without accounts; it is clearly labelled and is not proof of the PayPal integration.
What's next
Webhook-based sync, merchant onboarding with proper authentication, payment reconciliation and role-based approvals.
Built With
- antropic-claude
- claude-api
- fastapi
- httpx
- javascript
- openai-chatgp
- paypal-invoicing-api
- paypal-sandbox
- python
- sqlite