Сайт гостиницы на 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 Appointment Booking Widget for a Medical Center
    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С-Битрикс. Закажите разработку сайта гостиницы — мы подберём архитектуру под ваш номерной фонд. Получите консультацию по архитектуре вашего сайта — оценим задачу и предложим решение.