One price preview equals one final charge, in every outlet, every time.
The problem
Fifteen outlets, three systems that didn’t talk to each other, and a customer standing at a counter waiting for someone to check a spreadsheet. Coupons were paper. Billing was per outlet. Anyone who wanted a number for the whole network waited eight days for it.
What was built
- One Node.js API serving a Flutter customer app and a React dashboard used by store owners, franchisees and super admins: 286 REST endpoints, 71 data models, around 91,000 lines.
- A pricing engine as the single source of truth for revenue: member and non-member rates, weekday and weekend, happy-hour windows, coupons that pro-rate, and a quote/commit contract so every price preview equals the final charge.
- Payments end to end: gateway orders and signed webhooks, in-app wallet, cash and split collection, refunds, store ledgers and franchise billing across the network.
- 170 test suites with money-conservation guards in CI.
Result
- 25,000
- 200,000+
- 4.7
- Up 10–15%
What I learned
The feature was never the hard part. The hard part was one number meaning the same thing in every outlet, on every screen, at every step, and staying that way after the next change. That is also, it turns out, the whole problem a multi-outlet business has with money.