Інтеграція 1С-Бітрікс з системою бронювання Travelline
Готель використовує віджет Travelline в iframe — втрачає до 40% конверсії через негнучкий UX, повільне завантаження та погану адаптацію під мобільні. Гості переходять на сторонній інтерфейс, а адміністратор вручну переносить дані. Пряма інтеграція 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} | Отримання даних броні |
Оплата та зберігання броней
Якщо тариф передбачає передоплату — інтегруємо платіжну систему (ЮKassa, Тинькофф). Сума передоплати береться з $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







