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:
- Open transaction.
- Execute SELECT FOR UPDATE on the room record.
- Check date overlaps.
- If free — INSERT into bl_booking with status pending.
- 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.
Channel Manager — the Main Technical Puzzle of a Hotel Website
A guest books through your site, the room must be blocked on Booking.com, Ostrovok, and in the PMS. Under the hood: two-way synchronization via Travelline or Bnovo API, handling of conflicts (two bookings in one second on different channels), seasonal pricing with dozens of rate plans. We build such solutions on 1C-Bitrix for hotels, hostels, and apartments. Order hotel website development — get an audit of your current booking channel and a roadmap to direct bookings. Contact us to discuss your project.
Why Do Hotels Lose Significant Revenue on OTA Commissions?
Booking.com charges a commission, Ostrovok as well. A hotel with 40 rooms and 70% occupancy pays about $60,000–$80,000 to aggregators each year. A custom Booking Engine on Bitrix solves three tasks:
- Direct bookings without commissions — even a 10% shift in booking flow recovers the site cost within 2–3 months.
- Best Rate Guarantee — a lower price than on aggregators encourages direct booking.
- Own guest database (aggregators do not share emails) and upselling: transfers, SPA, restaurant.
Example: An urban hotel with 40 rooms increased direct bookings from 15% to 40% within a quarter after implementing the engine. Overbooking dropped to zero. The payback period was under 6 months.
How Does a Booking Engine Work Under the Hood?
The booking module is not a "leave a request" form but an engine with business logic. A Booking Engine pays off far faster than paying aggregator commissions.
Search and Availability
The guest enters dates and category — sees real available rooms. Behind the scenes: an availability table in the info block with type booking_availability, date overlap check via SQL BETWEEN, minimum stay and check-in restrictions. We optimize queries with composite indexes to keep response time under 200 ms even for 50 room types.
Pricing
Seasonal pricing is the most painful part. We implement it via info block property PRICE_CALENDAR with prices per date, surcharges for weekends and holidays, discounts for long stays, corporate rates via promo code. The calculator recalculates on the fly using Bitrix\Main\Type\Date and custom agents that update cached prices every hour.
Multi-Room Booking
A family books two rooms in one request — without re-entering dates. We implement it via sale.basket with custom basket item properties that store room IDs and check-in/out dates. The basket validation checks availability for each room simultaneously.
What Additional Services and Payment Options Are Supported?
Transfers, breakfast, parking — added to the booking as linked products tied to dates. Payment: full prepayment, deposit (first night), or card holding with receipt generation according to Federal Law 54-FZ via sale.cashbox. We integrate with YooKassa, Sber, and other acquirers. The fiscalization process is automated: every successful payment triggers a receipt to OFD. No manual intervention needed.
How Does a Channel Manager Solve Overbooking?
Channel Manager — two-way synchronization via aggregator APIs. Travelline, Bnovo, Wubook are connected through their protocols:
- Booking on the site → room blocked on Booking, Ostrovok, Yandex.Travel.
- Booking on OTA → room blocked on the site.
- Price change → update on all channels.
Hurdle: Travelline API works via XML with a delay of up to 30 seconds. On peak dates we implement double-checking — before confirming a booking, we recheck availability via the PMS inventory. In a project for a chain of three hotels, this eliminated all overbooking in high season. The system processed over 8,000 bookings without a single conflict.
PMS Integration
Property Management System — the hotel's brain. We integrate via:
- Synchronization of room inventory and statuses (available, occupied, cleaning).
- Automatic creation of booking in PMS upon online order via webhook.
- Retrieval of statuses (confirmed, checked in, checked out) for guest digital profile.
The integration is based on REST API. We handle error states (e.g., PMS timeout) with queued retry logic and manual fallback.
Guest Digital Profile and Bitrix24 CRM — Loyalty Ecosystem
The guest profile is not just "order history." History of stays, loyalty program with points and statuses, saved preferences (high floor, pillow type) are stored in UF_* fields. A returning guest appreciates being remembered.
CRM based on Bitrix24 complements PMS. A guest card with spent amount, preferences, automated robot chains:
- Pre-arrival (3 days before check-in) — email with information, transfer offer.
- Check-out +1 day — thank you, review request.
- Check-out +30 days — personalized repeat offer (e.g., "Welcome back, 10% discount").
SEO and Mobile Version: Competing with Booking
Booking dominates organic search. The key to success is long-tail and local queries:
- Local SEO — optimization for "hotel in downtown with pool."
- Schema markup
Hotel, LodgingBusiness, Offer with prices — rich snippets can increase CTR by 20–30%.
- Google Hotel Ads — feed via Google Hotel Center, prices alongside OTAs.
- Content with guides and attractions.
Mobile version — the majority of bookings. Form in 3–4 steps, native date picker, autofill for returning guests, PWA with push notifications. Map integration — route to hotel in one tap.
Common Mistakes in Hotel Website Development
- Ignoring caching (
BX_COMPOSITE_CACHE) — booking pages load very slowly, causing a 30% bounce rate.
- Not accounting for time zones — guests from other regions see incorrect check-in time, leading to confusion and cancellations.
- Single-table availability model without indexes — SQL queries on many rooms take seconds instead of milliseconds.
Fixing each mistake typically saves the hotel a significant portion of lost bookings — up to 15–20% recovery.
What's Included in the Deliverables
| Deliverable |
Description |
| Technical specification |
Detailed business process descriptions, integration schemes |
| Design prototypes |
Wireframes for booking flow, admin panel |
| Source code |
Git repository with custom modules, PHP 8.1+, HL blocks, migrations |
| API documentation |
Endpoints, authentication, error handling |
| Test credentials |
Access to test environment, error logs |
| Training |
Video instructions for staff, access handover |
| Post-launch support |
30 days of bug fixes and minor adjustments |
Our Experience and Company Metrics
Over 12 years of building hotel websites on 1C-Bitrix. Completed 80+ projects for hotels, hostels, and apartment owners. Our team holds official 1C-Bitrix certifications. We have successfully integrated with Travelline, Bnovo, YooKassa, and major OTAs. Contact us to get a portfolio of similar projects.
Process Workflow
| Stage |
Documentation and Artifacts |
| Analytics |
Technical specification with business process descriptions, integration schemes |
| Design |
Screen prototypes, database architecture, flow diagrams |
| Development |
Source code in Git (Bitrix Framework + custom modules, PHP 8.1+, HL blocks) |
| Integration |
API documentation, test credentials, error logs |
| Testing |
Load testing (hundreds of parallel bookings), regression testing |
| Deployment and Training |
Launch, video instructions, access handover |
Development Timelines
| Project Type |
Timeline |
| Hotel website (without booking) |
2–3 weeks |
| Website with Booking Engine |
2–3 months |
| Full platform (booking + PMS + Channel Manager) |
3–5 months |
| Hotel chain (multisite + unified CRM) |
4–6 months |
The cost is calculated individually based on your requirements, room count, integration complexity. Contact us for a detailed estimate. Hotel website development on 1C-Bitrix is an investment in direct sales that pays off quickly — typically within 3–6 months.