Custom 1С-Bitrix Booking System: Eliminating Overbooking

Custom 1С-Bitrix Booking System: Eliminating Overbooking Overbooking is a headache for any hotel business. When two guests simultaneously book the last room, a standard Bitrix cannot guarantee that no double booking occurs. Losses from such conflicts can reach 500,000 rubles per year for a small

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1415
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    995
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    733
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    863
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    772
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1134

Custom 1С-Bitrix Booking System: Eliminating Overbooking

Overbooking is a headache for any hotel business. When two guests simultaneously book the last room, a standard Bitrix cannot guarantee that no double booking occurs. Losses from such conflicts can reach 500,000 rubles per year for a small network. We developed a custom booking system on 1С-Bitrix that completely eliminates overbooking through transactional row locking and automatic release of expired bookings. Custom development of a booking system on 1С-Bitrix starts with database schema design: the bl_booking table, indexes, and transactions. Under the hood: SELECT FOR UPDATE, an agent, and an AJAX calendar. Below is the architecture and a real case.

According to 1С-Bitrix documentation, for complex booking logic it is recommended to use custom tables instead of information blocks. We use exactly this approach: an rooms information block for room descriptions, and a custom bl_booking table for occupancy tracking. This provides flexibility in queries and performance.

Why Standard Information Blocks Don't Work for Booking?

Calendar-based availability tracking requires a separate schema. Information blocks cannot efficiently check date overlaps and lock slots.

Room table — information block of type room with properties PROPERTY_ROOM_TYPE, PROPERTY_CAPACITY and binding to hotel.

Booking table — custom table bl_booking:

CREATE TABLE bl_booking ( id SERIAL PRIMARY KEY, room_id INT NOT NULL, user_id INT, date_from DATE NOT NULL, date_to DATE NOT NULL, status VARCHAR(20) NOT NULL, -- pending, confirmed, cancelled, expired order_id INT, price_total NUMERIC(12,2), created_at TIMESTAMP DEFAULT NOW(), expires_at TIMESTAMP, guest_name VARCHAR(255), guest_phone VARCHAR(50), guest_email VARCHAR(255) ); CREATE INDEX idx_booking_room_dates ON bl_booking(room_id, date_from, date_to, status); 

How Does the Availability Check with Race Condition Protection Work?

The key query checks for overlaps:

SELECT COUNT(*) FROM bl_booking WHERE room_id = :room_id AND status IN ('pending', 'confirmed') AND date_from < :date_to AND date_to > :date_from; 

If COUNT > 0 — the room is unavailable. The query is wrapped in a transaction with SELECT FOR UPDATE to eliminate race conditions. Implementation steps:

  1. Open transaction.
  2. Execute SELECT FOR UPDATE on the room record.
  3. Check date overlaps.
  4. If free — INSERT into bl_booking with status pending.
  5. Commit transaction.

Under parallel requests, the second request waits for the first transaction to finish, guaranteeing no double bookings. The custom check based on bl_booking runs 5 times faster than attempting similar logic on standard info blocks.

How Is Payment Timeout Handled?

After creating a booking in pending status, a timer starts. If payment is not received within 15–30 minutes, the booking transitions to expired and the slot is released.

Implementation via an agent:

function ReleasExpiredBookings(): string { $expiredIds = BookingTable::getList([ 'filter' => [ 'STATUS' => 'pending', '<=EXPIRES_AT' => new \Bitrix\Main\Type\DateTime(), ], 'select' => ['ID'], ])->fetchAll(); foreach ($expiredIds as $row) { BookingTable::update($row['ID'], ['STATUS' => 'expired']); } return __FUNCTION__ . '();'; } 

Registered via CAgent::AddAgent() with a 60-second interval.

How Is the Date Picker Interface Built?

The availability calendar is built using an AJAX request to /bitrix/services/main/ajax.php?action=BookingModule:getAvailability. The backend returns occupied dates. On the frontend we use Flatpickr with disabled day marking.

AJAX controller extending \Bitrix\Main\Engine\Controller:

class BookingController extends \Bitrix\Main\Engine\Controller { public function getAvailabilityAction(int $roomId, string $month): array { // returns occupied dates for the month } } 

Case Study: Apartment Hotel Network (3 properties, 47 rooms)

Task: Replace manual phone-based booking, eliminate overbooking.

Initial situation: Managers used an Excel spreadsheet, reconciled weekly — periodic double bookings led to guest complaints. Overbooking losses before implementation were about 500,000 rubles per year.

Solutions implemented:

  • Information block rooms with 47 elements, each with gallery and properties (FLOOR, VIEW, BED_TYPE)
  • bl_booking table with date range index
  • AJAX controller for availability check (responds in 80–120 ms)
  • Integration with payment gateway via sale.payment module: booking transitions to confirmed on webhook from payment gateway
  • Agent to release expired bookings every 2 minutes
  • Administrative module with calendar view of room occupancy

Results: Zero overbookings over 14 months of operation, booking form conversion rate 4.2% (was 0% — everything went through phone). Development costs recovered in 2 months.

Development Process

Stage Duration
Data schema design 3 days
Backend development (table, agent, controller) 5 days
Frontend (calendar, form, AJAX) 4 days
Integration with payment gateway 2 days
Admin interface 3 days
Testing and launch 2 days

Timelines may vary depending on integration complexity and number of properties.

Approach Comparison

Aspect Standard sale module Custom bl_booking
Date overlap check Requires complex modifications Built-in, fast
Booking timeout None, only manual cancellation Automatic agent
Race condition Not resolved SELECT FOR UPDATE
Check performance ~500 ms 80–120 ms

What Does the Booking System Development Include?

  • Data model design with room types and seasonal pricing
  • Availability check mechanism with race condition protection
  • Date selection interface with occupancy visualization
  • Automatic agent for releasing expired bookings
  • Integration with sale module for invoicing and payment acceptance
  • Administrative section for booking management
  • Guest and admin notification setup (email/SMS)

Get a consultation for your project. Order a turnkey booking system development — we will prepare a commercial proposal within 1 business day. Contact us to estimate development timelines and cost for your tasks.