Profile
Fatih
Profile

Fatih

Contact
  • fatihaljabar@gmail.com
  • fatihaljabar.com
Languages
🇬🇧 English
🇮🇩 Indonesia
Home
About
Achievements
Projects
Contact
Back

SplitBill

Split shared bills without the awkward math. Photograph a receipt, OCR reads the items and prices, decide who ate what, and share the result through one short link.

Tech Stack :
GitHub Live Demo
SplitBill

Timeline: August – August 2026

Overview

SplitBill solves the awkward part of splitting a shared bill: figuring out who owes what. Photograph a receipt, on-device OCR reads the items and prices, everyone marks what they had, and the app hands out one short link with the exact breakdown. No login, no install, no manual math.

It's a real, production product, live at splitbills.site, built for the Indonesian market with bilingual support (Bahasa Indonesia + English) and OCR tuned specifically for Indonesian receipt formats.

The Problem It Solves

The original prototype worked, but it cut a corner that quietly broke four of its own promises: it never stored anything on a server. Every bill's data, including items, prices, and participant names, was packed into the URL itself.

PromisedWhat Actually Happened
Short share linksLinks were enormous, since the entire bill was encoded in the URL
Private bills (others can't see your amount)Anyone holding the link could read the full payload
Creator sees who's paidPayment status never crossed devices; it lived only in the browser that set it
Auto-delete after 24 hoursNothing to delete. The data was the link, and expiry was only checked client-side, easy to bypass

Fixing this meant a real backend: a database to hold bill state, short codes that resolve server-side, and privacy enforcement that can't be defeated by editing a URL, all while keeping the interface, flow, and OCR accuracy pixel-identical to the version already validated with real users.

Key Features

  • Receipt scanning: camera or gallery upload, OCR (tesseract.js, tuned ind+eng) running entirely client-side. Photos never leave the device.
  • Review before it counts: every scan lands on an editable review screen first. Nothing enters a bill unchecked.
  • Flexible splitting: evenly, by item, by percentage, or custom amounts, with one item shareable across any subset of people.
  • Fees handled correctly: tax, service charge, discounts, and extra fees as a percentage or fixed amount, with optional rounding.
  • Exact Rupiah, always: the sum of every participant's share equals the grand total exactly, even when division leaves a remainder.
  • Short share links: splitbills.site/s/AB12CD34, valid 24 hours, with QR code and WhatsApp sharing built in.
  • Public and private modes: public bills show everyone the full breakdown; private bills send each participant only their own amount, enforced server-side, with an optional personal link per participant.
  • Cross-device payment tracking: participants mark themselves paid from their own phone, and the bill creator sees it update in real time.
  • Auto-expiry: every bill is deleted 24 hours after creation. Not configurable, by design. This is a privacy guarantee, not a setting.
  • Tech Stack

    LayerChoice
    FrontendVue 3.5 + TypeScript, Vite 7, Tailwind CSS 4, vue-router 4
    StatePlain reactive() composables, no Pinia; the app's state shape doesn't need it
    BackendHono + @hono/node-server, one process serving the API and the built frontend
    DatabaseMySQL 8 via Drizzle ORM
    OCRTesseract.js (ind+eng trained data), assets self-hosted
    TestingPlaywright for end-to-end, Node's built-in test runner for unit tests
    ToolingBiome for lint and format

    How It Works

    1. Scan or enter manually. The camera flow requires HTTPS (getUserMedia won't run without it) and runs OCR fully in-browser. No image is ever uploaded for processing.
    2. Review, always. OCR output, including items, prices, quantities, tax, service charge, and total, populates an editable screen. The user confirms or corrects before anything is saved.
    3. Assign and split. Each item can be assigned to any subset of participants; the split method (even, by item, percentage, custom) determines each person's share, with rounding handled so shares always sum to the exact total.
    4. Mint a short link. The finished bill is written to the database and issued a short, unpredictable code. Public bills expose the full breakdown to anyone with the link; private bills are gated server-side, per participant.
    5. Share and settle. Recipients open the link, find their name, copy the creator's bank account, and mark themselves paid, visible back to the creator immediately, from any device.
    6. Expire. 24 hours after creation, the bill and everything in it is deleted server-side.

    Privacy by Construction

    • Receipt photos are processed on-device and never uploaded anywhere.
    • OCR assets are served from the app's own domain, with zero third-party CDN requests during scanning.
    • No analytics, no tracking cookies, no third-party scripts of any kind.
    • Bill data lives on the server only for the 24-hour window, then is deleted outright.

    Testing

    Two layers, each proving something the other can't:

    • Unit tests (node --test, no browser) cover the money logic in the shared calculation module, specifically the rounding edge cases where a naive split could lose or invent a single Rupiah.
    • End-to-end tests (Playwright) drive a real browser through the full flow: create a bill, assign items, mint a link, then open that link in a separate browser context simulating a different device with none of the creator's local state, and mark it paid. The suite also asserts directly on API payloads that private bills never leak other participants' amounts, that payments for non-participants are rejected, and that short codes are unique and unpredictable.

    The e2e suite runs against the production server build rather than the dev server, because the two properties actually worth proving, money computed server-side and payment status crossing devices, don't exist without a real backend in the loop.

    Links

    • Live app: splitbills.site
    • Source: github.com/fatihaljabar/splitbill