Inspiration
Freelancers and small agencies send invoices through PayPal and then spend weeks chasing late payments. The reminders feel awkward, clients often can't pay in full, and negotiating a discount or payment plan by hand is slow. We wanted an assistant that handles the follow-up politely, understands why the client is late, and sets up a real payment arrangement inside PayPal — not a mock.
What it does
PulsePay syncs a merchant's PayPal invoices, ranks them by urgency with an explainable reason, and lets an AI agent follow up in the owner's tone. When a client can't pay in full, the agent negotiates within the owner's policy:
- Early-payment discount — native PayPal rule when available, with a void-and-reissue fallback
- Staged installment plan — installment 1 sent now, the rest scheduled
- PayPal Pay Later — when PayPal offers it to the client
A deterministic policy guard checks every proposal before it can touch money. Anything outside the rules goes to the owner's approval queue. Once accepted, the executor creates or reissues real PayPal invoices, and verified webhooks flip the dashboard row to PAID in real time. Only the demo clock is simulated.
How we built it
- Frontend: Next.js 16, TypeScript, Tailwind CSS, AG Grid
- Backend: Next.js route handlers, Zod policy schemas, Supabase Postgres + Realtime
- PayPal: Agent Toolkit plus raw REST for Invoicing v2, Orders v2 (Pay Later), and webhooks
- AI: Gemini as the primary model with a Groq fallback, plus an intent gate for prompt injection and disputes
- Hosting: Vercel
Every agent and PayPal action is written to an audit event log. The executor is idempotent: retrying an accept never creates a duplicate invoice or installment.
Challenges we ran into
- The Agent Toolkit's default OAuth token omits the Invoicing scope, so invoice calls returned 403 until we requested scopes explicitly.
- PayPal Sandbox returned 500 for native conditional discount rules, so we added a void-and-reissue fallback.
- PayPal sends
INVOICING.INVOICE.PAIDfor partial payments too. We had to classify full vs partial and never resolve a conversation on a partial payment. - Webhook verification needs every transmission header, not just the transmission ID, and dedupe had to be atomic.
- Payer links are returned by
send_invoice, notget_invoice, so we rebuild them from the invoice ID after a reload. - Pay Later depends on the buyer's country. We verified it with a US Sandbox buyer and made the agent say "if PayPal offers it to you."
- Seeding creates nine real PayPal invoices in about 20 seconds, which required explicit serverless timeouts.
What we learned
- Money-moving agents need deterministic guardrails, not prompt instructions.
- PayPal's API has sharp edges: scopes, payer links, partial payments, and country-dependent features.
- Idempotency and audit logs are not optional when an AI can change an invoice.
- A real Sandbox integration is far more convincing than a mock, even with its limitations.
What's next
- Production onboarding for real merchants
- Email and SMS reminders
- Smarter negotiation using payment history
- Multi-currency and multi-business support
- Analytics on recovered revenue
Built With
- ag-grid
- gemini
- groq
- next.js
- paypal
- paypal-agent-toolkit
- paypal-invoicing-api
- paypal-orders-api
- paypal-webhooks
- postgresql
- react
- supabase
- tailwind-css
- typescript
- vercel
- zod