Booking flow
The typical flow for a booking engine: get a token, list rooms for the dates and occupancy the guest searched, apply the chosen rate and any coupon, complete the payment step, and write the booking to HMS with BookingPushRQ. This guide walks through each step with real requests and responses.
/external/public/login/external/online/roomTypecoupon/search · stock/packagespayment/type/{type}channel/booking1. Get a token#
Log in once when your server starts or when the token expires, and store the token together with the hotel ID. Details: Authentication.
2. List the rooms#
Request the room list with the values from the guest’s search form. If children travel, send their ages; child pricing is calculated by age.
curl "https://test.hms.gen.tr/external/online/roomType" \
-H "Authorization: Bearer $HMS_TOKEN" \
-d "hotelID=1000" -d "startDate=2026-08-18" -d "endDate=2026-08-20" \
-d "adultCount=2" -d "childCount=1" -d "childAges[]=7" -d "language=en"What to show for each room type in the response:
| Field | On screen |
|---|---|
name, images[], detail, roomFeatures[] | Room card |
roomCount | Rooms left. 0 means “not for sale” — reason in roomRestrictionMessage. |
accommodationTypes[].title | Board option (Bed & Breakfast, Half Board…) |
accommodationTypes[].prices{} | Rate options: standard and non-refundable |
Keys of the prices object have the form "<persons>-<1|0>". Suffix 1 is the standard (refundable) rate, 0 the non-refundable rate; the non-refundable option carries nonRefundable: "[NR]". With per-room pricing (priceType: 1) the key is 1-1 / 1-0 regardless of occupancy.
{
"2-1": {
"total": 2,
"title": 2,
"nonRefundable": "",
"price": "1930.00",
"currency": "TRY",
"id": "2/2",
"prices": [
{
"price": "965.00",
"tarih": "18.08.2026"
},
{
"price": "965.00",
"tarih": "19.08.2026"
}
]
},
"2-0": {
"total": 2,
"title": 2,
"nonRefundable": "[NR]",
"price": "1737.00",
"currency": "TRY",
"id": "2-0/2",
"prices": [
{
"price": "868.50",
"tarih": "18.08.2026"
},
{
"price": "868.50",
"tarih": "19.08.2026"
}
]
}
}3. Coupons and packages#
If the guest enters a coupon, validate it and apply the discount on your side:
curl "https://test.hms.gen.tr/external/online/coupon/search" \
-H "Authorization: Bearer $HMS_TOKEN" \
-d "hotelID=1000" -d "coupon=SUMMER2026"{
"success": true,
"cupon": {
"id": 12,
"change": 0,
"rate": "10.00"
}
}With change 0, rate is a percentage discount (10%); with 1 it is a fixed amount (10.00 in the hotel currency). Apply the discount to the room amount and send the discounted totals in the booking.
To sell extras, show the package list. Selected packages go into the booking as extras[], with the package id in stockID. The totals after coupons and packages are written to the booking’s Total.
4. Payment step#
List the payment types the hotel accepts and proceed according to the guest’s choice. For type 10 (online payment) a payment session is started and the guest is handed over to the provider; after payment they return to your returnUrl. All types are covered in the Payment flow guide.
5. Push the booking#
Once the payment outcome is known, write the booking to HMS. ID is the unique code you generate; give the same code to the guest. Room and board type IDs come from the room list.
curl -X POST "https://test.hms.gen.tr/external/online/channel/booking" \
-H "Authorization: Bearer $HMS_TOKEN" \
-H "Content-Type: application/json" \
-d @booking.jsonconst booking = {
hotelID: "1000",
ID: orderNo, // your unique booking code
type: "Book",
createDateTime: new Date().toISOString(),
checkinDate: "2026-08-18",
checkoutDate: "2026-08-20",
RoomStays: [{
roomTypeID: "2", roomName: "Standard Room",
ratePlanID: "2", ratePlanName: "Bed & Breakfast",
type: "Book", NumberOfUnits: "1",
checkinDate: "2026-08-18", checkoutDate: "2026-08-20",
GuestCount: { adult: 2, child: 1 },
PerDayRates: { currency: "TRY", PerDayRate: [
{ stayDate: "2026-08-18", baseRate: "965.00", hotelServiceFees: "0" },
{ stayDate: "2026-08-19", baseRate: "965.00", hotelServiceFees: "0" }
]},
Total: { amountAfterTaxes: "1930.00", amountOfTaxes: "175.45", currency: "TRY" }
}],
PrimaryGuests: [{ name: "Ayşe", surname: "Demir", PhoneNumber: "+905551112233", email: "[email protected]", CountryCode: "TR" }],
ChildGuests: [{ age: 7 }],
SpecialRequest: [{ text: "Late check-in, around 23:00." }],
extras: [],
Total: { amountAfterTaxes: "1930.00", amountOfTaxes: "175.45", extraTotal: "0.00", currency: "TRY" }
};
const res = await fetch("https://test.hms.gen.tr/external/online/channel/booking", {
method: "POST",
headers: { "Authorization": `Bearer ${process.env.HMS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({ BookingPushRQ: { Bookings: [booking] } })
});
const { BookingPushRS } = await res.json();
if (BookingPushRS.Error) throw new Error(BookingPushRS.Error);
const hmsId = BookingPushRS.BookingConfirmNumbers[0].HMS_ID;$booking = [
'hotelID' => '1000',
'ID' => $orderNo, // your unique booking code
'type' => 'Book',
'createDateTime' => date('c'),
'checkinDate' => '2026-08-18',
'checkoutDate' => '2026-08-20',
'RoomStays' => [[
'roomTypeID' => '2', 'roomName' => 'Standard Room',
'ratePlanID' => '2', 'ratePlanName' => 'Bed & Breakfast',
'type' => 'Book', 'NumberOfUnits' => '1',
'checkinDate' => '2026-08-18', 'checkoutDate' => '2026-08-20',
'GuestCount' => ['adult' => 2, 'child' => 1],
'PerDayRates' => ['currency' => 'TRY', 'PerDayRate' => [
['stayDate' => '2026-08-18', 'baseRate' => '965.00', 'hotelServiceFees' => '0'],
['stayDate' => '2026-08-19', 'baseRate' => '965.00', 'hotelServiceFees' => '0'],
]],
'Total' => ['amountAfterTaxes' => '1930.00', 'amountOfTaxes' => '175.45', 'currency' => 'TRY'],
]],
'PrimaryGuests' => [['name' => 'Ayşe', 'surname' => 'Demir', 'PhoneNumber' => '+905551112233', 'email' => '[email protected]', 'CountryCode' => 'TR']],
'ChildGuests' => [['age' => 7]],
'SpecialRequest' => [['text' => 'Late check-in, around 23:00.']],
'extras' => [],
'Total' => ['amountAfterTaxes' => '1930.00', 'amountOfTaxes' => '175.45', 'extraTotal' => '0.00', 'currency' => 'TRY'],
];
$ch = curl_init('https://test.hms.gen.tr/external/online/channel/booking');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('HMS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['BookingPushRQ' => ['Bookings' => [$booking]]]),
]);
$rs = json_decode(curl_exec($ch), true)['BookingPushRS'];
if (isset($rs['Error'])) {
throw new RuntimeException($rs['Error']);
}
$hmsId = $rs['BookingConfirmNumbers'][0]['HMS_ID'];{
"BookingPushRS": {
"Success": true,
"BookingConfirmNumbers": [
{
"confirmTime": 1755500000,
"bookingID": 48213,
"bookingType": "Book",
"HMS_ID": 48213
}
]
}
}HMS_ID is the booking ID in HMS; store it with your own record. The booking appears in the panel under the “Online” channel, and HMS sends the guest a confirmation e-mail according to the hotel’s settings.
Multiple rooms#
When several rooms of the same room type and board type are sold, each room is a separate RoomStays item; NumberOfUnits is "1" for the first, "2" for the second and so on. Different room types are separate items too. The booking’s Total is the sum of all rooms and extras.
Modifications and cancellations#
Send the booking again to the same endpoint with the same ID:
type: "Modify"— dates, rooms or guest details changed. Send the complete booking in its current state; HMS replaces the existing record with it.type: "Cancel"— the booking was cancelled. The rooms carrytype: "Cancel"as well.
Common mistakes#
- Caching the room list for long. Availability and rates change constantly; refresh the list before the guest enters the payment step.
- Sending a
childCountthat differs from the length ofchildAges[]: the server trusts the age list and silently changes the child count. - Sending your own IDs as
roomTypeID/ratePlanIDinstead of the IDs from the room list: Could not register. is returned. - Sending
PaymentCardfor payment types other than 9: card data is transmitted to HMS unnecessarily. - Retrying after a network error with a different
ID: this creates a duplicate booking. Retry with the sameID.