Inspiration
Freelance work usually ends with an awkward question: what exactly am I paying for? Deliverables change across revisions, feedback lives in chat threads, and the invoice arrives weeks later as a list of amounts. When a client asks which version of the work a line covers, nobody can point to it.
I wanted an invoice where every line can answer that question by itself.
What it does
DeliverPay is a responsive web workspace for a freelancer and a client. It keeps one record from delivered work to payment:
- Scope & price. The freelancer defines deliverables, amounts and acceptance criteria.
- Evidence. Delivered work is saved as versioned evidence. Any edit creates a new version and resets earlier acceptance.
- AI review. Gemini checks the evidence against each criterion and labels it
supported,missing,contradictedorunverifiable. Every quote it returns must exist word-for-word in the evidence, or the server rejects the review. The freelancer edits the proposal privately before sharing it. - Client decision. The client requests a specific change or accepts one exact evidence version.
- Invoice approval. Only accepted work can be invoiced. The freelancer reviews the recipient, total, currency and due date, then explicitly approves creating and sending the invoice.
- PayPal invoice. The invoice is created and sent through the PayPal Invoicing API (sandbox). The server reconciles its status from PayPal and verifies webhook signatures with PayPal before trusting an event.
- Proof. After invoicing, the accepted snapshot never changes. Each invoice line opens its own proof (evidence, review, acceptance), which can be exported as a PDF receipt.
The core rule: AI proposes, people decide. The model cannot accept work, change an amount or send a bill. Every money action requires a human click and is authorized on the server.
How we built it
- Frontend: React + TypeScript + Vite, responsive for a freelancer on a laptop and a client on a phone.
- Backend: Go with Clean Architecture (domain → application → adapters). PayPal, Gemini, HTTP and SQL code live only in adapters, wired in one composition root.
- Database: PostgreSQL. Each project is a versioned aggregate updated under row locks. Money is stored as integer minor units.
- AI: Gemini through a strict JSON schema. The server validates criterion coverage and exact citations independently of the model, and records the model and prompt version on every review.
- PayPal: Invoicing API v2 (create, send, get, search) with OAuth, plus webhook signature verification and event de-duplication.
- Testing: Go tests with the race detector, PostgreSQL integration tests, and Playwright two-role browser tests (freelancer on desktop, client on mobile).
- Demo video: Remotion with a Three.js voxel identity. The music is original and synthesized in code.
Challenges we ran into
- Payments and app records are not one transaction. If PayPal times out after creating an invoice, retrying blindly could bill a client twice. DeliverPay stores the operation intent first, treats a timeout as an unknown outcome, and reconciles by invoice ID or invoice number. It never re-creates the invoice blindly.
- AI provider availability. Gemini models sometimes returned HTTP 503/500 or timed out. I added a bounded fallback: an allowlisted next model, a shared 50-second deadline, a per-model cooldown, and provenance showing which model answered. A failure stays visible, and the freelancer can write the review by hand.
- Keeping acceptance honest. A client must never accept a review they didn't see. Each published review gets its own ID, acceptance is bound to both the evidence version and the review ID, and any stale action is rejected.
- Not overstating results. The UI clearly separates simulated payment, manually marked payment, a real sandbox buyer payment and a verified webhook. A browser redirect is never treated as proof of payment.
Accomplishments that we're proud of
- Every invoice line traces back to the exact evidence version and decision behind it, even after the work is edited later.
- In a native evaluation on 12 synthetic cases, Gemini returned valid, fully cited reviews for 10. Every criterion it answered matched the proposed label. The two failures were provider timeouts, and both were shown to the user rather than hidden.
- A real Gemini review ran end-to-end through browser → Go → Gemini → PostgreSQL in a two-role test.
- No model can trigger billing or acceptance, and the server, not the UI, enforces this.
What we learned
- Payment integrations are mostly about the unhappy paths: timeouts, duplicates, stale tabs and webhooks that arrive late.
- AI is most useful when its output can be checked. Requiring exact quotes turned "trust the model" into "verify the model".
- Versioning is what makes a record trustworthy. Without it, "accepted" means nothing once the work changes.
What's next for DeliverPay — Every Invoice Backed by Proof
- Complete a hosted demo with a verified buyer sandbox checkout and signed webhook delivery.
- Milestone and partial invoices, so one disputed deliverable doesn't block the rest.
- Inspectable file and image evidence (screenshots and design files) with bounded AI extraction.
- Testing with real freelancer/client pairs to measure whether invoice disputes actually go down.
Demo note
The video shows a real, saved Gemini review (0:19), then a scripted walkthrough in an isolated workspace with a simulated review checklist and simulated payment, so every step can be repeated on camera. PayPal sandbox invoicing is implemented in the code. Buyer checkout and signed webhook delivery are not shown in the video.
Built With
- cloudflare-tunnel
- docker
- gemini
- go
- nginx
- paypal-invoicing-api
- paypal-sandbox
- playwright
- postgresql
- react
- remotion
- three.js
- typescript
- vite
Log in or sign up for Devpost to join the conversation.