Coffeemania: Pay & Order at the Table
A web app behind the QR code on the table: guests see their bill, pay it through Russia’s Faster Payments System in their own banking app, redeem loyalty points and tip the waiter — and since 2024 order from the menu straight to the table.
Under NDA — happy to walk through the architecture and the code in a call.

Outcome
- 28
- days from first commit to a production environment in July 2022
- 93
- tracker tasks closed, most during the QA month before table ordering launched
- 2,5
- years of development in production — July 2022 to February 2025
Product screens

Paying the bill: the table from the QR code, the POS bill with points redeemed, the Faster Payments bank picker with the remembered bank on top, and the payment confirmation offering a tip.

Ordering at the table: the menu with its category bar, the dish card in a bottom sheet with cooking options, and the cart with modifiers and comments.

Loyalty: sign-in by phone number and SMS code, and in the cart a points slider, unavailable dishes in their own block and the discounted total.

The full bill in a bottom sheet and the payment waiting screen: until the bank confirms, a countdown runs and another bank can be chosen.
The business problem
In a restaurant the guest waits for the waiter twice: to order and to pay. The brief was a service with nothing to install — point the camera at the table’s QR code and see your bill from the POS right away. Payment goes through the Faster Payments System in any bank, with loyalty points earned or redeemed and a tip for the waiter. All of it on the guest’s phone, in any browser including Safari and its quirks, and with no mistakes in the totals: this is money.
My role
Frontend engineer on the product from the first commit through 2025: the MVP took four weeks — in July 2022, from init to a production environment. I then grew the product for two and a half years: loyalty sign-in, tips, remembering the guest’s bank, the move from Preact CLI to Vite and, in 2024, self-ordering at the table with a menu, cart and modifiers. I closed 93 tracker tasks, most of them during a month-long QA pass before table ordering launched.
The solution
React, TypeScript and Vite, with state split into Effector domain models — table, bill, cart, menu, payment, banks, user — and gates tying data loading to screens. The QR code opens a link with the table number; the table and cart IDs sync with the address bar through effector-storage, so a reload or a shared link keeps the state, and after 40 idle minutes the table session resets. For payment the backend issues a Faster Payments link, the bank list comes from the NSPK directory, and the chosen bank opens by deep link straight in its app; the last bank is remembered and listed first. The status screen polls the backend until the bank confirms, shows a payment countdown and, on success, opens the CloudTips tipping widget. Loyalty sign-in uses an SMS code or a call with the last digits of the number; the resend timer survives a page reload, and the repeat auth check signs the phone with HMAC-SHA512 and a salt so the number never travels in the clear. The points slider recalculates the total instantly. Table ordering has a category bar that follows the scroll and dish cards in bottom sheets with photos, modifiers, cooking options, nutrition facts, allergens and Markdown descriptions; the cart merges identical items, moves stop-listed dishes into a separate block and clears it in one tap. Yandex Metrica goals track sign-ins, points redemption and tips.