Bill2Go
Scan any receipt, let a vision model itemize it, share a no-login link, and everyone claims what they ate in real time. Twenty minutes of post-meal math becomes under one minute.
// Splitting a restaurant bill is a small annoyance that everyone has. I wanted each person to pick their own items from a shared link instead of one person doing the math.
The brief
One person scans the bill in the app. Gemini Vision parses arbitrary receipt formats (printed, misaligned, even handwritten) into structured JSON line items. The app creates a shareable web session; everyone else opens the link with no install and no account, ticks what they ate, and totals with tax, tip and extra charges allocate live for everyone. Settle up, reopen later, share by QR, split across currencies.
Architecture
Three surfaces, one source of truth:
- Mobile. Expo and expo-router, Firebase auth, RevenueCat subscriptions plus server-verified rewarded ads.
- Web. Vite, React and TypeScript. Guests join sessions here with zero friction; it auto-deploys to bill2go.app.
- Backend. FastAPI with Pydantic-validated endpoints. The server owns entitlements and scan limits; clients cannot lie about what they paid for.
The AI path is the story: a brittle classical OCR pipeline gave way to OCR plus LLM text repair, which gave way to Gemini Vision with a prompt-enforced JSON schema. The current version handles any receipt format with no per-format training.
The hard parts
- Claim integrity on edits. When a shared bill re-syncs, item claims survive only if price and quantity are unchanged; any money-field change resets that item’s claims. The rule is encoded as backend tests.
- Security, checked like any other feature. Three audit rounds on my own product: rate limiting, input validation, session ownership checks, server-write-only money fields, CORS lockdown, bill-takeover guards, bounded uploads, constant-time webhook auth.
- Testing without live dependencies. 84 hermetic backend tests run against an in-memory Firestore fake, auth stubs and a fake Gemini. CI gates every push, and a push is a deploy.
Where it started
The proof of concept was SplitBill, a Flask prototype that parsed bills with an OpenAI vision model. Bill2Go is the productized successor, rebuilt for mobile with real monetization and real users.