A till that keeps working when the internet doesn't
Sepiring POS
An Android point-of-sale for restaurants that runs fully offline, prints to a thermal printer, and syncs afterwards.
The problem
A restaurant can't stop serving because the connection dropped. But a purely offline till is no use either if the owner can never see the numbers from elsewhere. Both had to be true at once.
The user journey
- Staff sign in with a PIN, open a shift, and start taking orders — all from a database inside the tablet itself.
- Orders are paid in cash or split across methods, then the receipt and kitchen ticket print to a thermal printer over Bluetooth.
- The shift closes, and the system works out how much cash should be in the drawer.
- Customers scanning the QR code on their table order from their own phone, and that order lands in the same queue.
What was built
A React app inside Capacitor with two Kotlin plugins I wrote: one for ESC/POS printing over Bluetooth Classic, one for native SQLite. Behind it sits PostgreSQL and an Express API I run myself rather than a third-party service.
Architecture
The hard part
Bluetooth thermal printers aren't supported by Web Bluetooth, so there was no browser shortcut — the native plugin had to be written. And printing can't be called working until it's tested against real hardware.
The outcome
- The full till flow runs completely offline: sign in, open shift, order, pay, print, close, daily report.
- Printing verified on a physical thermal printer, not just an emulator.
- QR self-ordering is live in production, and a second restaurant was created through the dashboard by the owner themselves.
- App updates ship without going through an app store, and never apply mid-shift.
What isn't finished
There's no manager-approval flow yet for cash variance, discounts, or voids — anyone signed in can do all three. Refunds are whole-order only, not per item. Both are recorded as the next piece of work.
My role
Product, architecture, app, native plugins, backend, and operations.
- Recorded by
- Ihsan Nugraha
- Checked
- 6 Aug 2026, 17:17 WIB
- How to verify
- Click any URL on this page
- Recorded by