Add multi-day reservation booking to your Larapen site. Manage bookable services with per-night pricing, handle guest reservations with check-in and check-out dates, and view everything on an interactive calendar, with optional payment integration.

Multi-day Reservations

Date-range bookings with check-in/check-out dates, configurable minimum and maximum night stays, and guest capacity limits.

Service Management

Create bookable services with translatable names, per-night pricing, capacity limits, and image galleries with featured images.

Interactive Calendar

Admin calendar view showing reservations as multi-day spans across services, with color-coded statuses for quick overview.

Payment Integration

Optional payment collection at checkout via Stripe, PayPal, Paddle, or MoMo through the Payable interface.

Email Notifications

Automatic emails for new reservations (admin), booking confirmations (client), and status changes (client).

Multi-language Support

Service names, descriptions, slugs, cancellation policy, and step titles are all translatable via Spatie Translatable.

Use Cases

The reservation system is designed for any business that accepts multi-day bookings:

  • Hotels & B&Bs: Room reservations with per-night rates, minimum stay requirements, and guest limits.
  • Venue Rental: Event spaces, conference rooms, or halls booked by the day with capacity enforcement.
  • Equipment Rental: Multi-day rental of vehicles, tools, or other gear with date-range selection.
  • Vacation Properties: Holiday homes or apartments with seasonal pricing and minimum night rules.
  • Campgrounds & RV Parks: Campsite or RV spot reservations with maximum guest counts.

Requirements

Requirement Version Notes
Larapen CMS v1.0.0+ Core platform with add-on system enabled
PHP 8.3+ Required by Larapen core
MySQL 8.0+ Required by Larapen core
Optional: To collect payments at checkout, install one or more payment gateway add-ons (Stripe, PayPal, Paddle, or MoMo).

Installation

Step 1: Upload the Add-on

In the admin panel, go to Admin → Extensions → Add-ons and click the Upload Add-on button. Select the add-on’s ZIP file: the system extracts it automatically and the add-on appears in the installed add-ons list.

Step 2: Activate the Add-on

Find Booking (Reservations) in the list and click Activate. Its migrations, seeders (if any) and permissions are set up automatically.

Step 3: Configure

Navigate to Admin → Booking → Settings to configure bookable services, opening hours, reservation rules, and notifications. See Configuration.

Purchase Code (License Key)

Booking (Reservations) is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate Booking (Reservations) in Admin panel → Add-ons.

Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.

Platform / Marketplace How you get the purchase code Where to find it again
bedigit.com Store
In-site purchase (Shop)
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. My Account → My Licenses on bedigit.com
Gumroad Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com
Envato Market
CodeCanyon
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. Envato account → Downloads → License certificate & purchase code
Check your spam folder. For both bedigit.com Store and Gumroad purchases, the purchase code is delivered by email. Automated license emails are very often filtered, so if the message is not in your inbox, look in your spam / junk folder before contacting support, and add our sender address to your contacts or allow list.

1. bedigit.com Store (in-site purchase)

  • As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
  • It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
  • The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
  • The matching invoice is under My Account → My Orders.

2. Gumroad

  • A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
  • The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
  • When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library → your purchase on gumroad.com.
  • Use the same email address on bedigit.com as on Gumroad: your keys are then linked to your account automatically and listed under My Account → My Licenses, even if you register after the purchase. You can also add a Gumroad key manually from My Account → My Gumroad Licenses.

3. Envato Market (CodeCanyon)

  • Envato purchase codes are issued and delivered by Envato Market, never emailed by us, so there is nothing to look for in your spam folder: you retrieve the code from your Envato account.
  • Log in to your Envato / CodeCanyon account, open the Downloads page, find the item, and choose License certificate & purchase code from the Download dropdown. The code is written in that certificate.
  • An Envato purchase code looks like 12345678-90ab-cdef-1234-567890abcdef (8-4-4-4-12 characters). It never changes, and renewing item support does not issue a new one.
  • Official Envato article: Where Is My Purchase Code?
Lost your purchase code? Search your mailbox (spam folder included) for “license” or “purchase code”, then check My Account → My Licenses on bedigit.com for Store and Gumroad purchases, or Downloads → License certificate on Envato. If it is still missing, open a ticket on our Help Center with your order number (Store), Gumroad sale ID or buyer email (Gumroad), or Envato username and item name (Envato).

Configuration

All settings are managed from /admin/booking/settings.

General Settings

Setting Key Type Description
booking_enabled Boolean Master toggle to enable or disable the entire booking system on the front-end.
booking_services_per_row Integer Number of service cards per row on the booking page grid.
booking_require_payment Boolean When enabled, guests must complete payment at checkout to confirm a reservation.
booking_advance_days Integer Maximum number of days in advance a reservation can be made.
booking_min_advance_hours Integer Minimum hours before check-in that a reservation can be placed.
booking_cancellation_policy Translatable text Cancellation policy text displayed to guests during booking. Supports per-language translations.
booking_captcha_enabled Boolean Enable CAPTCHA verification on the booking form to prevent spam submissions.
booking_service_images_enabled Boolean Enable image uploads and galleries for services.
booking_service_step_title Translatable text Custom title for the service selection step in the booking wizard. Supports per-language translations.

Notification Settings

Notification toggles are managed from the centralized notification settings page at /admin/settings/notifications. The booking add-on registers 3 notification types:

Notification Key Recipient Description
booking_new_reservation_admin Admin Notifies the admin when a new reservation is placed.
booking_reservation_confirmation Client Sends a booking confirmation email to the guest after a reservation is created.
booking_reservation_status_change Client Notifies the guest when their reservation status changes (confirmed, cancelled, completed).
Config keys: In the add-on's config/booking.php, these correspond to notify_admin_on_new_reservation, notify_client_on_reservation, and notify_client_on_status_change.

Admin: Services

Manage bookable services at /admin/booking/services. The list view displays services in a sortable table with the following columns:

Column Description
Featured ImageThumbnail of the service's primary image (if images are enabled).
NameTranslatable service name.
Nights RangeMinimum and maximum nights allowed (e.g., "2 - 14 nights").
Price Per NightNightly rate with currency.
StatusActive or inactive badge.
PositionSort order for front-end display.

Create & Edit

The service form includes the following fields:

Field Type Description
name Translatable string Display name of the service (required, per language).
slug Translatable string URL-friendly slug, auto-generated from the name (per language).
description Translatable text Rich description shown on the front-end (per language).
price_per_night Decimal Nightly rate for the service.
min_nights Integer Minimum number of nights required for a reservation.
max_nights Integer Maximum number of nights allowed for a reservation.
max_guests Integer Maximum number of guests per reservation.
currency String Currency code for pricing (e.g., USD, EUR).
max_capacity Integer Total available units (e.g., number of rooms). Limits concurrent reservations for the same dates.
is_active Boolean Whether the service is visible and bookable on the front-end.
position Integer Sort order for displaying services on the booking page.

Service Images

When booking_service_images_enabled is turned on, each service supports image management via the HasMedia trait and the admin media picker:

  • Featured image: The primary image shown in service cards on the booking page and at the top of the service detail.
  • Gallery images: Additional images displayed in a lightbox gallery on the service detail view.
Tip: Use high-quality images with consistent aspect ratios for the best visual result on the booking page grid.

Admin: Reservations

Manage all reservations at /admin/booking/reservations. The list view includes status filter tabs and summary stats cards:

  • Total Reservations: All-time count of reservations.
  • Active Reservations: Currently confirmed and in-progress reservations.
  • Check-ins Today: Reservations with today's date as check-in.
  • Check-outs Today: Reservations with today's date as check-out.

Reservations can be filtered by status using the ReservationStatus enum:

Status Description
PendingNewly placed, awaiting admin review or payment.
ConfirmedApproved and confirmed by admin or after successful payment.
CancelledCancelled by admin or guest.
CompletedGuest has checked out, stay is finished.

Detail & Status

The reservation detail view shows:

  • Guest information: Name, email, phone number, number of guests, and any notes.
  • Reservation dates: Check-in date, check-out date, and total number of nights.
  • Service details: Selected service name, price per night, and total price.
  • Payment information: Payment status, gateway used, and transaction reference (when payment is required).
  • Admin notes: Internal notes field for staff use.
  • Status management: Dropdown to change the reservation status. Changing status triggers a notification email to the guest (if enabled).

Calendar View

Access the calendar at /admin/booking/reservations/calendar. Reservations are displayed as multi-day horizontal spans on a calendar grid, with each reservation color-coded by its status. The calendar fetches data from the calendar-events endpoint and supports month navigation.

Admin: Settings

Configure the booking system at /admin/booking/settings. Settings are organized into the following groups:

General

  • Enabled (booking_enabled): Master on/off toggle for the booking system.
  • Services per row (booking_services_per_row): Grid columns on the booking page.

Display Settings

  • Service images (booking_service_images_enabled): Toggle image uploads and galleries for services.
  • Service step title (booking_service_step_title): Custom translatable heading for the service selection step in the booking wizard.

Payment

  • Require payment (booking_require_payment): When enabled, reservations must be paid at checkout to be confirmed. Requires at least one payment gateway add-on (Stripe, PayPal, Paddle, or MoMo).

Scheduling

  • Advance days (booking_advance_days): How far into the future guests can book.
  • Minimum advance hours (booking_min_advance_hours): How many hours before check-in a reservation can be placed.

Cancellation Policy

  • Policy text (booking_cancellation_policy): Translatable text displayed to guests during the booking process. Supports separate content per language.

Notifications

Notification toggles are managed centrally at /admin/settings/notifications. See the Configuration section for the 3 notification types registered by this add-on.

CAPTCHA

  • Enable CAPTCHA (booking_captcha_enabled): Adds CAPTCHA verification to the booking form to prevent automated spam submissions.

Front-end: Booking Page

Routes

Method URI Description
GET /booking Main booking page with service selection and reservation wizard.
POST /booking Submit a new reservation.
GET /booking/confirmation/{reservation} Reservation confirmation page.
GET /booking/availability Monthly availability map (JSON).
GET /booking/check-availability Date range availability check (JSON).
GET /booking/checkout/{reservation} Payment checkout page (when payment is required).
GET /booking/my-reservations Authenticated user's reservation history.

Booking Wizard

The front-end booking page uses a multi-step wizard:

  1. Step 1: Service Selection: Browse available services displayed as cards in a grid (configurable columns via booking_services_per_row). Each card shows the featured image (if enabled), service name, price per night, and guest capacity. Clicking a card selects the service and advances to the next step.
  2. Step 2: Date Selection: An interactive calendar for choosing check-in and check-out dates. The calendar enforces the service's minimum and maximum night rules, advance booking limits, and availability based on remaining capacity. Unavailable dates are grayed out.
  3. Step 3: Client Details, A form collecting guest information:
    • Full name (required)
    • Email address (required)
    • Phone number
    • Number of guests
    • Special requests / notes
    The cancellation policy is displayed here if configured. CAPTCHA is shown if enabled.

Front-end: Availability API

Two GET endpoints provide availability data consumed by the booking wizard's calendar:

GET /booking/availability
Parameters
service_id Required. The ID of the service to check.
month Required. Month number (1-12).
year Required. Four-digit year.
Response

Returns a monthly availability map: an object keyed by date with remaining capacity for each day of the requested month.

GET /booking/check-availability
Parameters
service_id Required. The ID of the service to check.
check_in Required. Desired check-in date (YYYY-MM-DD).
check_out Required. Desired check-out date (YYYY-MM-DD).
Response

Returns whether the service is available for the entire requested date range, along with the calculated total price and number of nights.

Front-end: Confirmation

After a reservation is successfully submitted, the guest is redirected to /booking/confirmation/{reservation}. This page displays a summary of the reservation including the service name, dates, number of nights, total price, and a confirmation reference. If payment is required and has not yet been completed, a link to the checkout page is shown.

Front-end: Payment Checkout

When booking_require_payment is enabled, guests are directed to /booking/checkout/{reservation} to complete payment. The checkout page displays the reservation summary and a payment gateway selector showing all active payment gateways (Stripe, PayPal, Paddle, MoMo) installed on the site.

The Reservation model implements the Payable interface, allowing it to work with any payment gateway add-on. After successful payment, the reservation status is automatically updated to Confirmed.

Note: At least one payment gateway add-on must be installed and configured for the checkout to function. Without a gateway, enabling booking_require_payment will display an error to guests.

Front-end: My Reservations

Authenticated users can view their reservation history at /booking/my-reservations. This page is accessible from the user menu under "My Reservations" and displays a list of the user's past and upcoming reservations with status, dates, and service details.

Notifications

The booking add-on defines 3 notification types, managed via the centralized notification system:

Type Key Recipient Trigger
booking_new_reservation_admin Admin A new reservation is submitted by a guest.
booking_reservation_confirmation Client A reservation is successfully created (sent immediately after submission).
booking_reservation_status_change Client An admin changes the reservation status (confirmed, cancelled, or completed).

Toggle each notification on or off at /admin/settings/notifications. Individual users can also manage their notification preferences from their account settings.

Updating

  1. Back up: Back up your database and the extensions/addons/booking directory before updating.
  2. Replace files: Overwrite the extensions/addons/booking directory with the new version.
  3. Run migrations: Execute php artisan migrate to apply any new database changes.
  4. Clear caches: Run php artisan optimize:clear to clear all application caches.

Uninstallation

Switching an add-on off without losing anything is a deactivation: go to Admin panel → Add-ons, find Booking (Reservations) and click Deactivate.

  • Its routes, views, admin menu entries and permissions stop being registered, and its front-end pages stop answering.
  • Its database tables and all the data they hold are kept, and its files stay under extensions/addons/booking/. Nothing is deleted.
  • The purchase code recorded at activation is kept too, so activating the add-on again does not ask for it.
  • Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.

Click Activate on the same card to switch it back on. Pending migrations are re-run, assets are republished, and the add-on picks up exactly where it left off.

Removing

Removing is permanent and destroys the add-on's data. The Remove button only appears on a deactivated add-on, so removal is always two steps:

  1. Deactivate Booking (Reservations) (see Uninstallation).
  2. Click Remove on its card and confirm the prompt.

The admin panel then, in one pass:

  • runs the add-on's uninstall hook, if it ships one, while its code is still on disk;
  • revokes the permissions declared in its addon.json;
  • rolls back its migrations (this drops its database tables and every row they hold) and purges its entries from the migrations table, so a later reinstall migrates from scratch;
  • deletes its published assets: public/addons/booking/, public/vendor/booking/ and storage/app/public/addons/booking/;
  • deletes the add-on directory extensions/addons/booking/;
  • deletes its row in the addons table (the recorded purchase code goes with it) and clears the application cache.
This cannot be undone. Back up your database before removing an add-on whose data you may still need: installing it again later creates empty tables, not your old content.

Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/booking/. In that last case, give that user write permission on the directory and on its parent, then try again.

Deleting the folder over FTP or SSH is not equivalent: the add-on's tables, its entries in the migrations table and its addons row are all left behind, and its card stays in the list. Use Remove in the admin panel instead.

Troubleshooting

No availability showing on the calendar

  • Verify the service has is_active set to true.
  • Check that max_capacity is greater than zero.
  • Ensure booking_advance_days covers the dates you are trying to book.
  • Confirm booking_min_advance_hours is not preventing near-term check-in dates.

Calendar not loading in admin

  • Clear browser cache and check the browser console for JavaScript errors.
  • Verify the calendar-events endpoint returns valid JSON by visiting /admin/booking/reservations/calendar-events directly.
  • Ensure the admin user has the booking.reservations.view permission.

Payment errors at checkout

  • Confirm at least one payment gateway add-on is installed and activated.
  • Verify the payment gateway API keys are correctly configured in the gateway's settings.
  • Check Laravel logs at storage/logs/laravel.log for detailed error messages.
  • Ensure the Reservation model's Payable interface methods return correct values (amount, currency, description).

CAPTCHA not displaying

  • Ensure booking_captcha_enabled is set to true in booking settings.
  • Verify the global CAPTCHA driver and API keys are configured at /admin/settings/security.

Service images not showing

  • Confirm booking_service_images_enabled is set to true.
  • Check that images were uploaded through the admin media picker.
  • Verify the storage symlink exists (php artisan storage:link).

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket
Apr 07, 2026