First Class Modules

Reservations

Turns a bookable product purchase into one secured workflow: contact identity, capacity-protected reservation, protected charge, calendar event, tenant-user assignment, resource booking, and scheduled before/after-service follow-up.

Runtime key
module.reservations
Experience
Sell, schedule & follow up
Security
Server-enforced

Use Reservations for appointments, classes, tours, consultations, rentals, services, and other products that must be paid for, placed on a calendar, assigned to a tenant user, connected to a customer contact, and followed up consistently.

Note

The bundled renderer key is module.reservations. First-class means BuildWithHQ supplies a native, typed, secured runtime experience inside normal app provisioning and the signed-in user's existing permissions.

What it does

Turns a bookable product purchase into one secured workflow: contact identity, capacity-protected reservation, protected charge, calendar event, tenant-user assignment, resource booking, and scheduled before/after-service follow-up.

Key capabilities

  • Define bookable products with duration, price/currency, party limits, concurrent capacity, buffers, hold time, and default location, resource, assignee, and follow-up timing.
  • Create or safely reuse an authorized Contact and preserve the purchaser's name, email, phone, and notes.
  • Create a capacity-protected Reservation and linked Calendar event, with an optional Resource booking and an active tenant user assigned to deliver the service.
  • Queue the existing idempotent charge-intent pipeline using a protected payment-method reference; the API never receives card numbers, security codes, processor credentials, or raw payment tokens.
  • Keep paid bookings pending and private until the charge worker reports success, then promote the reservation, event, resource, and follow-ups transactionally.
  • Track Pending Payment, Requires Action, Confirmed, Checked In, Completed, Cancelled, No Show, and Payment Failed with optimistic concurrency and an audit timeline.
  • Schedule separate pre-service and post-service follow-up date/time, recipient email, subject, message, delivery state, attempts, sent time, and outbound-message reference.
  • Use idempotency keys to make checkout retries safe and prevent duplicate contacts, charges, calendar events, and reservations.
  • Let the tenant account owner choose disabled, optional, or required collection; creation, manual, or completion timing; full or deposit collection; partial-payment rules; currency; minimum charge; and paid-before-completion enforcement.
  • Give users with the existing billing capability a secured balance, payment history, charge history, and protected charge action for the reservation record.

Reservation purchase flow

StepCanonical resultImportant behavior
Choose product and timeProduct + UTC windowDuration, buffers, party size, location, and capacity are validated inside the transaction.
Identify customerContactAn authorized exact email match may be reused; otherwise one Contact is created and linked.
Reserve serviceReservation + Calendar event + optional Resource bookingA paid event stays a private payment hold until the charge succeeds.
ChargeBilling charge intentThe existing worker uses a protected method; retries use the same idempotency key.
Confirm and serveLifecycle + audit eventsCalendar, resource, and follow-up state remains synchronized.
Follow upPreService and PostService jobsEach has its own time, email, message, attempts, result, and evidence.

Tenant API

  • GET/POST /api/modules/reservations/products lists and manages the catalog.
  • GET /api/modules/reservations lists a secured schedule window; GET /api/modules/reservations/{recordId} returns detail and history.
  • POST /api/modules/reservations/purchase performs idempotent contact, calendar, reservation, and charge orchestration.
  • PUT /api/modules/reservations/{recordId}/status applies a lifecycle transition.
  • PUT /api/modules/reservations/{recordId}/followups creates or reschedules a before/after-service follow-up.
  • GET/PUT /api/modules/payments/settings reads or changes the tenant-owned Reservations and Work Orders policies.
  • GET /api/modules/payments/records/{recordId} returns the secured balance/history; POST /api/modules/payments/records/{recordId}/charges queues an idempotent protected charge.
  • GET /api/modules/payments/methods lists display-only metadata for active consented methods; connector endpoints accept external secret references, never reusable credentials.

Common uses

  • Paid consultations and professional-service appointments.
  • Tours, classes, lessons, events, and capacity-limited sessions.
  • Installations, inspections, salon/wellness visits, rentals, and service calls.
  • Free appointments that still need contact, calendar, assignment, capacity, and follow-up.

How it connects

Reservations reuse Contacts, Calendar, Resources, the billing charge-intent/payment ledger, Record Relations, and the communications worker boundary. The Reservation owns lifecycle; payment, contact, calendar, and message records remain canonical and linked instead of copied into a shadow subsystem.

Where applicable, its records use the universal RecordId conventions so they can participate in secured relationships, activity history, favorites, dynamic fields, notifications, Inbox attention, and global search without copying the source record.

Security and data boundary

List/detail access is inherited from secured universal Records. Product management and mutations require current DataRole capability. Locations and contact targets are revalidated in the user's scope, assignees must be active tenant users, capacity is fenced transactionally, and identity comes from verified server context. The tenant account owner controls payment policy and connector references; collection requires the existing CanBillRecords capability plus record scope. Raw card data and provider credentials are never accepted or persisted by Reservations.

  • The authenticated service derives the SaaS app, tenant account, user, DataRole, and location scope; browser identifiers are never authorization proof.
  • The page editor composes React components with validated data bindings. Those bindings call typed runtime APIs, whose application services execute reviewed stored procedures.
  • List, search, detail, relation, activity, favorite, and write operations reapply their required server-side permissions.

Add it to an app

  1. As the tenant account owner, configure an external payment-connector secret reference and choose separate Reservations and Work Orders collection policies; never add card fields to a page.
  2. Add module.reservations to an in-SaaS page and place that shared page in each intended user-type menu.
  3. Create each product with duration, price, capacity/party rules, buffer, hold, location/resource/assignee, and follow-up timing.
  4. Grant existing DataRole, CanBillRecords, and location access to users who may view, collect, sell, assign, check in, complete, cancel, or follow up.
  5. Exercise free, disabled, optional, required, deposit, manual, and paid-before-completion paths plus idempotent replay, full capacity, payment success/failure/Requires Action, calendar/resource synchronization, and both follow-ups before publishing.
Tip

Start with one product and one assigned team. Decide whether capacity counts people or simultaneous services, set realistic buffers and hold time, configure payment separately, and test duplicate checkout, payment failure, Requires Action, cancellation, no-show, and both follow-ups.

Important

A renderer being bundled in the tenant application does not make its data visible in every app. The server returns only components and records authorized for the current app and signed-in user; unavailable or unauthorized blocks fail closed.