API виджета бронирования v1 (hmsExternalPrices)

Версия: v1 | Статус: Deprecated (не поддерживается) | Лицензия: Бронирование онлайн | Продукт: Shelter Cloud | Уровень: Дилерский

Оглавление


Общее описание

API виджета бронирования (hmsExternalPrices) предназначено для создания собственного модуля онлайн-бронирования на сайте отеля или сторонней платформе.

Возможности API:

  • Получение справочников: тарифы, категории номеров, типы питания, дополнительные услуги
  • Проверка доступности номеров по датам
  • Поиск вариантов размещения по заданным параметрам (даты, количество гостей) с ценами
  • Подбор альтернативных дат при отсутствии свободных номеров
  • Создание и отмена бронирования
  • Проверка статуса оплаты заказа

Базовый URL: https://cloud.shelter.ru/externalPrices/

Требование: Для работы API необходима активная лицензия на модуль «Бронирование онлайн». Без этого модуля API не будет функционировать.

Postman-коллекция: Готовые запросы ко всем методам — ExternalPrices_v1.postman_collection.json

Два режима ответа:

Режим Условие Content-Type Формат
JavaScript По умолчанию text/html fd_avails = [...]; (JS-переменная)
JSON Параметр json или plainJson application/json Чистый JSON-массив

Примечание: JSON-режим поддерживается только в методах jsAvailables и jsSearchJoin. Методы jsTariffs, jsExtrtaServices, jsAlternatives и jsOrderStatus всегда возвращают JavaScript.


Аутентификация

API использует токен отеля для идентификации. Токен представляет собой UUID (36 символов), например: <токен>.

Для методов поиска и чтения (jsTariffs, jsAvailables, jsSearchJoin, jsAlternatives, jsExtrtaServices, jsOrderStatus) используется публичный токен.

Для методов создания и отмены бронирования (CreateOrder, AnnulateOrder) используется приватный токен.

Получение публичного токена

  1. Войти в интерфейс Shelter Cloud
  2. Нажать на имя пользователя в правом верхнем углу
  3. Перейти на вкладку «Онлайн для сайта»
  4. Скопировать токен

Получение приватного токена

Приватный токен доступен только через прямую ссылку: https://cloud.shelter.ru/shelter-cloud/#/tokens (тип токена — PrivateToken). Данный экран не отображается в меню интерфейса.

Обратите внимание: Для получения приватного токена обратитесь в техподдержку Shelter.


Типовой сценарий бронирования

1. Получение справочных данных
   └── jsTariffs (тарифы, категории, питание)
   └── jsExtrtaServices (доп. услуги)

2. Поиск доступности
   ├── jsAvailables (периоды доступности)
   └── jsSearchJoin (варианты размещения с ценами)
       └── Если нет вариантов → jsAlternatives (альтернативные даты)

3. Создание бронирования
   └── CreateOrder (POST с данными гостей)

4. Управление бронированием
   ├── jsOrderStatus / CheckPayment (проверка оплаты)
   └── AnnulateOrder (отмена)

Методы API


jsTariffs — Тарифы, категории номеров и типы питания

URL: GET /externalPrices/jsTariffs.aspx

Назначение: Возвращает все активные тарифы с ценами, категории номеров и типы питания для отеля.

Параметры запроса

Параметр Тип Обяз. Описание
token string Да Токен отеля

Пример запроса

GET /externalPrices/jsTariffs.aspx?token=<токен>

Формат ответа

Ответ всегда в формате JavaScript и содержит три переменных:

fd_tariffs — массив тарифов:

fd_tariffs = [
  {
    id: 123,                    // ID тарифа
    name: 'Стандартный',        // Название
    code: 'STANDARD',          // Код тарифа
    comment: 'Описание',       // Комментарий (может отсутствовать)
    hours4Prepayment: 72,      // Часов на предоплату (может отсутствовать)
    prepayment: 20,            // Размер предоплаты (может отсутствовать)
    prepaymentType: '%',       // Тип предоплаты (может отсутствовать), см. ниже
    costs: [                   // Массив цен
      {
        cost: 3500.00,         // Цена
        from: new Date(2025, 0, 1),   // Дата начала (формат JavaScript: месяц 0-индексирован, 0=Январь)
        to: new Date(2025, 11, 31),   // Дата окончания (11=Декабрь)
        roomId: 45,            // ID категории номера
        roomCode: 'DBL',       // Код категории (может отсутствовать)
        boardingId: 5,         // ID типа питания (может отсутствовать)
        boardingCode: 'HB',    // Код типа питания (может отсутствовать)
        ageFrom: 0,            // Возраст от (может отсутствовать = для всех)
        ageTo: 12,             // Возраст до (может отсутствовать = для всех)
        extraBed: true,        // true = цена для доп. места (может отсутствовать)
        type: 'perPerson',     // Тип цены (см. ниже)
        guests: 2,             // Кол-во гостей в номере (может отсутствовать = для всех)
        guestSerialNumber: 1,  // Порядковый номер гостя (может отсутствовать = для всех)
        weeks: '12345',        // Дни недели: 1=Пн...7=Вс (может отсутствовать = все)
        minLength: 3,          // Мин. продолжительность (может отсутствовать)
        maxLength: 7,          // Макс. продолжительность (может отсутствовать)
        period: 'night'        // Период расчёта цены (см. ниже)
      }
    ]
  }
];

Типы цены (type):

  • perPerson — за человека
  • perRoom — за номер
  • perBed — за койко-место
  • perMotherAndChild — за мать и дитя

Период (period):

  • night — за ночь
  • day — за день (сутки)
  • arrival — за заезд

Тип предоплаты (prepaymentType):

  • % — процент от стоимости проживания. Значение prepayment указывает процент (например, 20 = 20%)
  • fix — фиксированная сумма. Значение prepayment указывает сумму в валюте отеля
  • 24hours — предоплата за первые сутки проживания. Значение prepayment указывает количество суток, за которые взимается предоплата (например, 2 = предоплата за 2 первых суток)

fd_rooms — массив категорий номеров:

fd_rooms = [
  {
    id: 45,                    // ID категории
    name: 'Двухместный',       // Название
    code: 'DBL',               // Код
    allowByBeds: true,         // Бронирование по койко-местам (может отсутствовать)
    allowByRooms: true,        // Бронирование номера целиком (может отсутствовать)
    building: 'Корпус А',     // Корпус (может отсутствовать)
    comment: 'Вид на море',   // Комментарий (может отсутствовать)
    images: [                  // Изображения (может отсутствовать)
      { path: 'http://...', pathSmall: 'http://...' }
    ],
    mainBeds: 2,               // Основных мест
    extraBeds: 1               // Дополнительных мест
  }
];

fd_boardings — массив типов питания:

fd_boardings = [
  {
    id: 5,                     // ID типа питания
    name: 'Полупансион',       // Название
    code: 'HB'                // Код
  }
];

Если нет типов питания, возвращается fd_boardings = undefined;


jsAvailables — Доступность номеров по датам

URL: GET /externalPrices/jsAvailables.aspx

Назначение: Возвращает периоды доступности номеров в заданном диапазоне дат.

Параметры запроса

Параметр Тип Обяз. Описание
token string Да Токен отеля
dateFrom string Да Дата начала (любой формат DateTime, автоматически >= сегодня)
dateTo string Да Дата окончания
roomId int Нет Фильтр по ID категории номера
guestsCount int Нет Кол-во гостей
source string Нет Источник перехода (URL)
json / plainJson — Нет Включить JSON-формат ответа

Пример запроса

GET /externalPrices/jsAvailables.aspx?token=e4922afa-...&dateFrom=2025-03-01&dateTo=2025-03-31&json

Валидация

  • dateFrom автоматически устанавливается не раньше сегодня
  • dateFrom <= dateTo
  • Диапазон не более 366 дней
  • Токен должен быть валидным (hotelId > 0)

Формат ответа

JavaScript-режим:

fd_periodAvailables = [
  { dateFrom: '2025-03-01', dateTo: '2025-03-15', onlyByRequest: false },
  { dateFrom: '2025-03-20', dateTo: '2025-03-31', onlyByRequest: true }
];

JSON-режим:

[
  { "dateFrom": "2025-03-01", "dateTo": "2025-03-15", "onlyByRequest": false },
  { "dateFrom": "2025-03-20", "dateTo": "2025-03-31", "onlyByRequest": true }
]
Поле Тип Описание
dateFrom string (yyyy-MM-dd) Начало периода доступности
dateTo string (yyyy-MM-dd) Конец периода доступности
onlyByRequest bool true = доступно только по запросу

jsSearchJoin — Поиск вариантов размещения с ценами

URL: GET /externalPrices/jsSearchJoin.aspx

Назначение: Основной метод поиска. Возвращает полную информацию о доступных вариантах размещения: цены, детализацию по дням, данные о номере, тарифе, питании и отеле.

Параметры запроса

Параметр Тип Обяз. Описание
arrival string Да Дата заезда
depart string Да Дата выезда
adults int Да Кол-во взрослых
childs int Нет Кол-во детей (по умолч. 0)
ages string Нет* Возраста детей через запятую (напр. 5,8,12). *Обязательно если childs > 0
promo string Нет Промокод
lang string Нет Язык (по умолч. ru)
filter string Да Фильтр отелей/номеров/тарифов (см. формат ниже)
source string Нет Источник перехода (URL)
byHours string Нет 1 = почасовое бронирование
json / plainJson — Нет Включить JSON-формат ответа

Формат параметра filter

[{token:<токен>}]

С фильтрацией по тарифу и категории:

[{token:e4922afa-...,tariff:STANDARD,room:DBL}]

С фильтрацией по ID:

[{token:e4922afa-...,tariffId:123,roomId:45}]

Несколько отелей:

[{token:token1},{token:token2}]

Пример запроса

GET /externalPrices/jsSearchJoin.aspx?arrival=2025-03-01&depart=2025-03-05&adults=2&childs=1&ages=8&filter=[{token:<токен>}]&json

Валидация

  • departure >= arrival
  • guestsCount (adults + childs) > 0
  • Диапазон дат не более 180 дней (6 месяцев)
  • Если childs > 0, количество элементов в ages должно совпадать с childs
  • filter обязателен, в нём должен быть хотя бы один элемент с валидным токеном

Формат ответа (JavaScript-режим)

fd_avails = [
  {
    hotelId: 100,
    roomId: 45,
    byBedsVariant: false,
    tariffId: 123,
    parentTariffId: 0,
    boardingId: 5,
    count: 3,                  // Кол-во доступных номеров (undefined = по запросу)
    price: 10500.00,
    details: { ... },          // Детализация по дням
    room: { ... },             // Информация о категории
    tariff: { ... },           // Информация о тарифе
    boarding: { ... },         // Информация о питании
    hotel: { ... }             // Информация об отеле
  }
];

Формат ответа (JSON-режим)

В JSON-режиме структура отличается — используется объект AvailablesData с вложенной моделью:

[
  {
    "hotelId": 100,
    "roomId": 45,
    "byBedsVariant": false,
    "tariffId": 123,
    "parentTariffId": 0,
    "boardingId": 5,
    "count": 3,
    "price": 10500.00,
    "details": [ ... ],
    "room": { ... },
    "tariff": { ... },
    "boarding": { ... },
    "hotel": { ... }
  }
]

Логика подбора номеров

  • Система автоматически подбирает номера по вместимости
  • Номер подходит, если основных мест + доп. мест >= запрошенного кол-ва гостей
  • Сначала заполняются основные места, затем дополнительные
  • Пример: номер на 2 основных + 1 доп. место вместит 1 взрослого + 1 ребёнка + 1 младенца (младенец на доп. месте)

jsAlternatives — Альтернативные даты

URL: GET /externalPrices/jsAlternatives.aspx

Назначение: Если на запрошенные даты нет доступных вариантов, этот метод вернёт ближайшие альтернативные периоды.

Параметры запроса

Параметр Тип Обяз. Описание
arrival string Да Желаемая дата заезда
depart string Да Желаемая дата выезда
adults int Да Кол-во взрослых
childs int Нет Кол-во детей
ages string Нет* Возраста детей (*обязательно если childs > 0)
filter string Да Фильтр (формат как у jsSearchJoin)
source string Нет Источник перехода

Формат ответа

fd_alternatives = [
  { arrival: '2025-03-10', departure: '2025-03-14' },
  { arrival: '2025-03-20', departure: '2025-03-24' }
];

Если альтернатив не найдено:

fd_alternatives = [];

jsExtrtaServices — Дополнительные услуги

URL: GET /externalPrices/jsExtrtaServices.aspx

Примечание: Опечатка в названии Extrta (вместо Extra) присутствует в исходном коде и сохранена для совместимости.

Назначение: Возвращает дополнительные услуги, доступные для онлайн-заказа, сгруппированные по категориям.

Параметры запроса

Параметр Тип Обяз. Описание
token string Да Токен отеля

Формат ответа

fd_extraservices = [
  {
    group: 'Трансфер',
    services: [
      { id: 201, name: 'Трансфер из аэропорта', desciption: 'В одну сторону', cost: 2500.00 },
      { id: 202, name: 'Трансфер в аэропорт', desciption: 'В одну сторону', cost: 2500.00 }
    ]
  },
  {
    group: 'Услуги номера',
    services: [
      { id: 101, name: 'Поздний выезд', desciption: 'До 18:00', cost: 1500.00 }
    ]
  }
];

Примечание: Поле desciption (вместо description) — опечатка в исходном коде, сохранена для совместимости.


CreateOrder — Создание бронирования

URL: POST /externalPrices/CreateOrder.aspx

Назначение: Создание нового заказа с одним или несколькими бронированиями.

Параметры запроса (POST form data)

Параметр Тип Обяз. Описание
token string Да Приватный токен
publicToken string Нет Публичный токен (если используется двойная аутентификация)
data string Да JSON-массив бронирований

Формат параметра data

[
  {
    "arrival": "2025-03-01",
    "departure": "2025-03-05",
    "timeArrival": "14:30",
    "timeDeparture": "11:00",
    "adults": 2,
    "children": 1,
    "ages": [8],
    "comment": "Комментарий от гостя",
    "roomId": 45,
    "byBedsVariant": false,
    "count": 1,
    "amount": 10500.00,
    "payed": 0,
    "paymentType": 0,
    "boardingId": 5,
    "tariffId": 123,
    "contactName": "Иванов Иван Иванович",
    "contactPhone": "+7-999-123-4567",
    "contactEmail": "ivanov@example.com",
    "source": "hotel-website.ru",
    "guests": [
      {
        "surname": "Иванов",
        "name": "Иван",
        "patronymic": "Иванович",
        "phone": "+7-999-123-4567",
        "email": "ivanov@example.com",
        "age": 35,
        "birthdate": "1990-01-15"
      },
      {
        "surname": "Иванова",
        "name": "Мария",
        "patronymic": "Петровна",
        "phone": "",
        "email": "",
        "age": 32
      },
      {
        "surname": "Иванов",
        "name": "Петя",
        "age": 8
      }
    ],
    "extraservices": [
      { "id": 201, "count": 1, "date": "2025-03-01" }
    ]
  }
]

Описание полей бронирования (Reservation)

Поле Тип Обяз. Описание
arrival DateTime Да Дата заезда
departure DateTime Да Дата выезда
timeArrival string Нет Время заезда (HH:mm)
timeDeparture string Нет Время выезда (HH:mm)
adults int Да Кол-во взрослых
children int Нет Кол-во детей
ages int[] Нет Возраста детей
comment string Нет Комментарий
roomId int Да ID категории номера
byBedsVariant bool Да true = по койко-местам, false = номер целиком
count int Да Кол-во номеров (или койко-мест при byBedsVariant)
amount decimal Да Сумма
payed decimal Нет Уже оплачено
paymentType decimal Нет Способ оплаты
boardingId int Да ID типа питания
tariffId int Да ID тарифа
guests Guest[] Да Список гостей (минимум один с контактными данными)
extraservices ExtraService[] Нет Доп. услуги
contactName string Нет* ФИО контактного лица
contactPhone string Нет* Телефон контактного лица
contactEmail string Нет* Email контактного лица
source string Нет Источник бронирования

*Хотя бы одно из полей contactName/contactPhone/contactEmail должно быть заполнено.

Описание полей гостя (Guest)

Поле Тип Обяз. Описание
surname string Да* Фамилия
name string Да* Имя
patronymic string Нет Отчество
phone string Нет Телефон
email string Нет Email
age int? Нет Возраст
birthdate DateTime? Нет Дата рождения

*Для первого (основного) гостя обязательны surname и name.

Описание полей доп. услуги (ExtraService)

Поле Тип Обяз. Описание
id int Да ID услуги
count int? Нет Количество
date DateTime? Нет Дата оказания

Валидация

  • data и token обязательны
  • Массив бронирований не может быть пустым
  • Для каждого бронирования:
    • amount > 0
    • departure > arrival, departure >= сегодня
    • Минимум один гость с контактными данными
    • Время (если указано) в формате HH:mm (00:00–23:59)
    • roomId должен принадлежать отелю, определённому по токену

Формат ответа

Успех:

{
  "success": true,
  "orderId": 12345,
  "invoiceNumber": "INV-001",
  "paygateError": "",
  "apiKey": "payment-api-key",
  "guestCode": "a1b2c3d4-...",
  "error": ""
}

Ошибка:

{
  "success": false,
  "orderId": 0,
  "invoiceNumber": "",
  "paygateError": "",
  "apiKey": "",
  "guestCode": "",
  "error": "описание ошибки"
}

Возможные ошибки

Ошибка Описание
parameter data required Не передан параметр data
parameter token required Не передан параметр token
invalid publicToken {token} Публичный токен не найден
invalid privateToken Приватный токен не прошёл проверку
invalid token {token} Токен не найден
not valid format: {data} Невалидный JSON в data
invalid token or roomId: {token} roomId не принадлежит отелю
invalid time format: {time} (need HH:mm) Неверный формат времени
input not valid: {details} Ошибка валидации данных
overflow Нет свободных номеров
internal error Внутренняя ошибка сервера

Интеграция с платёжными системами

После успешного создания заказа, в зависимости от настроек отеля, автоматически создаётся платёжный документ:

  • OrderPaygate — создаётся счёт, возвращаются invoiceNumber и apiKey
  • Uniteller — создаётся ссылка на оплату

Если для отеля включен код гостя, в ответе также будет guestCode.


AnnulateOrder — Отмена бронирования

URL: POST /externalPrices/AnnulateOrder.aspx

Назначение: Отмена (аннуляция) существующего заказа.

Параметры запроса (POST form data)

Параметр Тип Обяз. Описание
token string Да Приватный токен
publicToken string Нет Публичный токен
orderId int Да ID заказа

Формат ответа

Успех:

{
  "success": true,
  "error": "",
  "orderId": 0
}

Ошибка:

{
  "success": false,
  "error": "orderId not found",
  "orderId": 0
}

Возможные ошибки

Ошибка Описание
parameter token required Не передан токен
invalid publicToken {token} Публичный токен не найден
invalid privateToken Приватный токен не прошёл проверку
invalid token {token} Токен не найден
parameter orderId required Не передан orderId
orderId not found Заказ не найден или не принадлежит отелю

jsOrderStatus — Статус оплаты заказа

URL: GET /externalPrices/jsOrderStatus.aspx

Назначение: Возвращает текущий статус оплаты заказа.

Параметры запроса

Параметр Тип Обяз. Описание
token string Да Токен отеля
orderId int Да ID заказа

Формат ответа

fd_order = 1;

Коды статусов

Код Имя Описание
-1 Annulate Полностью аннулирован
0 No Заказ не найден
1 Bron Бронь (без оплаты)
2 Prepayment Частичная оплата (предоплата)
3 Payment Полностью оплачен

CheckPayment — Проверка оплаты

URL: GET /externalPrices/CheckPayment.aspx

Назначение: Детализированная проверка статуса оплаты заказа.

Параметры запроса

Параметр Тип Обяз. Описание
token string Да Токен отеля
orderId int Да ID заказа

Формат ответа

Успех:

{
  "status": 200,
  "errorDescription": "",
  "payStatus": "PAID"
}

Ошибка (параметры не переданы):

{
  "status": 500,
  "errorDescription": "Не переданы обязательные параметры запроса",
  "payStatus": ""
}

Модели данных

Reservation (бронирование)

arrival          : DateTime      — дата заезда
departure        : DateTime      — дата выезда
timeArrival      : string        — время заезда (HH:mm)
timeDeparture    : string        — время выезда (HH:mm)
adults           : int           — кол-во взрослых
children         : int           — кол-во детей
ages             : List<int>     — возраста детей
comment          : string        — комментарий
roomId           : int           — ID категории номера
byBedsVariant    : bool          — бронирование по койко-местам
count            : int           — кол-во номеров/мест
amount           : decimal       — сумма
payed            : decimal       — оплачено
paymentType      : decimal       — способ оплаты
boardingId       : int           — ID типа питания
tariffId         : int           — ID тарифа
guests           : List<Guest>   — список гостей
extraservices    : List<ExtraService> — доп. услуги
contactName      : string        — ФИО контактного лица
contactPhone     : string        — телефон контактного лица
contactEmail     : string        — email контактного лица
source           : string        — источник бронирования
byRequest        : bool?         — бронирование по запросу

Guest (гость)

surname          : string        — фамилия
name             : string        — имя
patronymic       : string        — отчество
phone            : string        — телефон
email            : string        — email
age              : int?          — возраст
birthdate        : DateTime?     — дата рождения

ExtraService (доп. услуга)

id               : int           — ID услуги
count            : int?          — количество
date             : DateTime?     — дата

SearchParameters (параметры поиска)

arrival          : DateTime      — дата заезда
departure        : DateTime      — дата выезда
adultsCount      : int           — кол-во взрослых
childsCount      : int           — кол-во детей
ages             : int[]         — возраста детей (сортируются по убыванию)
promo            : string        — промокод
guestsCount      : int           — вычисляемое: adults + childs
isMotherAndChild : bool          — вычисляемое: guestsCount == 2 && childs == 1
filter           : IList<FilterItem> — фильтры
byHours          : bool          — почасовое бронирование

FilterItem (элемент фильтра)

Token            : string        — токен отеля
TariffCode       : string        — код тарифа
RoomTypeCode     : string        — код категории номера
HotelId          : int           — определяется по токену
TariffId         : int           — определяется по коду или ID
RoomTypeId       : int           — определяется по коду или ID

Перечисления

OrderStatus — Статус заказа

Значение Имя Описание
-1 Annulate Аннулирован
0 No Не найден
1 Bron Бронирование (не оплачено)
2 Prepayment Предоплата
3 Payment Полная оплата

StepResult — Результат операции

Значение Имя Описание
1 OK Успешно
2 Overflow Нет результатов / нет мест
3 Error Ошибка сервера
4 InvalidParameters Неверные параметры

PaymentSystem — Платёжные системы

Значение Имя
0 None
1 OrderPaygate
2 ReservMaster
3 Appex
4 PayMaster
5 Tinkoff
6 Paykeeper
7 PayOnline
8 Paygate
9 Avangard
10 OnlineSberbank
11 Uniteller

Платёжные системы

OrderPaygate

При создании заказа через CreateOrder, если для отеля настроена платёжная система OrderPaygate:

  1. Автоматически создаётся счёт через Unipag API
  2. В ответе возвращается invoiceNumber и apiKey
  3. Клиент перенаправляется на оплату

Uniteller

  1. Генерируется ссылка для оплаты:
    https://cloud.shelter.ru/uniteller/payment.aspx?token={token}&resId={resId}&id={cashId}&prep=1
    
  2. В ответе возвращается invoiceNumber

Устранение неполадок

Проблема: Пустой массив результатов

Проверьте:

  1. Лицензия на модуль «Бронирование онлайн» активна
  2. Категории номеров и тарифы настроены для онлайн-продажи
  3. Цены установлены на запрошенный период
  4. Нет ограничений по тарифам/категориям
  5. Тарифы не удалены и не просрочены

Проблема: Неверный формат запроса

Отладка через DevTools браузера:

  1. Откройте авто-сгенерированный сайт с модулем бронирования
  2. Откройте DevTools (F12) → вкладка Network
  3. Установите фильтр «Fetch/XDR»
  4. Выполните поиск на виджете
  5. Найдите запрос к API

Вкладка Network

  1. Во вкладке Headers — URL и метод запроса
  2. Во вкладке Payload → View source — тело запроса

Payload

  1. Во вкладке Response — структура ответа

Response

Проблема: Ошибка «overflow» при CreateOrder

Нет свободных номеров на запрошенные даты. Выполните предварительный поиск через jsSearchJoin или jsAvailables.

Проблема: «invalid token»

  • Убедитесь, что токен корректен (формат UUID)
  • Для CreateOrder/AnnulateOrder используйте приватный токен
  • Проверьте, что токен активен в настройках Shelter Cloud

См. также:

Документация составлена на основе анализа исходного кода hmsExternalPrices.