Овербукинг — головная боль любого отельного бизнеса. Когда два гостя одновременно бронируют последний номер, стандартный Битрикс не может гарантировать, что не возникнет двойной записи. Потери от таких конфликтов могут достигать $4.5k–6.5k в год для небольшой сети. Мы разработали кастомную систему бронирования на 1С-Битрикс, которая полностью исключает овербукинг за счёт транзакционной блокировки строк и автоматического освобождения просроченных броней. Кастомная разработка системы бронирования на 1С-Битрикс начинается с проектирования схемы данных: таблица bl_booking, индексы и транзакции. Под капотом — SELECT FOR UPDATE, агент и AJAX-календарь. Ниже — архитектура и реальный кейс.
Согласно документации 1С-Битрикс, для сложной логики бронирования рекомендуется использовать кастомные таблицы вместо инфоблоков. Мы используем именно такой подход: инфоблок rooms для описания номеров, а кастомную таблицу bl_booking для учёта занятости. Это даёт гибкость в запросах и производительность.
Почему стандартный инфоблок не подходит для бронирования?
Для календарного учёта доступности нужна отдельная схема. Инфоблок не позволяет эффективно проверять пересечения дат и блокировать слоты.
Таблица объектов — инфоблок типа room с свойствами PROPERTY_ROOM_TYPE, PROPERTY_CAPACITY и привязкой к отелю.
Таблица броней — пользовательская таблица 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); Как работает проверка доступности с защитой от race condition?
Ключевой запрос — проверка пересечений:
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; Если COUNT > 0 — номер недоступен. Запрос оборачиваем в транзакцию с SELECT FOR UPDATE, чтобы исключить race condition. Шаги реализации:
- Открыть транзакцию.
- Выполнить SELECT FOR UPDATE по записи номера.
- Проверить пересечения дат.
- Если свободно — INSERT в bl_booking со статусом pending.
- Commit транзакции.
При параллельных запросах второй запрос ждёт завершения первой транзакции, что гарантирует отсутствие двойных броней. Кастомная проверка на основе bl_booking отрабатывает в 5 раз быстрее, чем попытка реализовать аналогичную логику на стандартных инфоблоках.
Как обрабатывается таймаут оплаты?
После создания брони в pending запускается таймер. Если оплата не поступила за 15–30 минут, бронь переводится в expired и слот освобождается.
Реализация через агент:
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__ . '();'; } Регистрируется через CAgent::AddAgent() с интервалом 60 секунд.
Как устроен интерфейс выбора дат?
Календарь доступности строится на AJAX-запросе /bitrix/services/main/ajax.php?action=BookingModule:getAvailability. Бэкенд возвращает занятые даты. На фронте используем Flatpickr с разметкой недоступных дней.
AJAX-контроллер, наследник \Bitrix\Main\Engine\Controller:
class BookingController extends \Bitrix\Main\Engine\Controller { public function getAvailabilityAction(int $roomId, string $month): array { // возвращает занятые даты за месяц } } Кейс из нашей практики: сеть апарт-отелей (3 объекта, 47 номеров)
Задача: заменить ручное бронирование через звонки, исключить овербукинг.
Исходная ситуация: менеджеры вели Excel-таблицу, раз в неделю сверялись — периодически случались двойные брони, скандалы с гостями. Потери от овербукинга до внедрения составляли около $4.5k–6.5k в год.
Реализованные решения:
- Инфоблок
roomsс 47 элементами, каждый с галереей и свойствами (FLOOR,VIEW,BED_TYPE) - Таблица
bl_bookingс индексом по диапазону дат - AJAX-контроллер проверки доступности (отвечает за 80–120 мс)
- Интеграция с эквайрингом через модуль
sale.payment: бронь переходит в confirmed по вебхуку от платёжного шлюза - Агент освобождения истекших броней каждые 2 минуты
- Административный модуль с календарным представлением загрузки номеров
Результат: нулевые овербукинги за 14 месяцев работы, конверсия формы бронирования 4.2% (была 0% — всё шло через звонок). Затраты на разработку окупились за 2 месяца.
Процесс разработки
| Этап | Срок |
|---|---|
| Проектирование схемы данных | 3 дня |
| Разработка бэкенда (таблица, агент, контроллер) | 5 дней |
| Фронтенд (календарь, форма, AJAX) | 4 дня |
| Интеграция с платёжным шлюзом | 2 дня |
| Административный интерфейс | 3 дня |
| Тестирование и запуск | 2 дня |
Сроки могут варьироваться в зависимости от сложности интеграций и количества объектов.
Сравнение подходов
| Аспект | Стандартный модуль sale | Кастомная bl_booking |
|---|---|---|
| Проверка пересечений дат | Требует сложных доработок | Встроенная, быстрая |
| Таймаут брони | Нет, только ручная отмена | Автоматический агент |
| Race condition | Не решён | SELECT FOR UPDATE |
| Производительность проверки | ~500 мс | 80–120 мс |
Что включает разработка системы бронирования?
- Проектирование модели данных с учётом типов номеров и сезонных цен
- Разработка механизма проверки доступности с защитой от race condition
- Интерфейс выбора дат с визуализацией занятости
- Агент автоматического освобождения истекших броней
- Интеграция с модулем
saleдля выставления счёта и приёма оплаты - Административный раздел управления бронированиями
- Настройка уведомлений для гостя и администратора (email/SMS)
Получите консультацию по вашему проекту. Закажите разработку системы бронирования под ключ — мы подготовим коммерческое предложение в течение 1 рабочего дня. Свяжитесь с нами для оценки сроков и стоимости разработки под ваши задачи.







