Skip to main content
Say Hello

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.

1 POS Walk-ups + online in a single queue
~2s From payment to kitchen ticket
0 Duplicate orders, via idempotent webhook

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