Сайт готелю на 1С-Бітрікс: онлайн-бронювання та PMS-інтеграція

Готельний сайт відрізняється від звичайного каталогу тим, що відвідувач обирає не товар, а часовий слот. Номер сам по собі — набір характеристик (площа, місткість, вид з вікна). Але без вільних дат це мертва картка. Весь проєкт будується навколо календаря доступності та механіки бронювання, а не нав
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
Сайт готелю на 1С-Бітрікс: онлайн-бронювання та PMS-інтеграція
Складний
від 1 тижня до 3 місяців

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1415
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    996
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    735
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    863
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    773
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1134

Готельний сайт відрізняється від звичайного каталогу тим, що відвідувач обирає не товар, а часовий слот. Номер сам по собі — набір характеристик (площа, місткість, вид з вікна). Але без вільних дат це мертва картка. Весь проєкт будується навколо календаря доступності та механіки бронювання, а не навколо красивої верстки. Проблема: відвідувач бачить красиві фото, але при спробі забронювати — календар не оновлений або ціна не відповідає сезону. Або інтеграція з Booking.com відсутня, і готель отримує овербукінг. Ми вирішуємо ці проблеми на рівні архітектури: двигун бронювання на Highload-блоках, сезонні тарифи, синхронізація з PMS.

Як працює система бронювання?

Ядро проєкту — управління доступністю номерів. Завдання: користувач обирає дати, система показує доступні типи з цінами, бронює та блокує номер.

Зберігання доступності — Highload-блок RoomInventory. Кожен рядок — одна ніч для одного фізичного номера.

Поле Тип Опис
UF_DATE date Дата ночі (наприклад, 2025-07-15 — ніч з 15 на 16 липня)
UF_ROOM_ID integer ID фізичного номера
UF_ROOM_TYPE_ID integer ID типу номера
UF_STATUS integer 0 = вільний, 1 = заброньований, 2 = заблокований, 3 = заселений
UF_BOOKING_ID integer ID замовлення (з модуля sale)
UF_RATE float Тариф за цю ніч (з урахуванням сезону)

Highload-блок — ORM-обгортка над таблицею з автоматичним API. При 100 номерах і горизонті 365 днів — 36 500 рядків. Обов'язкові індекси: складений на (UF_DATE, UF_ROOM_TYPE_ID, UF_STATUS) та (UF_BOOKING_ID).

Алгоритм перевірки доступності. Гість вводить check_in, check_out, guests. Система знаходить типи номерів з хоча б одним фізичним номером, вільним на всі ночі.

public function getAvailableRoomTypes( \Bitrix\Main\Type\Date $checkIn, \Bitrix\Main\Type\Date $checkOut, int $guests ): array { $nights = $checkOut->getDiff($checkIn)->days; $dates = []; for ($i = 0; $i < $nights; $i++) { $d = clone $checkIn; $d->add(new \DateInterval("P{$i}D")); $dates[] = $d->format('Y-m-d'); } // Знаходимо номери, зайняті хоча б в одну з ночей $busyRooms = RoomInventoryTable::getList([ 'select' => ['UF_ROOM_ID'], 'filter' => [ 'UF_DATE' => $dates, '!UF_STATUS' => 0, ], 'group' => ['UF_ROOM_ID'], ])->fetchAll(); $busyRoomIds = array_column($busyRooms, 'UF_ROOM_ID'); // Далі — виключаємо зайняті номери та фільтруємо за місткістю } 

Підхід через HAVING COUNT(*) = {$nights} коректніший:

SQL-запит перевірки доступності
SELECT UF_ROOM_ID, UF_ROOM_TYPE_ID FROM hl_room_inventory WHERE UF_DATE IN ('2025-07-15','2025-07-16','2025-07-17') AND UF_STATUS = 0 GROUP BY UF_ROOM_ID, UF_ROOM_TYPE_ID HAVING COUNT(*) = 3 

Календар доступності на фронті. Два поля — дата заїзду та виїзду. Реалізація на flatpickr у режимі range. При відкритті — AJAX-запит за матрицею доступності: масив дат з ознакою «є вільні номери». Endpoint повертає JSON:

{ "2025-07": { "15": {"available": true, "min_rate": 4500}, "16": {"available": true, "min_rate": 4500}, "17": {"available": false, "min_rate": null}, "18": {"available": true, "min_rate": 6200} } } 

Недоступні дати блокуються в календарі (disable). Мінімальний тариф — при наведенні. Запити кешуються через Bitrix\Main\Data\Cache з ключем availability_{month}_{year}.

Чому сезонне ціноутворення збільшує прибуток?

Highload-блок RatePlan:

Поле Тип
UF_ROOM_TYPE_ID integer
UF_DATE_FROM date
UF_DATE_TO date
UF_WEEKDAY_RATE float
UF_WEEKEND_RATE float
UF_PRIORITY integer

При розрахунку вартості бронювання система перебирає кожну ніч, знаходить відповідний тарифний план і підсумовує. Підсумкова сума — сума по всіх ночах.

Архітектура номерного фонду

Кожен тип номера — елемент інфоблоку «Номерний фонд». Важливо розділяти тип (наприклад, «Стандарт двомісний») та фізичні номери (20 кімнат). Це ключове архітектурне рішення.

Структура інфоблоку:

Властивість Тип Призначення
CAPACITY N (число) Місткість (основні місця)
CAPACITY_EXTRA N Дод. місця (розкладачка, дитяче ліжечко)
AREA N Площа, м²
AMENITIES L (список, множинне) Зручності: Wi-Fi, кондиціонер, міні-бар, сейф
BED_TYPE L (список) Тип ліжка: double, twin, king
VIEW L (список) Вид: море, місто, сад, двір
FLOOR_RANGE S (рядок) Поверхи: «3-5»
GALLERY F (файл, множинне) Фотогалерея номера
PANORAMA_URL S Посилання на 360-панораму
ROOM_COUNT N Кількість фізичних номерів цього типу
MIN_STAY N Мінімальна кількість ночей
BASE_RATE N Базовий тариф за ніч (без сезонних націнок)

Зручності (AMENITIES) — множинна властивість типу «Список». Не Highload-блок, тому що набір фіксований (30-50 позицій). На фронті значення маппяться на іконки через конфіг.

Фотогалерея та віртуальний тур. Множинна властивість типу «Файл». Рендер — Swiper.js з lazy-завантаженням, прев'ю через CFile::ResizeImageGet() на 600x400 з BX_RESIZE_IMAGE_PROPORTIONAL. Для 360-панорами — Pannellum.js: бібліотека приймає equirectangular-зображення та рендерить інтерактивний огляд. Зберігання — рядкова властивість PANORAMA_URL. Pannellum ініціалізується на клієнті:

pannellum.viewer('panorama-container', { type: 'equirectangular', panorama: roomData.panoramaUrl, autoLoad: true, compass: true, hotSpots: [ { pitch: -5, yaw: 120, type: 'info', text: 'Ванна кімната' }, { pitch: 0, yaw: 240, type: 'info', text: 'Балкон з видом на море' } ] }); 

Hotspots задаються в JSON-властивості інфоблоку або в Highload-блоці, якщо потрібна адмін-панель.

Як iCal-синхронізація запобігає овербукінгу?

Готель продає номери на сайті та через OTA (Booking.com, Expedia). Без синхронізації — овербукінг. Channel Manager синхронізує доступність та тарифи між PMS, сайтом і каналами.

iCal-синхронізація — найпростіший варіант. Booking.com та Airbnb віддають .ics-файли. Бітрікс-агент раз на 15 хвилин:

  1. Забирає .ics за URL (file_get_contents або cURL)
  2. Парсить VEVENT — вилучає DTSTART, DTEND, SUMMARY
  3. Оновлює RoomInventory: UF_STATUS = 2 (заблокований)
  4. Генерує вихідний .ics з бронюваннями сайту

Обмеження iCal: немає тарифів, затримка до 15 хвилин. Для 100+ номерів потрібен API-коннектор. XML Push / API — через REST або SOAP (Booking.com Connectivity API). iCal-синхронізація в 10 разів простіша за API-інтеграцію, але менш гнучка.

PMS-інтеграція. 1С:Отель — обмін через HTTP-сервіс. Opera / Fidelio — SOAP з WSDL. Ми реалізуємо клас-обгортку над SoapClient з логуванням.

Онлайн-оплата та передоплата. Бронювання через модуль sale. Замовлення — одна позиція «Проживання в {тип}, {check_in} — {check_out}. Передоплата (20-30%) — кастомний обробник OnSaleBeforeOrderAdd`. Відсоток і перша ніч — типові схеми.

Додаткові модулі

Особистий кабінет гостя: авторизація (email + OAuth), мої бронювання, історія поїздок, програма лояльності. Бали нараховуються через обробник OnSaleStatusOrderChange.

Мультимовність: мовні версії (/en/, /de/), контент через властивості інфоблоків, hreflang. SEO та мікророзмітка: Schema.org Hotel + HotelRoom + Offer. Розмітка генерується автоматично.

Фотоцентричний дизайн: WebP з fallback, <picture> з srcset, lazy-load. Оригінали до 3000px, прев'ю 800x600.

Відгуки: Highload-блок Reviews з модерацією. Агрегований рейтинг у властивості інфоблоку AVG_RATING.

Що входить в роботу

  • Аналітика та прототипування (карта номерного фонду, логіка бронювання)
  • Дизайн (фотоцентричний UI, мобільна версія, календар)
  • Ядро бронювання (RoomInventory, перевірка доступності, оформлення замовлення, оплата)
  • Інтеграції (PMS, Channel Manager, платіжні системи, REST API)
  • Контент та SEO (мікророзмітка, мультимовність, мета-шаблони)
  • Тестування та запуск (навантажувальне, кросбраузерне, деплой)
  • Документація та навчання адміністраторів
  • Постпроєктний супровід та гарантія

Етапи та терміни

Масштаб Терміни
Міні-готель, 10-20 номерів, базове бронювання 4–8 тижнів
Готель, 50-100 номерів, Channel Manager, PMS 10–16 тижнів
Мережа готелів, мультисайт, програма лояльності 16–24 тижні

Терміни не включають фотосесію та створення 360-панорам — це паралельний процес.

Пряме бронювання через сайт у 2-3 рази вигідніше для готелю, ніж через OTA, за рахунок відсутності комісії. Економія становить 15-25% від виручки. Система бронювання окупається в середньому за 6-12 місяців за рахунок зростання прямих продажів.

Ми працюємо в готельній розробці понад 8 років, виконали понад 50 проєктів для готельного бізнесу. Наші інженери — сертифіковані спеціалісти 1С-Бітрікс. Замовте розробку сайту готелю — ми підберемо архітектуру під ваш номерний фонд. Отримайте консультацію щодо архітектури вашого сайту — оцінимо завдання та запропонуємо рішення.