All case studies
FrontendFrontend Engineer

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.

Coffeemania: Pay & Order at the Table

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

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.

Stack

  • React
  • TypeScript
  • Effector
  • Patronum
  • Vite
  • SCSS Modules
  • SBP (NSPK)
  • Vaul
  • Swiper
  • CloudTips