Custom 1С-Bitrix Booking System: Eliminating Overbooking

Simultaneous bookings of the same room are a source of losses and conflicts in the hotel business. We develop a booking system on 1C-Bitrix that eliminates overbooking through transactional locking and automatic release of expired requests. Our team delivers the project turnkey—from data schema design to implementation and ongoing support.
Frequently Asked Questions

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 $4.5k–6.5k 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 $4.5k–6.5k 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.

Our competencies:

Latest works

  • B2B ADVANCE company website development
    B2B ADVANCE company website development
    1543
  • Website development for FIXPER company
    Website development for FIXPER company
    1060
  • Development of an Online Appointment Booking Widget for a Medical Center
    Development of an Online Appointment Booking Widget for a Medical Center
    837
  • Development based on 1C Enterprise for MIRSANBEL
    Development based on 1C Enterprise for MIRSANBEL
    928
  • Website development on CRM Bitrix24 for DOLBIMBY
    Website development on CRM Bitrix24 for DOLBIMBY
    865
  • Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1223