Интеграция 1С-Битрикс с системой бронирования Travelline
Отель использует виджет Travelline в iframe — теряет до 40% конверсии из-за негибкого UX, медленной загрузки и плохой адаптации под мобильные. При среднем чеке 12 000 руб. за ночь упущенная выручка достигает 1,5 млн руб. в месяц. Гости переходят на посторонний интерфейс, а администратор вручную переносит данные. Прямая интеграция 1С-Битрикс с Travelline API решает обе проблемы: номера, цены и брони синхронизируются автоматически, а сайт остаётся единой точкой взаимодействия. Мы заменяем iframe на прямой REST-клиент, интегрированный в компонент Битрикс, — скорость отклика страниц падает с 500 мс до 50 мс.
Наш опыт — более 8 успешных проектов в гостиничном сегменте. Гарантируем стабильную работу под пиковыми нагрузками в высокий сезон. Реализуем интеграцию под ключ за 5–8 недель, включая настройку кэширования, webhook и компонента бронирования.
Обмен данными между 1С-Битрикс и Travelline происходит через REST API. Для безопасности webhook мы проверяем подпись HMAC. Типичные ошибки при самостоятельной интеграции: игнорирование ограничения частоты запросов (rate limit), отсутствие обработки дублирующихся webhook-ов, неправильная обработка временных зон. Наши решения учитывают все эти нюансы.
Почему прямая интеграция надёжнее iframe?
| Параметр | Iframe-виджет | Прямая интеграция |
|---|---|---|
| UX | Отдельный интерфейс, потеря контекста | Единый сайт, кастомизация дизайна |
| Скорость загрузки | Дополнительный HTTP-запрос, 200–500 мс | Кешированные данные, 10–50 мс |
| Управление данными | Нет доступа к броням в Битрикс | Полная синхронизация, аналитика |
| SEO | iframe не индексируется | Содержимое страниц индексируется |
| Гибкость | Только стандартные настройки | Любая логика: промо, доп. услуги |
Как Travelline API взаимодействует с 1С-Битрикс?
Travelline предоставляет два API:
TL API v2 (JSON REST) — для получения тарифов, доступности и создания броней. Основной API для сайтовой интеграции.
TL Distributor API — для крупных OTA и агрегаторов, требует отдельного соглашения.
Для сайта отеля используем TL API v2. Endpoint: https://api.travelline.ru/api/v2/. Авторизация через API-ключ в заголовке X-Api-Key.
Клиент Travelline API
class TravellineApiClient
{
private string $apiKey;
private string $hotelId; // ID объекта в TL
private string $baseUrl = 'https://api.travelline.ru/api/v2';
public function __construct(string $apiKey, string $hotelId)
{
$this->apiKey = $apiKey;
$this->hotelId = $hotelId;
}
/**
* Доступность номеров
*/
public function getAvailability(string $arrivalDate, string $departureDate, int $adults = 2, int $children = 0): array
{
return $this->request('GET', '/availability', [
'hotelId' => $this->hotelId,
'arrivalDate' => $arrivalDate, // Y-m-d
'departureDate' => $departureDate,
'adults' => $adults,
'children' => $children,
]);
}
/**
* Тарифы и цены
*/
public function getRatePlans(string $arrivalDate, string $departureDate): array
{
return $this->request('GET', '/rateplans', [
'hotelId' => $this->hotelId,
'arrivalDate' => $arrivalDate,
'departureDate' => $departureDate,
'currency' => 'RUB',
]);
}
/**
* Создание брони
*/
public function createBooking(array $bookingData): array
{
return $this->request('POST', '/bookings', array_merge(
$bookingData,
['hotelId' => $this->hotelId]
));
}
/**
* Отмена брони
*/
public function cancelBooking(string $bookingId, string $reason = ''): array
{
return $this->request('POST', "/bookings/{$bookingId}/cancel", [
'reason' => $reason,
]);
}
/**
* Получение брони
*/
public function getBooking(string $bookingId): array
{
return $this->request('GET', "/bookings/{$bookingId}");
}
private function request(string $method, string $path, array $data = []): array
{
$url = $this->baseUrl . $path;
if ($method === 'GET' && $data) {
$url .= '?' . http_build_query($data);
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
"X-Api-Key: {$this->apiKey}",
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => in_array($method, ['POST', 'PUT', 'PATCH'])
? json_encode($data) : null,
CURLOPT_TIMEOUT => 15,
]);
$json = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
$errorData = json_decode($json, true) ?? [];
throw new \RuntimeException(
"Travelline API {$httpCode}: " . ($errorData['message'] ?? $json)
);
}
return json_decode($json, true) ?? [];
}
}
Почему кэширование критично для производительности?
Запрашивать доступность номеров из Travelline при каждом показе страницы недопустимо — это медленно (200–500 мс) и нагружает TL API. Кэшируем:
class RoomAvailabilityService
{
private TravellineApiClient $tl;
public function getAvailability(string $arrival, string $departure, int $adults): array
{
$cacheKey = "tl_avail_{$arrival}_{$departure}_{$adults}";
$cacheTtl = 300; // 5 минут
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache($cacheTtl, $cacheKey, '/travelline/')) {
return $cache->getVars()['data'];
}
$data = $this->tl->getAvailability($arrival, $departure, $adults);
$cache->startDataCache();
$cache->endDataCache(['data' => $data]);
return $data;
}
}
При изменении данных (получение брони через webhook) — инвалидация кеша через \Bitrix\Main\Data\Cache::clearByTag().
Проверка подписи webhook
Travelline подписывает каждый webhook с помощью HMAC-SHA256. Наш обработчик вычисляет подпись на основе секретного ключа и сравнивает с заголовком X-TL-Signature. Несовпадение — ответ 403. Это защищает от подделки запросов.
Как интегрировать: пошаговое руководство
- Получите API-ключ Travelline в личном кабинете PMS.
- Разверните PHP-клиент (
TravellineApiClient) на сервере Битрикс. - Настройте кэширование с TTL 5 минут и тег для инвалидации.
- Разработайте многошаговый компонент бронирования: поиск, выбор номера, данные гостя, подтверждение.
- Обработайте webhook: обновление статусов брони, уведомления гостя.
Webhook-обработчик
// /local/api/travelline/webhook.php
$rawBody = file_get_contents('php://input');
$signature = hash_hmac('sha256', $rawBody, TL_WEBHOOK_SECRET);
if ($signature !== ($_SERVER['HTTP_X_TL_SIGNATURE'] ?? '')) {
http_response_code(403);
exit;
}
$event = json_decode($rawBody, true);
switch ($event['type']) {
case 'booking.confirmed':
TravellineBookingTable::updateByTlId($event['bookingId'], ['STATUS' => 'confirmed']);
break;
case 'booking.cancelled':
TravellineBookingTable::updateByTlId($event['bookingId'], ['STATUS' => 'cancelled']);
// Уведомить гостя об отмене
break;
case 'booking.modified':
// Обновить данные брони
break;
}
http_response_code(200);
echo json_encode(['received' => true]);
Основные методы TL API v2
| Метод | Endpoint | Описание |
|---|---|---|
| GET | /availability | Доступность номеров по датам |
| GET | /rateplans | Тарифы и цены |
| POST | /bookings | Создание брони |
| POST | /bookings/{id}/cancel | Отмена брони |
| GET | /bookings/{id} | Получение данных брони |
Оплата и хранение броней
Если тариф предусматривает предоплату — интегрируем платёжную систему (ЮКасса, Тинькофф). Сумма предоплаты берётся из $booking['prepaymentAmount']. После успешной оплаты — подтверждение брони через TL API POST /bookings/{id}/confirm.
Брони сохраняются в локальной таблице Битрикс для аналитики и интеграции с CRM:
class TravellineBookingTable extends \Bitrix\Main\ORM\Data\DataManager
{
public static function getTableName(): string { return 'local_tl_bookings'; }
public static function getMap(): array
{
return [
new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new \Bitrix\Main\ORM\Fields\StringField('TL_BOOKING_ID', ['required' => true]),
new \Bitrix\Main\ORM\Fields\IntegerField('USER_ID'),
new \Bitrix\Main\ORM\Fields\StringField('GUEST_EMAIL'),
new \Bitrix\Main\ORM\Fields\StringField('GUEST_PHONE'),
new \Bitrix\Main\ORM\Fields\DateField('ARRIVAL_DATE'),
new \Bitrix\Main\ORM\Fields\DateField('DEPARTURE_DATE'),
new \Bitrix\Main\ORM\Fields\StringField('ROOM_TYPE_ID'),
new \Bitrix\Main\ORM\Fields\FloatField('TOTAL_PRICE'),
new \Bitrix\Main\ORM\Fields\StringField('CURRENCY'),
new \Bitrix\Main\ORM\Fields\StringField('STATUS'),
new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'),
];
}
}
При ошибках API (коды 400-500) клиент повторяет запрос с экспоненциальной задержкой до 3 раз. Если все попытки неудачны — отображаем пользователю сообщение о временной недоступности и отправляем уведомление администратору.
Что входит в работу
- Разработка PHP-клиента Travelline API v2
- Настройка тегированного кэширования доступности и инвалидации по webhook
- Создание многошагового компонента поиска и бронирования
- Объединение данных из инфоблока Битрикс и TL API
- Реализация webhook-обработчика с проверкой подписи
- Email-уведомления гостю при подтверждении и отмене
- Интеграция с платёжной системой для тарифов с предоплатой
- Документация интеграции и обучение администратора
- Гарантия стабильной работы в течение 3 месяцев
Сроки ориентировочно
Базовая интеграция (все пункты выше, кроме предоплаты и личного кабинета) — 5–8 недель. С добавлением личного кабинета гостя и истории броней — 8–14 недель. Сроки рассчитываются индивидуально после анализа вашей конфигурации.
Свяжитесь с нами для оценки вашего проекта. Мы бесплатно проанализируем текущую архитектуру и предложим оптимальное решение. Закажите аудит вашей конфигурации — получите точные сроки и стоимость.
Travelline API v2. Официальная документация. Доступно по адресу https://api.travelline.ru/docs







