Loading...
Loading...
Expert guide for the payload-reserve plugin — a Payload CMS 3.x reservation/booking system. Use when working with: reservation systems, booking systems, appointment scheduling, calendar views, availability checks, conflict detection, double-booking prevention, status workflows (pending/confirmed/completed/cancelled/no-show), buffer times, cancellation policies, schedule management, service/resource configuration, customer management, walk-in bookings, or integrating payments (Stripe) and notifications with a Payload CMS reservation plugin. Triggers on: "payload-reserve", "payloadReserve", "reservation plugin", "booking plugin", "appointment plugin", "schedule plugin", "availability overview", "calendar view", "reservation conflict", "double booking", "booking status", "cancellation policy".
npx skill4agent add elghaied/payload-reserve payload-reservepayload-reserveauth: trueaccess.admin: () => false/api/reservation-customer-search(pluginOptions) => (config) => modifiedConfigpayload-reservepayload-reserve/clientpayload-reserve/rscimport { buildConfig } from 'payload'
import { payloadReserve } from 'payload-reserve'
export default buildConfig({
collections: [/* your existing collections */],
plugins: [payloadReserve()],
})payload ^3.76.1payloadReserve({
disabled: false, // disable plugin (collections still registered)
slugs: {
services: 'services', // override collection slugs
resources: 'resources',
schedules: 'schedules',
reservations: 'reservations',
customers: 'customers',
media: 'media', // media collection for Resources image field
},
adminGroup: 'Reservations', // admin panel group name
defaultBufferTime: 0, // minutes between reservations (fallback)
cancellationNoticePeriod: 24, // minimum hours notice for cancellation
access: { // per-collection access control overrides
services: { read: () => true },
resources: { /* ... */ },
schedules: { /* ... */ },
reservations: { /* ... */ },
customers: { /* ... */ },
},
})| Option | Default | Description |
|---|---|---|
| | Disable plugin functionality |
| | Collection slugs |
| | Admin panel group |
| | Default buffer minutes between bookings |
| | Minimum hours notice for cancellation |
| | Per-collection access control overrides |
Services <--many-to-many-- Resources
|
has schedule
|
Schedules
Reservations --> Service
--> Resource
--> Customer +-> confirmed --+-> completed
| |
pending ------+ +-> cancelled
| |
+-> cancelled +-> no-showpendingpendingconfirmedcompletedcancelledno-showexport default buildConfig({
plugins: [
payloadReserve(),
// Add fields to reservations after the plugin
(config) => {
const reservations = config.collections?.find(c => c.slug === 'reservations')
if (reservations) {
reservations.fields.push({ name: 'internalNotes', type: 'textarea' })
}
return config
},
],
})// In a plugin that runs after payloadReserve()
const reservations = config.collections?.find(c => c.slug === 'reservations')
if (reservations) {
if (!reservations.hooks) reservations.hooks = {}
if (!reservations.hooks.afterChange) reservations.hooks.afterChange = []
reservations.hooks.afterChange.push(myNotificationHook)
}accesspayloadReserve({
slugs: {
services: 'salon-services',
resources: 'stylists',
schedules: 'stylist-schedules',
reservations: 'appointments',
customers: 'clients',
},
})config.admin.custom.reservationSlugsreservation-todays-reservations/admin/reservation-availabilitypayload-reserve| Function | Purpose |
|---|---|
| Add minutes to a Date |
| Check time range overlap |
| Compute blocked window with buffers |
| Hours between now and future date |
| Resolve concrete time ranges for a date |
| Merge date + "HH:mm" string |
| Check if date is an exception |
bufferTimeBeforebufferTimeAfterdefaultBufferTimecontext: { skipReservationHooks: true }cancellationNoticePeriodaccess.admin: () => false/api/customers/loginstartTime + service.durationduration