Inspiration

Freelancers and small businesses lose time and goodwill chasing late invoices. It's repetitive and awkward, so it gets put off, and cash flow suffers. But handing an AI the power to email customers about money is risky: one wrong message to a client can damage a relationship. I wanted an agent that does the tedious chasing while a human keeps control of anything that actually contacts a customer.

What it does

GetPaid Copilot lets you work with PayPal invoices in plain language.

  • Draft: "Draft a $450 invoice for Acme for website maintenance, due in 7 days" creates a real draft invoice in PayPal.
  • Ask, then approve: "Send it" does not send anything by itself. The AI queues the request, and a person approves it in an Approval inbox. Only then does PayPal send the invoice.
  • Chase: for an unpaid invoice, the AI writes a polite, specific payment reminder with the amount and due date. It also waits for approval.
  • Track: a live AG Grid dashboard shows every invoice and flips to PAID, with a popup, when the customer pays through PayPal checkout.
  • Transparent AI: click any action chip in the chat to see the exact tool and arguments the model chose.

How I built it

  • PayPal: the PayPal Invoicing API v2 in the sandbox (create drafts, send invoices, send reminders, list invoices, read status), with PayPal OAuth 2.0 client credentials used server-side so secrets never reach the browser.
  • AI: Google Gemini function calling drives an agent loop. The model chooses which PayPal tool to call and with what arguments, and writes the reminder text. Per-call timeouts and automatic fallback across several Gemini models keep it responsive when one is overloaded.
  • Safety by design: tools are split into "run now" (read, list, create draft) and "queue for approval" (send invoice, send reminder). The model can only queue the second group. The server calls PayPal for those only after a human approves.
  • App: Next.js, React, TypeScript and Tailwind CSS, with AG Grid for the invoice table, a rate limit on the AI endpoint, and hosting on Render.
  • I used an AI coding assistant (Claude) to help plan, write and debug the code.

Challenges I ran into

  • PayPal blocks sending invoices to customers inside India. The error (INR_FOREIGN_CURRENCY_BLOCKED) came back under a misleading HTTP 406 status, so I had to read the details array to find the real cause, then recreate my sandbox accounts as US accounts.
  • A new sandbox app returned 403 NOT_AUTHORIZED until I enabled the Invoicing feature on that app.
  • Gemini models were sometimes overloaded (503). Requests stalled, so I added timeouts, automatic model fallback and a friendly "model is busy" message.
  • A production-only Next.js behavior froze the approval queue. A GET route that only read a file was prerendered at build time, so the Approval inbox showed empty on the hosted app even though it worked locally. Forcing those routes to run per request fixed it.
  • Free hosting limits. The free Render instance sleeps and has little CPU, so I reduced polling and capped request sizes.

Accomplishments that I'm proud of

  • A complete loop on a public URL: the AI drafts, a human approves, PayPal sends, the customer pays, and the dashboard shows PAID.
  • A safety model where a wrong or manipulated AI answer cannot contact a client by itself, because the risky actions can only be queued.
  • An agent whose work is visible: you can inspect every tool call and its arguments.

What I learned

Designing an agent around what it is allowed to do matters as much as what it can do. Splitting tools into "run now" and "queue for approval" made the product safer and easier to demo. I also learned how much production behavior can differ from local development, how to make an app resilient to a flaky model (timeouts, fallback, friendly errors), and how to read PayPal's error details instead of trusting the status code.

What's next for GetPaid Copilot

  • PayPal webhooks instead of polling, for instant status updates
  • A durable database for approvals, instead of local disk
  • Multi-user accounts, so each business has its own invoices and approval queue
  • Scheduled "chase" runs that queue reminders for overdue invoices automatically, still behind human approval

Built With

  • ag-grid
  • ai-agents
  • function-calling
  • google-gemini
  • nextjs
  • paypal
  • paypal-invoicing-api
  • paypal-sandbox
  • react
  • render
  • tailwindcss
  • typescript
Share this project:

Updates

Submission history