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 |
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 |
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?
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/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 Image | Thumbnail of the service's primary image (if images are enabled). |
| Name | Translatable service name. |
| Nights Range | Minimum and maximum nights allowed (e.g., "2 - 14 nights"). |
| Price Per Night | Nightly rate with currency. |
| Status | Active or inactive badge. |
| Position | Sort 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.
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 |
|---|---|
| Pending | Newly placed, awaiting admin review or payment. |
| Confirmed | Approved and confirmed by admin or after successful payment. |
| Cancelled | Cancelled by admin or guest. |
| Completed | Guest 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:
-
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. - 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.
-
Step 3: Client Details,
A form collecting guest information:
- Full name (required)
- Email address (required)
- Phone number
- Number of guests
- Special requests / notes
Front-end: Availability API
Two GET endpoints provide availability data consumed by the booking wizard's calendar:
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.
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.
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
- Back up: Back up your database and the
extensions/addons/bookingdirectory before updating. - Replace files: Overwrite the
extensions/addons/bookingdirectory with the new version. - Run migrations: Execute
php artisan migrateto apply any new database changes. - Clear caches: Run
php artisan optimize:clearto 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:
- Deactivate Booking (Reservations) (see Uninstallation).
- 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
migrationstable, so a later reinstall migrates from scratch; - deletes its published assets:
public/addons/booking/,public/vendor/booking/andstorage/app/public/addons/booking/; - deletes the add-on directory
extensions/addons/booking/; - deletes its row in the
addonstable (the recorded purchase code goes with it) and clears the application cache.
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_activeset to true. - Check that
max_capacityis greater than zero. - Ensure
booking_advance_dayscovers the dates you are trying to book. - Confirm
booking_min_advance_hoursis 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-eventsendpoint returns valid JSON by visiting/admin/booking/reservations/calendar-eventsdirectly. - Ensure the admin user has the
booking.reservations.viewpermission.
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.logfor detailed error messages. - Ensure the Reservation model's
Payableinterface methods return correct values (amount, currency, description).
CAPTCHA not displaying
- Ensure
booking_captcha_enabledis 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_enabledis set to true. - Check that images were uploaded through the admin media picker.
- Verify the
storagesymlink exists (php artisan storage:link).