1C-Bitrix Integration with Bnovo Booking System
Bnovo is a PMS system for hotels with its own channel manager and online booking module. The problem without integration: a manager receives a request through the 1C-Bitrix website, manually enters the booking into Bnovo, then manually updates room availability back on the site. Two sources of truth — two places for errors. Overbooking in this scenario is only a matter of time.
Integration Architecture
Bnovo provides a REST API (https://online.bnovo.ru/api/v1/). Authentication — hotel API key in the X-Api-Key header. Core entities: rooms, reservations, rates, availability (availability by date).
Data flow directions:
- Bnovo → 1C-Bitrix: synchronise room availability and rates — so the on-site widget shows accurate occupancy.
- 1C-Bitrix → Bnovo: transmit new bookings created through the website.
We avoid intermediate storage — data is passed directly via API with caching on the 1C-Bitrix side.
Availability Synchronisation
Bnovo returns availability via GET /api/v1/availability?hotel_id={id}&date_from=YYYY-MM-DD&date_to=YYYY-MM-DD. The response contains an array of dates with the number of free rooms per room type.
A 1C-Bitrix agent runs every 10 minutes and updates the local availability cache in the bl_bnovo_availability table:
CREATE TABLE bl_bnovo_availability (
room_type_id INT NOT NULL,
date DATE NOT NULL,
qty_available SMALLINT NOT NULL DEFAULT 0,
synced_at TIMESTAMP NOT NULL,
PRIMARY KEY (room_type_id, date)
);
The date-picker widget on the site queries this table — without hitting the Bnovo API in real time. This reduces dependency on the external service's availability and speeds up form responsiveness.
Creating a Booking in Bnovo from 1C-Bitrix
After a successful payment (the OnSalePaymentEntitySaved event with IS_PAID = Y), the handler builds a request to Bnovo:
$response = $bnovoClient->post('/api/v1/reservations', [
'hotel_id' => $this->hotelId,
'room_id' => $roomId,
'date_from' => $booking->getDateFrom()->format('Y-m-d'),
'date_to' => $booking->getDateTo()->format('Y-m-d'),
'rate_id' => $booking->getRateId(),
'guest' => [
'name' => $order->getPropertyValueByCode('NAME'),
'phone' => $order->getPropertyValueByCode('PHONE'),
'email' => $order->getPropertyValueByCode('EMAIL'),
],
'amount' => $payment->getSum(),
'source' => 'website',
]);
$bnovoReservationId = $response['reservation']['id'];
The reservation_id from the response is saved in the order's UF field UF_BNOVO_RESERVATION_ID — this is required for subsequent operations (cancellation, date changes).
Webhooks from Bnovo
Bnovo can send webhooks when a booking status changes for reservations created within the PMS (not via the website). Configuration is done in the "Integrations" section of the Bnovo admin panel: specify the handler URL on the 1C-Bitrix side.
Handler /api/bnovo-webhook.php:
$payload = json_decode(file_get_contents('php://input'), true);
// Signature verification: HMAC-SHA256 of request body + secret key
$expectedSign = hash_hmac('sha256', file_get_contents('php://input'), BNOVO_WEBHOOK_SECRET);
if (!hash_equals($expectedSign, $_SERVER['HTTP_X_BNOVO_SIGNATURE'] ?? '')) {
http_response_code(403);
exit;
}
switch ($payload['event']) {
case 'reservation.created':
// Create an order in 1C-Bitrix or notify the manager
break;
case 'reservation.cancelled':
// Cancel the order in 1C-Bitrix
BnovoSyncService::cancelOrder($payload['reservation_id']);
break;
case 'availability.updated':
// Reset availability cache for affected dates
BnovoCache::invalidate($payload['room_type_id'], $payload['dates']);
break;
}
Rates and Seasonal Pricing
Bnovo stores rates — a set of pricing rules. The GET /api/v1/rates method returns a list with conditions: minimum number of nights, date restrictions, meal type. We sync rates to the bl_bnovo_rates table once per hour — they change infrequently.
On the booking form, rates are loaded via an AJAX call: the user selects dates, the site requests current rates with prices via GET /api/v1/rates/prices?room_id=X&date_from=...&date_to=... and displays accommodation options.
Timeline
| Phase | Duration |
|---|---|
| API client setup and authentication | 1 day |
| Availability sync (agent + table) | 2 days |
| Booking transmission to Bnovo on payment | 2 days |
| Webhook handler from Bnovo | 1–2 days |
| Rate synchronisation | 1 day |
| Testing and debugging | 2 days |
| Total | 9–11 days |







