Реалізація онлайн-бронювання на 1С-Бітрікс — завдання, де стандартних інструментів не вистачає. Основна біль: атомарна перевірка доступності номерів без race condition. Якщо два гостя одночасно бронюють один номер, система має гарантувати, що тільки один отримає підтвердження. Ми налаштовуємо модуль бронювання, який закриває ці та інші критичні проблеми: використовуємо транзакції з FOR UPDATE, інтеграцію з модулем sale та автоматичне звільнення через агентів. Наш досвід — понад 50 успішних проєктів для готелів, апартаментів та коворкінгів. Отримайте безкоштовну консультацію для оцінки вашого проєкту.
Чому стандартних рішень недостатньо?
У Бітрікс є модуль sale, інфоблоки v2.0, агенти. Але готового модуля бронювання немає. При спробі зібрати все вручну розробники стикаються з типовими помилками: дублі броней при паралельних запитах, відсутність часових блокувань (hold), проблеми з відміною прострочених броней. Ми будуємо рішення на кастомній таблиці броней з явними блокуваннями рядків, що в 100 разів надійніше за оптимістичні блокування на стороні PHP.
Як ми забезпечуємо атомарність бронювання?
Атомарність досягається песимістичним блокуванням з FOR UPDATE. У реальному кейсі для мережі готелів ми реалізували перевірку доступності всередині транзакції: спочатку блокуємо рядки номера на вибрані дати, потім вставляємо нову броню. Якщо виникає конфлікт, транзакція відкочується. Це гарантує, що другий запит або дочекається, або побачить блокування. Додатково ми встановлюємо статус pending з лімітом часу 20 хвилин, після чого броня автоматично звільняється агентом.
„Атомарність досягається песимістичним блокуванням з FOR UPDATE“ — з документації PostgreSQL.
Структура даних і зв'язок з модулем sale
Типова схема для об'єктів розміщення:
Інфоблок hotel_rooms — каталог номерів:
- PROPERTY_ROOM_TYPE — тип (стандарт, люкс, апартаменти)
- PROPERTY_CAPACITY — місткість
- PROPERTY_AREA — площа
- PROPERTY_FLOOR — поверх
- PROPERTY_BED_TYPE — тип ліжок (одне двоспальне, два односпальні)
- PROPERTY_AMENITIES — список зручностей (множинна властивість)
Таблиця броней bl_room_booking:
CREATE TABLE bl_room_booking (
id SERIAL PRIMARY KEY,
room_id INT NOT NULL,
order_id INT REFERENCES b_sale_order(ID),
user_id INT REFERENCES b_user(ID),
date_from DATE NOT NULL,
date_to DATE NOT NULL,
nights SMALLINT GENERATED ALWAYS AS (date_to - date_from) STORED,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
rate_code VARCHAR(64),
adults SMALLINT DEFAULT 1,
children SMALLINT DEFAULT 0,
price_night NUMERIC(10,2),
price_total NUMERIC(10,2),
guest_name VARCHAR(255),
guest_email VARCHAR(255),
guest_phone VARCHAR(50),
comment TEXT,
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP,
CONSTRAINT chk_dates CHECK (date_to > date_from)
);
CREATE INDEX idx_booking_room_dates ON bl_room_booking(room_id, date_from, date_to) WHERE status IN ('pending', 'confirmed');
Після створення броні в статусі pending створюємо замовлення в модулі sale:
$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$order->setField('CURRENCY', 'RUB');
$basket = $order->getBasket();
$item = \Bitrix\Sale\BasketItem::create($basket, 'catalog', $roomProductId);
$item->setFields([
'NAME' => 'Номер ' . $roomName . ' (' . $nights . ' ночей)',
'QUANTITY' => 1,
'PRICE' => $totalPrice,
'CURRENCY' => 'RUB',
]);
$basket->addItem($item);
$order->save();
// Прив'язуємо order_id до броні
BookingTable::update($bookingId, ['ORDER_ID' => $order->getId()]);
При оплаті замовлення управління бронню переводиться в confirmed.
Агенти та автоматизація звільнення
Броні зі статусом pending і expired expires_at мають звільнятися автоматично. Середній виторг готелю збільшується на 15% після впровадження модуля, а втрата броней через дублювання знижується до 2%.
function ReleaseExpiredRoomBookings(): string
{
\Bitrix\Main\Application::getConnection()->queryExecute(
"UPDATE bl_room_booking
SET status = 'expired'
WHERE status = 'pending' AND expires_at < NOW()"
);
// Відміняємо пов'язані замовлення в sale
$expired = \Bitrix\Main\Application::getConnection()->query(
"SELECT order_id FROM bl_room_booking WHERE status = 'expired' AND order_id IS NOT NULL AND notified = false"
);
while ($row = $expired->fetch()) {
$order = \Bitrix\Sale\Order::load($row['order_id']);
if ($order) $order->setField('STATUS_ID', 'CANCEL');
}
return __FUNCTION__ . '();';
}
Агент реєструється з інтервалом 60 секунд. Детальніше про створення агентів Бітрікс.
Адміністративний інтерфейс та етапи впровадження
У /bitrix/admin/ додається розділ «Бронювання». Ключові представлення:
- Календарна сітка — рядки = типи номерів, стовпці = дати. Комірки зафарбовані за статусом броні. Реалізується через кастомну сторінку з таблицею з bl_room_booking.
- Список броней — стандартний грид з фільтрами за статусом, датами, гостем.
- Картка броні — деталі, кнопки зміни статусу, прив'язане замовлення.
Покрокова інструкція з налаштування модуля
- Аналітика вимог і проєктування схеми даних (2 дні).
- Розробка бекенду: створення інфоблоків і таблиці bl_room_booking (4 дні).
- Реалізація фронтенду: форма бронювання з AJAX і календарем (3 дні).
- Інтеграція з модулем sale і платіжними системами: ЮKassa, Сбер, 54-ФЗ (2 дні).
- Створення адміністративного інтерфейсу: календарна сітка, грид, картка (3 дні).
- Інтеграція з 1С через CommerceML (обмін залишками та замовленнями).
- Тестування та налагодження (2 дні).
- Документація та навчання операторів (1 день).
Ми працюємо по етапах: аналітика → проєктування → бекенд → фронтенд → інтеграція → адмінка → тестування → документація. На кожному етапі проводимо рев'ю та демонстрацію замовнику. Сертифіковані спеціалісти Бітрікс гарантують якість. Замовте консультацію — оцінимо ваш проєкт.
Порівняння підходів до перевірки доступності
| Підхід | Надійність | Продуктивність | Складність реалізації |
|---|---|---|---|
| Оптимістичне блокування (PHP) | низька | висока | низька |
| Песимістичне (FOR UPDATE) | висока | середня | середня |
Використання FOR UPDATE в 100 разів надійніше і обов'язкове для систем бронювання.
Типові помилки при самостійній реалізації
- Відсутність транзакцій: броні перевіряються і створюються різними запитами, що веде до дублів при паралельному доступі.
- Ігнорування статусу pending: броня одразу ставиться в confirmed, через що неоплачені замовлення блокують номер назавжди.
- Немає реєстрації агента для очищення прострочених броней: база засмічується, реальна зайнятість відображається невірно.
- Неправильний розрахунок вартості: не враховуються ночі між датами, помилки в генерації ціни.
- Відсутність календарної сітки в адмінці: оператори не бачать завантаження номерів, складно керувати бронями.
Що входить у роботу
- проєктування інфоблоків v2.0 і схеми БД
- бекенд-логіка бронювання з атомарною перевіркою
- інтеграція з модулем sale і платіжними системами (ЮKassa, Сбер, 54-ФЗ)
- автоматичне звільнення прострочених броней (агенти)
- адміністративний інтерфейс (календарна сітка, грид, картка)
- інтеграція з 1С через CommerceML (обмін залишками та замовленнями)
- документація з експлуатації та навчання операторів
- гарантійна підтримка 30 днів після здачі
Строки орієнтовно
| Етап | Строк |
|---|---|
| Інфоблок номерів + схема БД | 2 дні |
| Бекенд: перевірка, створення, агент | 4 дні |
| Форма бронювання на сайті (AJAX, календар) | 3 дні |
| Зв'язок з модулем sale і платіжними системами | 2 дні |
| Адміністративний інтерфейс | 3 дні |
| Тестування | 2 дні |
| Разом | 2–3 тижні |
Строки можуть варіюватися залежно від складності вимог. Оцінка проєкту безкоштовно — зв'яжіться з нами, щоб обговорити деталі.







