Payment flow

The hotel decides in the panel which payment types it accepts for online bookings. The booking engine shows that list and follows a different path for each type. This guide covers the four payment types and what to do for each.

List the payment types#

Terminal
curl "https://test.hms.gen.tr/external/online/payment/type?hotelID=1000" \
  -H "Authorization: Bearer $HMS_TOKEN"
Response · 200
{
    "success": true,
    "count": 3,
    "items": [
        {
            "title": "Pay at Hotel",
            "title_translate": "odeme.otelde_odeme",
            "typeID": 1
        },
        {
            "title": "Bank Transfer",
            "title_translate": "odeme.havale",
            "typeID": 3
        },
        {
            "title": "Online Card Payment",
            "title_translate": "odeme.online_odeme",
            "typeID": 10
        }
    ]
}
typeIDTypeWhat happens
1Pay at hotelNo collection; the booking is pushed directly.
3Bank transferThe hotel’s bank accounts are shown; the booking is pushed as “awaiting payment”.
9Credit card (guarantee)Card details are sent to HMS with the booking in PaymentCard; the hotel charges the card.
10Online payment (virtual POS)HMS starts a payment session; the guest is handed to the provider’s payment page and returns to your returnUrl.

Type 1 · Pay at hotel#

No extra step. You may call the endpoint to get an acknowledgement:

POST …/payment/type/1 → 200
{
    "success": true,
    "message": "payment_at_the_hotel"
}

Type 3 · Bank transfer#

Fetch the bank accounts the hotel enabled for online sales and show them to the guest:

Terminal
curl -X POST "https://test.hms.gen.tr/external/online/payment/type/3" \
  -H "Authorization: Bearer $HMS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hotelID": 1000}'
Response · 200
{
    "success": true,
    "message": "payment_by_bank_transfer",
    "banks": [
        {
            "companyName": "Ziraat Bank",
            "holder": "Demo Turizm A.Ş.",
            "branchName": "Denizli",
            "branchNumber": "0123",
            "bankAccountNumber": "12345678-5001",
            "iban": "TR00 0001 0001 2345 6789 5001 01"
        }
    ]
}

If no account is configured, bank_info_is_not_found is returned; hide this type from the list.

Type 9 · Credit card#

The endpoint only tells you that card details must be collected:

POST …/payment/type/9 → 200
{
    "success": true,
    "message": "credit_card_info_should_be_requested"
}

Collect the card details in your own form and send them in the PaymentCard field of each RoomStays item in the booking push:

RoomStays[].PaymentCard
{
    "PaymentCard": {
        "CardHolder": {
            "fullname": "Ayşe Demir",
            "address": "Kumsal Cad. No: 12",
            "country": "Türkiye",
            "city": "Antalya"
        },
        "cardNumber": "5571135571135575",
        "expireDate": "0329",
        "cardCode": "MasterCard",
        "seriesCode": "000"
    }
}

Type 10 · Online payment#

Start a payment session with the guest and basket details. All fields are required; a missing field is reported with required_input_info_not_submitted and errors[].

Request
curl -X POST "https://test.hms.gen.tr/external/online/payment/type/10" \
  -H "Authorization: Bearer $HMS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "hotelID": 1000,
    "totalPrice": 2330.00,
    "orderID": "4811174883",
    "returnUrl": "https://booking.example.com/payment/result",
    "name": "Ayşe", "surname": "Demir",
    "email": "[email protected]", "phone": "05551112233",
    "city": "Denizli", "address": "Kumsal Cad. No: 12", "countryID": 1,
    "baskets": [
      { "id": 2,  "name": "Standard Room · Bed & Breakfast", "piece": 1, "price": 1930.00 },
      { "id": 12, "name": "Dinner", "piece": 1, "price": 400.00 }
    ]
  }'
Response · 200
{
    "success": true,
    "message": "payment_order_code",
    "code": "<form method=\"post\" action=\"https://vpos.provider.example/3d\"><input type=\"hidden\" name=\"orderId\" value=\"4811174883\"> … </form><script>document.forms[0].submit()</script>"
}

The returned code is an HTML fragment: depending on the hotel’s virtual POS provider it is an auto-submitting 3D Secure form, a window.location redirect script or an embedded checkout form (e.g. iyzico). Render the fragment as-is on your payment page; do not try to parse it. The guest completes the payment at the provider and returns to your returnUrl; the outcome is signalled by query parameters appended to it (sonuc=1 success, sonuc=0 failure). Your order number (orderID) is stored with the payment record; match it to your own record on return, and push the booking only if the payment succeeded.

FieldNote
totalPriceMust equal the basket total; this amount goes to the provider.
orderIDMust be unique. Using the booking ID makes reconciliation easier.
countryIDid from the country list.
baskets[]One line per room or extra. id is the room type / package ID, piece the quantity, price the unit price.

Using the virtual POS details directly#

If you want to connect to the provider from your own server instead of HMS’s payment page, the virtual POS details endpoint returns the merchant ID, keys and provider code. These are secrets: use them server-side only and agree this approach with HMS first.

After payment#

  • For type 10, push the booking after the payment is confirmed; do not push on a failed payment.
  • For type 3, push the booking immediately; the hotel records the transfer in the panel when it arrives.
  • In the booking push, Total.amountAfterTaxes must equal the amount collected or to be collected.
Last updated: 8 September 2026Found a mistake? Let us know