Rolling Mugshot · 2026
Rolling Mugshot Online Ordering
Order-Ahead for a Mobile Coffee Cart, Wired Straight into Square POS
Role
Product Designer & Full-Stack Developer
Year
2026
Stack
Next.js 16 · App Router · React 19 · Tailwind CSS · shadcn/ui · Square · Neon Postgres · Resend · Vercel
Overview
Executive Summary
Rolling Mugshot Online Ordering lets customers browse the menu, order ahead, pay online, and collect at the truck window — without standing in the morning queue. Orders flow through Square Payment Links so they land in Square POS alongside walk-ups, write to a Postgres source of truth, surface to staff in a PIN-gated kitchen view, and confirm to the customer on a live-polling status page. An idempotent webhook plus a reconcile cron make sure every paid order arrives exactly once — all deployed on Vercel.
The Challenge
A Queue at the Window and Two Systems to Reconcile
A mobile coffee cart lives and dies by throughput at peak. Rolling Mugshot needed to take orders ahead of time without bolting on a second point-of-sale to reconcile at the end of the day. The hard part isn't the menu — it's making sure an online order behaves exactly like a walk-up: same till, same queue, counted once, never lost.
- A growing queue at the cart window during the morning rush
- Walk-up sales and any online channel living in two separate systems to reconcile
- No way for staff to see what's coming before a customer reaches the window
- Dropped or duplicated orders whenever a payment webhook is retried
- No digital receipt trail for customers paying ahead
"Two-till drift" — the moment online orders live in a separate system from the window, every shift ends with a reconciliation puzzle and the risk of a paid order nobody made.
The Solution
One Queue, Backed by a Real Database
A Next.js 16 App Router build that hands money to Square via Payment
Links — so online orders surface in the same POS as the window — and
treats a Postgres orders table as the single source of truth.
Every decision, from the UNIQUE payment reference to the reconcile cron,
exists so that every paid order reaches the cart exactly once and exactly as
ordered.
Square Payment Links
Checkout creates a real Square Order plus a hosted Payment Link, so online pre-orders land in Square POS right alongside walk-up sales — one queue, one source of takings, no double entry.
Postgres Source of Truth
Every paid order is written to a Neon Postgres `orders` table — the canonical record the kitchen view, status page, and receipts all read from, independent of Square's dashboard.
Idempotent Webhook
The Square order ID is a UNIQUE column and the webhook does INSERT … ON CONFLICT DO NOTHING — so retried `payment.updated` events can never create a duplicate order at the window.
Live Order Status Page
After paying, customers land on a status screen that polls every 3 seconds — walking from "Order received" to "Preparing" to "Ready for pickup" without a refresh or a text message.
PIN-Gated Kitchen Queue
A dedicated /kitchen view, protected by a signed HMAC cookie + shared PIN, lets cart staff advance each order paid → preparing → ready → collected on a glanceable counter tablet.
Dual Resend Emails + Reconcile Cron
Each paid order fires two Resend emails — a kitchen ticket and a customer receipt — while a reconcile route polls Square for any payment the webhook missed, so nothing slips through.
Design
Key Design Decisions
Pickup-at-the-Window, Not Delivery
The whole flow is scoped to order-ahead-and-collect. No couriers, no delivery zones — just a faster path to the same truck window, which keeps the build simple and the margins intact.
A Status Page That Replaces the "Is It Ready?" Tap
Rather than texting customers, the post-payment screen polls every 3 seconds and moves through received → preparing → ready states — so people walk up exactly when their coffee is done, not before.
Human-Readable Pickup Codes
Orders get a short, speakable code instead of a UUID, so a barista can call it across a noisy cart and a customer can read it back without squinting at a screen.
Friction-Light Staff Auth
The kitchen view is gated by a signed HMAC cookie and a shared PIN — secure enough for a counter tablet, but no account juggling for casual staff mid-rush.
Engineering
Technical Architecture
Built on Next.js 16 App Router and deployed on Vercel. Checkout creates a Square Payment Link; a signature-verified webhook inserts the paid order into Neon Postgres and fires Resend emails; the kitchen view and customer status page both read from that single table. A reconcile route backfills anything Square's webhook misses.
Framework
Next.js 16
App Router · RSC
Payments
Square
Payment Links · Webhooks
Data
Neon Postgres
Source of truth · Resend
Customer ──▶ /api/checkout ──▶ Square Payment Link ──▶ hosted checkout │ pays ▼ /api/square/webhook │ INSERT … ON CONFLICT DO NOTHING ▼ Postgres `orders` │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ Resend /kitchen /order/[id] (ticket + receipt) (staff queue) (polls every 3s) ▲ /api/cron/reconcile ──┘ (backfills missed webhooks)
☕ The whole system is built around one invariant: the Square order ID is UNIQUE in Postgres. Webhook retries, duplicate events, and reconcile sweeps all converge on the same row — so a paid order can be created once and only once, no matter how many times Square tries.
Impact
The Result
Rolling Mugshot customers can order and pay before they arrive, then walk straight to the window when their status page says "Ready." Because checkout runs through Square, online pre-orders sit in the same POS as walk-ups — one queue, one set of takings, nothing to reconcile twice.
- One unified queue — online orders land in Square POS alongside window sales, with no second till to reconcile.
- Exactly-once order capture — a UNIQUE payment reference plus a reconcile cron guarantee no duplicates and no dropped orders.
- No more "is it ready?" — a live status page and a glanceable kitchen queue keep customers and staff in sync without a single text message.
💡 Meet the merchant where they already are: by building on the cart's existing Square POS instead of a parallel system, online ordering became an extension of the window — not a second business to run.
Last updated · June 2026