payload-reserve
v1.1.0
Published
A Payload CMS 3.x plugin for reservation and booking management with conflict detection, status workflows, and calendar UI
Maintainers
Readme
payload-reserve
A full-featured reservation and booking plugin for Payload CMS 3.x. Adds a scheduling system with conflict detection, a configurable status machine, multi-resource bookings, capacity and inventory tracking, a public REST API, and admin UI components.
Designed for salons, clinics, hotels, restaurants, event venues, and any business that needs appointment scheduling managed through Payload's admin panel.
Features
- 5 Domain Collections — Services, Resources, Schedules, Reservations, and Customers (standalone or user-collection extension)
- User Collection Extension — Optionally extend your existing auth collection with booking fields; set
userCollection: undefined(default) to use a standalone Customers collection - Resource Owner Multi-Tenancy — Opt-in
resourceOwnerModewires ownership access control so each resource owner (host) sees only their own listings and reservations - Configurable Status Machine — Define your own statuses, transitions, blocking states, and terminal states
- Double-Booking Prevention — Server-side conflict detection with configurable buffer times; respects capacity modes
- Auto End Time — Calculates
endTimefromstartTime + service.durationautomatically - Three Duration Types —
fixed(service duration),flexible(customer-specified end), andfull-daybookings - Multi-Resource Bookings — Single reservation that spans multiple resources simultaneously via the
itemsarray - Capacity and Inventory —
quantity > 1allows multiple concurrent bookings per resource;capacityMode(per-reservation|per-guest) controls how capacity is counted - Idempotency — Optional
idempotencyKeyprevents duplicate submissions - Extra Reservation Fields — Inject custom fields into the Reservations collection via
extraReservationFieldswithout forking the plugin - Cancellation Policy — Configurable minimum notice period enforcement
- Plugin Hooks API — Seven lifecycle hooks (
beforeBookingCreate,afterBookingCreate,beforeBookingConfirm,afterBookingConfirm,beforeBookingCancel,afterBookingCancel,afterStatusChange) for integrating email, Stripe, and external systems - Availability Service — Pure functions and DB helpers for slot generation and conflict checking
- Public REST API — Five pre-built endpoints for availability, slot listing, booking, cancellation, and customer search
- Calendar View — Month/week/day calendar replacing the default reservations list view
- Dashboard Widget — Server component showing today's booking stats
- Availability Overview — Weekly grid of resource availability vs. booked slots
- Recurring and Manual Schedules — Weekly patterns with exception dates, or specific one-off dates
- Localization Support — Collection fields can be localized when Payload localization is enabled
- Type-Safe — Full TypeScript support with exported types
Install
pnpm add payload-reserve
# or
npm install payload-reservePeer dependencies: payload ^3.77.0, @payloadcms/ui ^3.77.0, @payloadcms/translations ^3.77.0
Quick Start
import { buildConfig } from 'payload'
import { payloadReserve } from 'payload-reserve'
export default buildConfig({
collections: [/* your collections */],
plugins: [
payloadReserve(),
],
})Resource Owner Multi-Tenancy
Enable resourceOwnerMode to support Airbnb-style platforms where each user manages their own listings (Resources) and sees only the reservations made against them. This is opt-in — single-tenant installs are unaffected.
payloadReserve({
userCollection: 'users', // required: which auth collection holds owners
resourceOwnerMode: {
adminRoles: ['admin'], // roles that bypass all filters (see all records)
ownerField: 'owner', // field name added to Resources (default: 'owner')
ownedServices: false, // set true if Services should also be owner-scoped
},
})What this does automatically:
| Collection | Behaviour |
|------------|-----------|
| Resources | Adds an owner relationship field (auto-populated on create); owners read/update/delete only their own records |
| Schedules | Owners read/update/delete only schedules whose resource they own (join through resource.owner) |
| Reservations | Owners can read reservations for their resources; mutations are admin-only |
| Services | Unchanged by default; set ownedServices: true to apply the same owner pattern |
The access override in plugin config always takes precedence over the auto-wired functions, so you can fine-tune any collection without losing the rest.
Documentation
The docs below live in the GitHub repository and are not included in the published npm package.
| Topic | Contents |
|-------|----------|
| Getting Started | Installation, quick start, what gets created |
| Configuration | All plugin options with types and defaults, including resourceOwnerMode |
| Collections | Services, Resources, Schedules, Customers, Reservations schemas |
| Status Machine | Default flow, custom machines, business logic hooks, escape hatch |
| Booking Features | Duration types, multi-resource bookings, capacity modes |
| Hooks API | All 7 plugin hook types with signatures and examples |
| REST API | All 5 public endpoints with params, responses, and fetch examples |
| Admin UI | Calendar view, dashboard widget, availability overview |
| Examples | Salon, hotel, restaurant, event venue, Stripe, email, multi-tenant (resource owner mode) |
| Advanced | DB indexes, reconciliation job for race condition detection |
| Development | Prerequisites, commands, project file tree |
