1C-Bitrix Integration with Shelter Booking System
Shelter is a domestic PMS for hostels, boutique hotels, and apart-hotels. Its target audience is small properties that find heavy PMS solutions too expensive but still need proper automation. The typical problem: the 1C-Bitrix website operates independently while Shelter runs in parallel. The manager enters guest data twice, has no consolidated occupancy view across channels, and only finds out about a cancellation in Shelter when they happen to open the tab.
Shelter API
Shelter provides a REST API. Base URL: https://api.shelter-pms.ru/v2/. Authentication — Bearer token in the header. Key endpoints:
-
GET /rooms— list of rooms with types -
GET /availability— availability for a date range -
GET /tariffs— rate plans -
POST /bookings— create a booking -
PUT /bookings/{id}— modify a booking -
GET /bookings/{id}— booking status
Rate limit: 120 requests per minute. For a large property (50+ rooms) this must be taken into account — batch requests are preferred over individual ones.
Room Inventory Synchronisation
On initial run (or on demand), we load the full room directory from Shelter and create corresponding infoblock elements in 1C-Bitrix. The mapping is stored in the bl_shelter_room_map table:
CREATE TABLE bl_shelter_room_map (
bitrix_element_id INT NOT NULL,
shelter_room_id VARCHAR(64) NOT NULL,
room_type VARCHAR(64),
synced_at TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (bitrix_element_id)
);
This allows availability synchronisation to address Shelter by shelter_room_id, while the website displays data through the standard 1C-Bitrix infoblock.
Fetching Availability
An agent requests GET /availability?date_from=YYYY-MM-DD&date_to=YYYY-MM-DD every 15 minutes. The response is a matrix of "date × room type × number of available units".
function SyncShelterAvailability(): string
{
$client = new ShelterApiClient(SHELTER_TOKEN);
$dateFrom = (new DateTime())->format('Y-m-d');
$dateTo = (new DateTime('+90 days'))->format('Y-m-d');
$data = $client->get('/availability', [
'date_from' => $dateFrom,
'date_to' => $dateTo,
]);
foreach ($data['availability'] as $row) {
\Bitrix\Main\Application::getConnection()->queryExecute(
"INSERT INTO bl_shelter_availability (room_type_id, date, qty)
VALUES (?, ?, ?)
ON CONFLICT (room_type_id, date) DO UPDATE SET qty = EXCLUDED.qty, synced_at = NOW()",
[$row['room_type_id'], $row['date'], $row['available']]
);
}
return __FUNCTION__ . '();';
}
Creating and Cancelling Bookings
When payment is confirmed in 1C-Bitrix, we send the booking to Shelter. Shelter returns a booking_id, which we save in the order's UF field UF_SHELTER_BOOKING_ID.
When an order is cancelled in 1C-Bitrix (the OnSaleOrderCanceled event or status change via handler), we send a PUT /bookings/{id} request with status: cancelled. If the Shelter API is unavailable at the time of cancellation — we queue the task in the agent with retry attempts.
Webhooks from Shelter
Shelter sends notifications when a booking status changes within the PMS (for example, a manager cancels a booking directly in Shelter, bypassing the website). Webhook configuration is done in "Settings → Integrations" within Shelter.
The handler verifies the signature (X-Shelter-Signature), identifies the event type, and updates the order in 1C-Bitrix. The critical event is booking.cancelled: we need to release the date in the local cache and notify the guest by email via \Bitrix\Main\Mail\Event::send.
Guest Information Transfer
Shelter stores guest profiles. When creating a booking via the website, we check whether a guest with that email exists in Shelter (GET /guests?email=...). If found — we pass the guest_id. If not — Shelter creates the profile automatically. This simplifies front-desk operations on repeat visits: the complete guest history is visible directly in the PMS.
Timeline
| Phase | Duration |
|---|---|
| API client and room mapping | 2 days |
| Availability synchronisation | 2 days |
| Booking creation/cancellation | 2 days |
| Webhook handler | 1 day |
| Testing | 2 days |
| Total | 9–11 days |







