Skip to main content
Case Study

Restaurants On Web — A Multi-Tenant Ordering Platform for Independent Restaurants

About the Client

Restaurants On Web is a multi-tenant ordering platform built for independent restaurants and takeaways. Each restaurant gets its own branded storefront — on a subdomain or its own custom domain — with online ordering, delivery and collection, promotions and payments, all running from one platform.

The proposition is straightforward. Independents have been paying a substantial share of every order to aggregator platforms, and the customer relationship that comes with it belongs to the aggregator rather than to the restaurant.

The Challenge

Challenges Faced

Independent restaurants losing a significant share of each order to aggregator commission.

No direct ordering channel, so the customer relationship sits with the platform rather than the restaurant.

UK VAT on food is genuinely complicated — the same item is taxed differently depending on whether it is hot, and whether it is eaten in, collected or delivered.

Delivery pricing that has to reflect real distance and coverage rather than a flat guess.

Promotions that need to combine, exclude one another and expire, without ever producing a wrong total.

Restaurant staff needing to work orders on the floor rather than at a desk.

Every restaurant needing to look like itself, not like a platform tenant.

Our Approach

Our Strategy

1

Multi-tenant architecture, enforced rather than intended

Per-restaurant tenancy with a tenant-scoped database layer that injects the restaurant filter automatically
Route handlers cannot reach the raw client, so a query that forgets its tenant is rejected rather than quietly returning another restaurant data
A CI check verifying every restaurant-scoped table carries a tenant id, with exemptions requiring a written justification
Tenant resolution by subdomain, custom domain or path, so a restaurant can trade under its own name
2

Pure engines for the parts that must be right

Cart, promotions and delivery built as pure functions — plain data in, plain data out, no clock reads and no I/O
Money held as integer pence throughout, never floating point
A UK VAT engine covering dine-in, hot and cold takeaway, reduced and zero rates, computed after order-level discounts
A promotions rule language with priority, exclusivity, codes and date windows, which reports why a promotion was not applied
Postcode-based delivery coverage, where out-of-area is a normal answer rather than an error
3

Payments as a marketplace

Stripe Connect Express onboarding, so each restaurant is paid directly
Platform commission taken as an application fee on subtotal, excluding delivery and VAT
Card, Apple Pay and Google Pay through the Stripe Payment Element, with 3DS handled
Webhook processing keyed on the Stripe event id, so a replayed event does no work twice
Cash and pay-on-collection handled alongside card, with refunds reconciled back to the order
4

Front of house and back of house

A point-of-sale mobile application for staff working orders away from a desk
An order state machine, so an order can only move in the ways it is allowed to
Seven themeable storefront packs with per-restaurant overrides, driven by CSS custom properties rather than forked code
A static-page CMS and Google Reviews integration for each storefront
The Impact

Transformational Results

Restaurants trading under their own brand and domain, with the customer relationship staying with them.

Commission set by the platform rather than by an aggregator, and taken transparently as a fee on subtotal.

VAT calculated correctly across dine-in, collection and delivery, with a breakdown retained so any receipt can be reconstructed.

Tenant isolation enforced by the data layer and checked in CI, rather than relying on every developer remembering.

Promotions that combine and exclude predictably, with the reason for a rejected promotion available rather than silent.

Payments, refunds and payouts reconciled automatically, including when Stripe redelivers an event.

Why It Matters

Ordering platforms are easy to build badly. The parts that decide whether one can be trusted — money, tax, tenant isolation and payment reconciliation — are exactly the parts that are invisible when they work. Building the cart, promotion and delivery logic as pure functions means those rules can be tested exhaustively without a database or a clock. Enforcing tenancy in the data layer, and verifying it in CI, means the most serious failure a multi-tenant platform can have is prevented structurally rather than by care.

If you are building a multi-tenant product, or paying a platform for a customer relationship that should be yours, we would be glad to talk about what it would take to own it.