Inspiration
Freelancers do the work first and get paid later, and "later" keeps slipping. Bonsai's data from more than 100,000 freelancers shows that 29% of invoices are paid late. Chasing those payments is unpaid, awkward work that most people put off. Meanwhile, their clients are used to paying by UPI in seconds, yet still receive PDF invoices with bank details to type in by hand. We wanted to remove every reason a client has to pay late.
What it does
- Invoice in one sentence: Type "Website redesign 40k, 2 revisions at 5k, 18% GST, due in 7 days" and AI turns it into a GST-ready invoice.
- One-tap payment page: Every invoice gets a hosted Razorpay checkout supporting cards, netbanking, wallets, and UPI. The client needs no account.
- Verified payments: Payments are confirmed on the server by checking Razorpay's signature, then confirmed again by a signed webhook. Each invoice is marked paid exactly once.
- AI follow-ups: The reminder tone escalates with how late the invoice is: friendly, then firm, then a final notice. Every email includes the amount, the invoice number, and the pay link.
- Auto-chase (Pro): A daily job drafts and sends reminders for overdue invoices.
- Client risk scores (Pro): Each client receives a predictive score $S \in [0, 100]$ based on historical payment velocity and past behavior.
- Cash-flow dashboard: See what’s outstanding, what’s overdue, what you’ve collected, your average days to get paid, and what’s expected in the next 30 days.
How we built it
- App: Next.js 15 (App Router, Server Components, Server Actions) with TypeScript and Tailwind CSS v4.
- Database and auth: Supabase Postgres and Auth. Row Level Security (RLS) on every table means each user can only ever see their own data.
- AI: Groq running
openai/gpt-oss-120bin JSON mode. Every response is validated with Zod before the app uses it. - Payments: Razorpay Orders, Checkout, and Webhooks. We secure webhook payloads using timing-safe comparisons and HMAC-SHA256 hash verification:
$$HMAC(K, m) = H((K \oplus opad) \parallel H((K \oplus ipad) \parallel m))$$
- Hosting: Vercel, with Vercel Cron for daily auto-chase and plan expiry. Everything runs on free tiers.
Challenges we ran into
- The AI model was retired mid-build: Groq retired Llama 3.3 while we were building. We switched to
gpt-oss-120band re-tested the invoice parser on real inputs. - Two payment confirmations racing: The browser callback and the webhook can both arrive for the same payment, so we made fulfillment idempotent. A payment can never be counted twice.
- Paid features had to be tamper-proof: Database column permissions stop users from upgrading their own plan from the browser. Plans change only after a payment the server has verified.
Accomplishments that we're proud of
- Building a complete, working business: sign-up, invoicing, real checkout, verified payments, subscriptions, usage limits, and platform fees are all live.
- Integrating security directly into the database architecture (RLS) rather than bolting it on afterward.
- Creating AI functionality that is genuinely useful but fault-tolerant—every output is schema-checked, and failed calls automatically refund the user's credit.
What we learned
- Payment integrations are mostly about the unhappy paths: closed tabs, duplicate events, and signatures that don't match.
- Putting a strict validation schema (like Zod) around LLM output is the fundamental requirement for making AI safe to use in production.
What's next for Duely
- Razorpay Route integration for split settlements, ensuring freelancers are paid out directly while Duely automatically collects its platform fee.
- UPI AutoPay subscriptions.
- Automated WhatsApp reminders.
- PDF invoices with GSTIN support.
- Recurring retainers.
- Team seats and collaboration for agencies.
Built With
- groq
- nextjs
- postgresql
- razorpay
- react
- supabase
- tailwindcss
- typescript
- vercel