An onboard till that keeps selling with no network
Cabin crew sell from a trolley, with a queue of passengers and no network. We built an onboard sales system where being offline is the normal case, not the error. The working demo won the contract.
The situation
Cyprus Airways cabin crew sell food, drinks and duty-free from the trolley. The system runs the catalogue, discounts, card and cash payments, receipts, trolley stock and the count at the end of each flight. It runs on handheld payment terminals, with a web back office for stock and reports. We delivered it with ThinkCRM, and it goes live in October 2026.
What made it hard
The till must open, sell, count, close and recover for up to 16 hours with no network. Every sale made in the air must land on the ground exactly once, and no passenger can ever be charged twice.
What we did
- Started from proven code: the till extends the point-of-sale engine from ThinkCRM’s gym platform, with new parts built for the cabin.
- Designed the offline sync as one append-only ledger. Each sale carries an ID that the device creates, and the server stores each one once, so a sale sent five times is recorded once.
- Signed every upload with a key for each device, and made the server answer record by record, so one bad record never rejects a whole batch.
- Wrote prices, discounts and money handling as one shared library that the device and the server both use, so the aisle and the ground always agree on what a basket costs.
- Kept the card out of the till. Payment runs in the terminal’s own payment app. While a card result is unclear, the till blocks every other payment for that basket, cash included, because treating an unclear result as a decline is how a passenger gets charged twice.
- Charged in euros, with prices shown in euros, pounds and dollars from daily ECB rates.
- Tested the offline design on paper before building it, and closed every conflict and gap that review found before the first line of sync code.
- Backed it with automated tests across the API, the back office and the device.
Before and after
What we would do differently
Our first terminal build carried only 64-bit libraries, and the older 32-bit terminals refused it with a misleading error. The fix took minutes. The build check that now fails when the 32-bit part is missing took longer, and mattered more.
Built with
Expo · React Native · NestJS · PostgreSQL · Payment terminals
Ready to build something great?
Tell us what’s breaking, or what you need built. You talk to the engineer who does the work.
