Inspiration Freelancing still runs on trust gaps. Clients pay upfront and pray the freelancer delivers, freelancers deliver and chase invoices for weeks, and manual approvals kill momentum. We kept asking: what if payment wasn't tied to time, but to verified quality?
Inspiration came from that frustration — what if an AI could read the original brief, review the actual deliverable like a real reviewer, and release money instantly only when the work is really good? No human in the middle, no awkward "approve it" messages, just work → verify → pay.
AutoMilestone was born from the idea that AI verification + programmable payouts can make freelancing boring in the best way: transparent, fast, and fair to both sides.
What it does AutoMilestone is an AI-powered freelancer payment automation platform built around milestone-based escrow.
A client creates a project with 1+ milestones (title + USD amount). The client funds it via PayPal Orders API, so money is held escrow-style. A freelancer opens the project by ID, submits their deliverable_text, and clicks "Run AI Verification".
Our Google Gemini 2.0 Flash agent reviews the submission against the original brief and milestone title. It returns a structured score (0-100) with feedback and missing items. If the score is ≥75, the backend automatically fires a PayPal Payout to the freelancer, creates a payment record, and marks the milestone paid — no manual approval needed. If it's below 75, the freelancer gets exact revision feedback and can resubmit.
Everything is visible live: client dashboard, freelancer dashboard, and a polling Live Payment Feed that updates every 10 seconds when webhooks confirm PAYMENT.PAYOUTS-ITEM.SUCCEEDED.
How we built it We built a production-ready monorepo from scratch:
Backend — Node.js 18+ + Express 4 + SQLite:
better-sqlite3 with auto-migrated schema (projects, milestones, payments) REST APIs for projects, milestones, verify, PayPal orders, payments, and webhooks geminiService calls Gemini 2.0 Flash with a strict raw-JSON-only prompt ({approved, score, feedback, missing}), enforcing score>=75 → approved server-side with parse-error fallback paypalService handles OAuth token (cached), Orders create/capture, and Payouts via native fetch with timeouts render.yaml for one-click Render deployment Frontend — React 18 + Vite + Tailwind v3:
Dark SaaS theme (bg-gray-950, indigo/emerald accents), Inter font React Router v6: /, /client, /freelancer with persistent navbar Core components: AIVerifier (idle → loading → approved/rejected), CreateProject, MilestoneCard, PayButton (@paypal/react-paypal-js), PaymentFeed Custom useToast hook + skeleton loaders + double-submit guards Security hardening (post-hack build):
helmet + PayPal-safe CSP, CORS allowlist, 256kb body cap, rate-limits (general/writes/sensitive) express-validator for UUIDs, emails, amounts, length caps; idempotency (409 if already paid); webhook signature verification; 15s PayPal / 30s Gemini timeouts; prompt marked as untrusted data to mitigate injection; optional X-API-Key gate Challenges we ran into Node 24 + better-sqlite3 native build failure: Took 2 days to realize v11 had no prebuilt binary for Node 24 — every install failed with gyp ERR!. Fixed by upgrading to better-sqlite3@^12.2.0 with prebuilt binaries. Gemini JSON discipline: Gemini loves to wrap JSON in markdown fences. We added stripping + strict JSON.parse in try/catch, plus a fallback (score:0, "AI parse error") so a bad output never triggers a payout. Financial integrity risks: A double-click or webhook spoof could have caused a double payout. We added 409 already-paid checks, transaction-wrapped verify+pay, and PayPal webhook signature verification before flipping pending → completed. CSP vs PayPal SDK conflict: Helmet's default CSP blocked PayPal's JS SDK. We scoped CSP explicitly for paypal.com / paypalobjects.com while keeping 'self' as default. Quota + UX balance: Gemini quota errors and slow PayPal calls needed graceful fallbacks, 20s frontend timeouts, and disabled buttons to prevent double-verify. The "AI service temporarily unavailable" state had to look intentional, not broken. Accomplishments that we're proud of End-to-end automation in one flow: POST /api/projects → PayPal fund → submit → verify → payout → payment row → live feed — all verified with a 12/12 security smoke test (valid 201, bad-email 400, bad-UUID 400, large-payload 413, CSP present). A true revision loop, not just approve/reject: AI returns actionable missing[] bullets; freelancer revises and resubmits without losing the milestone. Production-style engineering: Rate-limits, validation, timeouts, token cache, redacted logs, prepared statements, graceful shutdown — not just a demo CRUD. Polished frontend: 103-module Vite build, confetti-flash on approval, live pulsing payment feed, dark SaaS polish in ~4 days. Shipped monorepo: Backend + frontend + render.yaml + README + SECURITY.md, pushed and deployed-ready on GitHub. What we learned LLMs are not deterministic — don't trust them with money. We learned to enforce thresholds server-side, validate JSON shape, cap output lengths, and always have a safe fallback (no payout on parse error). Prompt injection is real. Treating user deliverables as data between tags, not instructions, is essential even for a hackathon project. SQLite + prepared statements is surprisingly powerful for a hackathon — WAL mode, busy timeout, foreign keys, and zero-config deployment beat writing auth + Postgres in 48 hours. Security can't be an afterthought. Headers, validation, and idempotency took us a full day, but they turned a demo into something we could actually demo to investors. PayPal Sandbox is a second codebase. Token expiry, webhook IDs, payout permissions, and live vs sandbox hosts each broke us once — checklists save hours. What's next for AutoMilestone Real user auth: Replace the simple API-key gate with per-user JWT/OAuth so clients only see their projects and freelancers only theirs. Production money: Switch from Sandbox to Live PayPal, add dispute/human-review fallback when AI is borderline (70-80), and add idempotency keys on payout retries. Scale the data layer: Migrate SQLite → Postgres for multi-instance, add analytics (AI score trends, on-time rate, payout latency). Better AI: Ensemble verification (Gemini + image/PDF/file attachment review), project-specific rubrics, and multi-language brief support. Marketplace: Public project board, freelancer profiles, multi-currency escrow, invoicing/tax exports, and a mobile app. AutoMilestone started as "AI verifies the work. PayPal sends the money." — next is making it the default rail for fair, instant freelance payments.
What's next for AutoMilestone
Built With
- axios
- cors
- dotenv
- express-rate-limit
- express-validator
- express.js
- github
- google-gemini
- helmet
- javascript
- netlify
- node.js
- paypal
- react
- render
- rest-api
- sqlite
- tailwind-css
- uuid
- vite

