AboutBlogContact
Web DevelopmentApril 5, 2026 4 min read 66

How to Build an Online Booking System: Architecture and Features Guide

AunimedaAunimeda
📋 Table of Contents

How to Build an Online Booking System: Architecture and Features Guide

Booking systems look simple on the surface - pick a date, pick a time, confirm. Under the hood, they involve race conditions, timezone nightmares, cancellation logic, and notification chains. Here's how to build one that actually works.


The Core Problem: Preventing Double-Bookings

This is the hardest part of any booking system. Two users click "Book 3:00 PM" at the same time. You must ensure only one succeeds.

Wrong approach: Check availability → show as available → save booking. The gap between check and save creates a race condition.

Correct approach: Database-level locking + transactions.

-- PostgreSQL: Atomic slot reservation
BEGIN;

SELECT id FROM slots 
WHERE start_time = '2026-04-10 15:00:00'
  AND staff_id = 5
  AND status = 'available'
FOR UPDATE SKIP LOCKED
LIMIT 1;

-- If row found, update it
UPDATE slots SET status = 'booked', booking_id = $1 
WHERE id = $selected_id;

COMMIT;

FOR UPDATE SKIP LOCKED acquires a row-level lock. Concurrent transactions skip locked rows rather than waiting. No double-booking possible.


Database Schema (Core Tables)

-- Resources being booked (staff, rooms, equipment)
resources (
  id, name, type, business_id, timezone, is_active
)

-- Availability windows
availability (
  id, resource_id, day_of_week, start_time, end_time
)

-- Booked slots
bookings (
  id, resource_id, customer_id,
  start_time TIMESTAMPTZ, end_time TIMESTAMPTZ,
  status ENUM('pending', 'confirmed', 'cancelled', 'completed', 'no_show'),
  notes, created_at, cancelled_at, cancellation_reason
)

-- Customers
customers (
  id, name, email, phone, business_id, notes
)

-- Services (what's being booked)
services (
  id, business_id, name, duration_minutes, price, buffer_time_minutes
)

Store all times as TIMESTAMPTZ (timestamp with timezone). Never store local times - you will regret it.


Feature List by Business Type

Universal (All Booking Systems)

  • Calendar view (day/week/month)
  • Available slot display
  • Booking confirmation (email + SMS)
  • Cancellation with configurable notice window
  • Reschedule
  • Reminder notifications (24h + 1h before)
  • Admin panel to manage bookings
  • Customer booking history

Hair Salon / Barbershop / Beauty

  • Staff selection
  • Service duration + buffer time between appointments
  • Multiple services in one booking
  • Client notes (e.g., "allergic to X")
  • Recurring booking (same time every week)

Medical / Dental Clinic

  • Doctor/specialist selection
  • Appointment type (consultation, procedure, follow-up)
  • Patient intake form (pre-appointment questionnaire)
  • Medical history notes
  • Insurance information fields
  • HIPAA/data protection compliance

Restaurant

  • Table size selection
  • Deposit / prepayment option
  • Special requests (birthday, dietary restrictions)
  • Waitlist for fully booked slots
  • Auto-release tables if not checked in within 15 min

Hotel / Accommodation

  • Date range selection (check-in / check-out)
  • Room type availability matrix
  • Rate calculation (price varies by date, room type)
  • OTA integration (Booking.com, Airbnb)

Calendar Integration

Most businesses need two-way sync with Google Calendar or Outlook:

// Google Calendar API example
const { google } = require('googleapis');
const calendar = google.calendar('v3');

// Create event when booking is confirmed
await calendar.events.insert({
  calendarId: 'primary',
  resource: {
    summary: `Appointment: ${customerName}`,
    start: { dateTime: booking.startTime },
    end: { dateTime: booking.endTime },
    description: booking.notes,
  }
});

This keeps staff calendars in sync automatically. Block manual calendar entries from accepting bookings (sync goes both ways).


Timezone Handling

The most common source of bugs in booking systems:

  1. Store all times in UTC in the database
  2. Convert to local time only for display
  3. Never store "3:00 PM" - always store 2026-04-10T09:00:00Z with explicit UTC offset
// Use date-fns-tz for reliable timezone conversion
import { zonedTimeToUtc, utcToZonedTime } from 'date-fns-tz';

const userLocalTime = '2026-04-10 15:00'; // User sees this
const timezone = 'Asia/Bishkek'; // UTC+6
const utcTime = zonedTimeToUtc(userLocalTime, timezone); // Store this

Notification System

Bookings require multiple notification triggers:

Event Notification
Booking created Confirmation email + SMS to customer
Booking created Alert to staff/admin
24h before Reminder to customer
1h before Final reminder
Cancellation Email to customer with reason
No-show Internal flag, optional customer email

Use a queue (BullMQ, Inngest) for scheduled notifications. Don't run setTimeout in your API - it won't survive server restarts.


Payment Integration

Options for requiring deposits or full prepayment:

Stripe: Best for international, cards, SEPA

const session = await stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  line_items: [{
    price_data: {
      currency: 'usd',
      product_data: { name: serviceName },
      unit_amount: depositAmount * 100,
    },
    quantity: 1,
  }],
  mode: 'payment',
  success_url: `${domain}/booking/confirm?session_id={CHECKOUT_SESSION_ID}`,
  cancel_url: `${domain}/booking/cancel`,
});

Booking is only confirmed after checkout.session.completed webhook fires.


Build vs Buy

Solution Cost Fit
Calendly / Cal.com $12–50/month Simple appointments, no customization
Booksy / Treatwell Revenue % or $50/month Beauty industry specific
Custom built $15,000–50,000 Full control, matches your exact workflow
White-label platform $5,000–20,000 Faster than custom, some limitations

Build custom when: existing solutions don't match your workflow, you need integration with your specific CRM/POS, or you're building a platform for multiple businesses.

Discuss building your booking system →

Read Also

SaaS Development Guide 2026 - Architecture, Stack, and Costaunimeda
Web Development

SaaS Development Guide 2026 - Architecture, Stack, and Cost

How to architect and build a SaaS product from scratch in 2026. Multi-tenancy, auth, billing, and the technical decisions that determine your ability to scale.

How Much Does a Website Cost in 2026? Honest Pricing Breakdownaunimeda
Web Development

How Much Does a Website Cost in 2026? Honest Pricing Breakdown

Actual website development costs in 2026 by type: landing page, corporate site, e-commerce, SaaS. What drives the price and how to avoid overpaying.

Next.js vs WordPress in 2026 - Which One Actually Wins?aunimeda
Web Development

Next.js vs WordPress in 2026 - Which One Actually Wins?

WordPress powers 43% of the web. Next.js is what serious developers build with. Here's an honest comparison on performance, SEO, cost, and when each actually makes sense.

Need IT development for your business?

We build websites, mobile apps and AI solutions. Free consultation.

Get Consultation All articles