How We Built Restrofi: A QR-Based Ordering System with AI Upselling
Published by the Navtechy engineering team
Restrofi started as a simple question: why are restaurants still using slow, expensive POS systems when every diner already has a smartphone in their pocket?
We set out to build a QR-based ordering system that would eliminate the wait, reduce POS fees, and — crucially — use AI to increase average order value. Here is how we did it.
You can see the live product at restrofi.com.
The Problem
Restaurants face three compounding problems:
- Slow ordering. Waitstaff take orders manually. During peak hours, wait times spiral. Diners leave.
- High POS fees. Traditional POS systems charge monthly licensing, hardware rental, and per-transaction fees that eat into already-thin margins.
- Missed upselling opportunities. A human server might suggest dessert. But they rarely tailor suggestions to what the customer has already ordered — and they never do it consistently at scale.
Our client — a mid-size restaurant group operating 8 locations — was losing an estimated 15–20% of potential revenue to these friction points.
Our Solution: Restrofi
Restrofi is a complete QR-based ordering and payment platform:
- Diner scans a QR code on their table
- Browses a mobile-optimised menu (no app download required)
- Adds items to cart — and receives AI-powered upsell suggestions in real time
- Pays via Stripe directly from the browser
- Kitchen receives the order instantly on a real-time dashboard
The entire flow — from scan to payment — takes under 90 seconds.
Architecture Overview
We chose a modern, serverless-leaning architecture to keep costs low and latency minimal:
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Diner's │────▶│ Next.js │────▶│ Node.js │
│ Browser │ │ Frontend │ │ API Layer │
│ (QR scan) │◀────│ (Vercel) │◀────│ (Vercel) │
└─────────────┘ └──────────────┘ └──────┬───────┘
│
┌──────────────────────┼──────────────────┐
│ │ │
┌────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐
│PostgreSQL│ │ OpenAI │ │ Stripe │
│(Supabase)│ │ API │ │ Payments │
└──────────┘ └────────────┘ └────────────┘
Tech Stack
| Layer | Technology | Why |
|---|---|---|
| Frontend | Next.js 14 (App Router) | Server components for fast initial load, client components for interactivity |
| Backend | Node.js API routes | Co-located with frontend on Vercel for zero cold-start latency |
| Database | PostgreSQL (Supabase) | Relational data model fits restaurant menus, orders, and users well |
| AI | OpenAI GPT-4 API | Best accuracy for food-pairing recommendations at the time of development |
| Payments | Stripe | Industry standard. Supports Apple Pay, Google Pay, and card payments |
| Hosting | Vercel | Edge network ensures sub-200ms TTFB globally |
| Real-time | Supabase Realtime | Kitchen dashboard updates instantly when a new order is placed |
The AI Upselling Engine
This was the most impactful feature we built. Here is how it works:
Step 1: Context Assembly
When a diner adds an item to their cart, we assemble a context object:
const upsellContext = {
currentItems: cart.items.map(item => item.name),
menuCategories: restaurant.menu.categories,
timeOfDay: getTimeOfDay(), // breakfast, lunch, dinner
averageOrderValue: restaurant.stats.avgOrderValue,
popularPairings: restaurant.stats.topPairings,
};
Step 2: AI Suggestion
We send this context to a fine-tuned prompt that generates personalised upsell suggestions based on what the customer has already added to their cart.
Step 3: Display
The suggestion appears as a subtle card below the cart — not a popup (we tested both; the card had 3x higher acceptance rate).
Results
After 3 months of A/B testing across all 8 locations:
- Average order value increased by 23% in the AI upsell variant
- Upsell acceptance rate: 31% (vs. 8% for human server upsells reported by the client)
- Order completion time dropped from 4.5 minutes to 1.2 minutes
Challenges We Faced
1. Latency on AI Suggestions
Early versions had 2–3 second delays for upsell suggestions. We solved this by:
- Caching menu-level embeddings so we only send dynamic context to the API
- Using streaming responses to show suggestions progressively
- Pre-computing popular pairings nightly and falling back to those when the API was slow
2. QR Code Reliability
Not all phone cameras handle QR codes equally. We implemented a fallback: a short URL printed below the QR code that goes to the same ordering page.
3. Kitchen Display Real-time Sync
Orders need to appear on the kitchen dashboard within 1–2 seconds. We used Supabase Realtime (built on PostgreSQL's logical replication) which gave us sub-second latency without managing WebSocket infrastructure ourselves.
What We Learned
- AI upselling works dramatically better than human upselling — but only when the suggestion is contextual and non-intrusive. A popup killed conversion. A subtle card tripled it.
- QR ordering removes friction but adds a trust gap. We added a "Powered by Restrofi" badge and SSL lock icon to the ordering page — this increased completion rates by 12%.
- Real-time is non-negotiable for kitchen operations. Even 5-second delays caused confusion during peak hours.
Outcome
Restrofi is now live at restrofi.com and serving multiple restaurant locations. The platform processes orders daily, has maintained 99.9% uptime since launch, and continues to deliver measurable revenue increases through AI-powered upselling.
If you are building a SaaS product for the restaurant industry — or any vertical — we would love to discuss how we can help. Start a conversation →
Built by Navtechy. We engineer intelligent software for businesses worldwide.