zsty.us

Before / After · Case Study

Balboa Psychic — a near-empty GoDaddy page to a deposit-taking booking platform

  • Local Pro Services
  • Beauty & Wellness

Psychic Readings by Doreen (Newport Beach) had a GoDaddy site-builder page with almost nothing on it — and a business that runs entirely on appointments. The rebuild is a Phase-1 booking platform: a multi-step /book flow (choose a reading → in-person / phone / Zoom → timezone-aware slots), Stripe Checkout deposits with a reserve-and-pay-later fallback, and webhook fulfillment that auto-creates the Zoom meeting and emails an .ics confirmation. Holds expire on a cron so an abandoned checkout can't squat on a slot, reminders go out hourly, and a password-gated admin includes a one-tap review-ask button.

A psychic's calendar is her inventory. The site's job is to sell slots without ever selling the same one twice.
🔒balboa-psychic.vercel.app
jackiej.events — modern site

Receipts — measured

Numbers that moved.

0
Booking modes offered
was 0
1440 min
Minutes an abandoned checkout can block a slot
was 1440 min
4
Manual steps from payment to a scheduled Zoom reading
was 4
  • GoDaddy near-empty page → Next.js 15 booking platform
  • 3 booking modes: in-person · phone · Zoom (auto-created via S2S OAuth)
  • Stripe deposit checkout + reserve-and-pay-later fallback
  • 10-min hold expiry + hourly reminder crons — no double-booked slots

The pixel diff

Overview, then the walkthrough.

Left: everything the legacy site shipped — frozen in place. Right: an auto-scrolling tour of the rebuild, from hero to booking. No slider to fight with.

Before — the overview
🔒balboapsychic.com
Before — the overview

This is everything the legacy site had to offer above the fold. No pricing, no calendar, no booking — the funnel ended at a mailto.

After — scroll through what shipped
🔒balboa-psychic.vercel.app
After — scroll through what shipped

Auto-scrolls through the modern site so you can see the booking surface, the package grid, the pricing table, and the calendar inline — without leaving this page.

The four beats

Problem · Insight · Build · Outcome.

Scroll past the legacy frame. The four beats land in order. At the end, the modern site fades into the same window.

🔒balboapsychic.com
Legacy
01 · Problem

An appointment business with no appointment machinery.

The GoDaddy page had nearly nothing on it — no services, no times, no way to book. Every reading was arranged by phone tag, every slot was unprotected against no-shows, and remote readings meant manually creating and sharing a meeting link.

02 · Insight

Sell the slot, not the page.

The site's one conversion is a booked, deposit-backed slot. Everything in the build serves that: the multi-step flow narrows to a time fast, the deposit makes the booking real, and fulfillment (Zoom + .ics + reminders) happens without Doreen touching a dashboard.

03 · Build

Booking engine first, brand surface around it.

Next.js 15 + Neon. Multi-step /book (service → mode → timezone-aware slots), Stripe Checkout deposits with reserve-and-pay-later, webhook fulfillment (payment state, Zoom S2S meeting create, .ics email), hold-expiry + hourly reminder crons, and a password-gated admin with a review-ask button. The constellation hero and aurora styling wrap it in a brand that fits the business.

04 · Outcome

A calendar that defends itself, awaiting content + DNS.

The platform is live at balboa-psychic.vercel.app. Remaining before cutover: Doreen's real photos and pricing, and pointing balboapsychic.com — the legacy GoDaddy page still answers there today, which is exactly what the before-captures show.

🔒balboa-psychic.vercel.app
Modern

Architecture

One chain replaced by another. Receipts above.

Old stack
  • GoDaddy builder
  • Phone-tag booking
  • No deposits
  • No calendar
New stack
  • Next.js 15 + Neon
  • Multi-step /book flow
  • Timezone-aware slot picker
  • Stripe deposits + pay-later fallback
  • Zoom S2S + .ics fulfillment
  • Hold-expiry + reminder crons

What changed

Grouped by what kind of system shipped.

Each claim ships with concrete evidence — env vars, table names, cadence chips. No marketing fluff.

Design

A hero that sets the mood without a stock tarot photo

Canvas-2D particle constellation with mouse parallax over a CSS aurora — an atmospheric, performance-cheap hero that reads 'mystic' without a single cliché stock image, and degrades gracefully under reduced-motion.

Before
A default site-builder template with placeholder sections.
After
A bespoke celestial hero rendered in canvas, no heavy assets.
Retention

Deposits kill the no-show problem — with an honest fallback

The /book flow takes a Stripe Checkout deposit to confirm a slot. Clients who won't pay online can reserve-and-pay-later — the slot holds for a bounded window instead of forever. Webhook fulfillment marks the booking paid, creates the Zoom meeting via S2S OAuth when the mode is remote, and emails an .ics the client's calendar understands.

Before
A booked reading was a verbal promise; no-shows cost the whole slot.
After
A slot is only confirmed by a deposit or a bounded hold — and fulfillment is automatic.
  • Stripe Checkout session per booking; webhook flips the booking state
  • Zoom meeting auto-created on paid remote bookings (S2S OAuth, no user token dance)
  • .ics confirmation attached so the appointment lands in the client's calendar
Agent backbone

Timezone-aware slots with a double-booking guard

Slot generation is luxon-based and timezone-aware (a phone reading booked from Chicago shows Chicago times), and the booking transaction guards against two clients landing on the same slot — the second writer loses cleanly, not silently.

  • luxon slot math keyed to the client's timezone
  • DB-level double-booking guard on the slot claim
  • 10-minute hold expiry cron releases abandoned checkouts
Real-time push

Crons that run the calendar while Doreen reads

An hourly reminder cron nudges upcoming appointments; the hold-expiry cron reclaims slots from abandoned checkouts every 10 minutes; and the password-gated admin includes a one-tap review-ask button for after a good reading — the retention loop for a reputation business.

While the owner sleeps.

Autonomous surfaces

The agent backbone keeps the brand earning after hours. The owner approves; the system runs.

  • Releases abandoned holds before they cost a slot

    every 10 min

    The hold-expiry cron reclaims any slot whose checkout was abandoned past the 10-minute window, returning it to inventory automatically.

  • Reminds upcoming appointments

    hourly

    An hourly cron emails reminders for approaching readings — fewer no-shows without Doreen managing a calendar app.

  • Fulfills paid bookings end-to-end

    on each paid booking

    The Stripe webhook marks the booking paid, creates the Zoom meeting for remote modes, and sends the .ics confirmation — zero manual steps between payment and a scheduled reading.

← All rebuilds

Balboa Psychic — a near-empty GoDaddy page to a deposit-taking booking platform — zsty.us