Developing Hotel Booking Platform
Hotel booking platform is a complex system with room inventory management, rates, dynamic pricing, PMS system integration, and GDS distribution. Development from scratch to Booking.com level — multi-year project, but regional aggregator or B2B tool for hotel chain — realistic task.
Data Model: Room Inventory
Hotel
└── RoomType (Standard, Deluxe, Suite)
├── Attributes (area, view, capacity, amenities)
└── Inventory (number of rooms of this type)
└── Rate Plans (Non-refundable, Flexible, Breakfast included)
└── Availability × Date × Price
Availability management: for each room type and each date, store quota (available count) and price. On booking quota decreases by 1.
CREATE TABLE room_availability (
room_type_id, date DATE, rate_plan_id,
available_count INT NOT NULL DEFAULT 0,
price_per_night DECIMAL(10,2),
PRIMARY KEY (room_type_id, date, rate_plan_id)
);
-- Atomic booking with stock check
UPDATE room_availability
SET available_count = available_count - 1
WHERE room_type_id = $1 AND date = ANY($dates)
AND rate_plan_id = $2 AND available_count > 0;
Multi-Night Booking
Booking spans several nights. Price summed across nights (different dates may have different rates). Must update availability for each check-in night.
Dynamic Pricing
Revenue Management System (RMS) automatically adjusts rates based on:
- Occupancy: if rooms running out — price up
- Advance demand: many searches for specific date → price up
- Seasonality and events (conferences, holidays)
- Competitor prices (rate parity monitoring)
Simple implementation: cron task hourly recalculates rates by rules.
Search with Filters
Search "hotels in Sochi, Aug 2–5, 2 guests, 1 room":
SELECT h.*, rt.*, ra.price_per_night
FROM hotels h
JOIN room_types rt ON rt.hotel_id = h.id
JOIN room_availability ra ON ra.room_type_id = rt.id
WHERE h.city = 'Sochi'
AND ra.date BETWEEN '2024-08-02' AND '2024-08-04'
AND rt.max_occupancy >= 2
GROUP BY h.id, rt.id
HAVING MIN(ra.available_count) > 0 -- all nights available
ORDER BY SUM(ra.price_per_night) ASC;
Channel Manager / PMS Integration
Hotels use PMS (Property Management System: Opera, Fidelio, SHELTER) for room inventory management. Availability and price updates must sync:
OTA Integration: standard OTA XML (Open Travel Alliance) for two-way sync with GDS and OTA channels.
Channel Manager: intermediate layer (SiteMinex, Effortless, MyAllocator) aggregates hotel data and distributes via unified API.
Direct PMS API: for large hotels — direct integration via REST or SOAP API of specific PMS.
Cancellation Policy
Rate plans have different policies:
- Non-refundable: 10–20% discount, no cancellation refund
- Flexible: cancellation 24–48 hours — full refund
- Partial refund: % depends on time to check-in
Payment and Guarantees
Two payment modes:
- Pay now: payment on booking (via Stripe/YooKassa)
- Pay at hotel: card guarantee (authorization without capture), payment at desk
For "Pay at hotel" — Stripe PaymentIntent with capture_method: manual. Authorize card on booking, capture at check-in.
Maps and Geosearch
Display hotels on map — Mapbox GL JS or Leaflet with clustering. PostGIS for geosearch ("hotels 2 km from beach" or "inside selected area on map").
Timeline
MVP (hotel catalog, date search, booking, payment, account): 4–5 months. With Channel Manager, dynamic rates, mobile app, PMS integration: 8–14 months.







