Xizmat Safari (XF) — интеграция МВД ↔ E-mehmon
API двусторонней интеграции системы служебных командировок Xizmat Safari (МВД,
*.imv.uz) с E-mehmon: бронирование гостиниц под госкомандировки, формирование и
подписание договора, подтверждение заселения.
В отличие от CRM Hotel API, XF — прямая интеграция:
Xizmat Safari ходит напрямую в E-mehmon (POST /api/xf-api), без промежуточного шлюза.
- Прод-домен:
emehmon.uz→POST https://emehmon.uz/api/xf-api. - Песочница:
sandbox-api.emehmon.uz— см.sandbox.md.
Направления обмена
Xizmat Safari (МВД) E-mehmon
│ │
│ ① POST /api/xf-api {method,data,...} │
│ ─────────────────────────────────────► │
│ ◄───────────────────────────────────── │ {data,message,code}
│ │
│ ② уведомления о статусе/договоре/QR │
│ ◄───────────────────────────────────── │
① Входящие (МВД → E-mehmon) — единое окно POST /api/xf-api, 7 методов (см. ниже).
② Исходящие (E-mehmon → МВД) — E-mehmon отправляет уведомления на согласованные с МВД endpoint'ы по ходу жизненного цикла брони:
| Уведомление | HTTP | Endpoint | Когда |
|---|---|---|---|
| Смена статуса брони | POST | /api/v1/booking/emehmon/response/ |
отель принял/отклонил бронь |
| Статус договора | POST | /api/v1/ehotel/booking_accept/ |
смена статуса договора |
| Готовый договор | GET | /api/v1/booking/contract/emehmon-preview/ |
E-mehmon забирает сформированный договор |
| Подтверждение заселения | POST | /api/v1/booking/contract/emehmon-confirm/ |
заселение подтверждено (QR + PINFL) |
| Подтверждение выезда | POST | /api/v1/booking/contract/emehmon-checkout/ |
гость выехал (dateVisitOff выставлен) |
| Проверка ЭЦП (E-IMZO) | POST | imzo.emehmon.uz:8080/backend/auth |
проверка электронной подписи |
Транспорт и аутентификация
POST /api/xf-api, Content-Type: application/json. Две независимые проверки:
1. IP-allowlist
Запросы принимаются только с заранее согласованных IP-адресов гейтвея МВД. Запрос с
неразрешённого адреса → 401.
2. Подпись hash
Поле hash в теле запроса — SHA1 от строки id_request, секретного ключа и method:
hash = sha1(id_request + "-" + secret + "-" + method)
secret — выданный вам ключ. Сравнение регистронезависимое (hash передавайте в lowercase).
Формат запроса/ответа
Запрос:
{
"method": "hotel-list",
"id_request": "req-001",
"data": { "region_id": 1703, "page": 1 },
"hash": "<см. выше>"
}
Ответ (единый конверт):
{ "data": { /* ... */ }, "message": "success", "code": 200 }
Обязательные поля запроса: method, data, hash, id_request (отсутствие любого → 401).
Методы
method |
Назначение | Ключевые data |
|---|---|---|
hotel-list |
Список отелей региона (стр. по 20) | region_id (COATO), page; опц. district_id (sp_id), hotel_type_id |
hotel-info |
Карточка отеля: номера, цены, занятость | hotel_id |
hotel-photos |
Фото отеля | hotel_id |
make-booking |
Создать бронь под командировку | hotel_id, checkin_date, checkout_date, organization_name, organization_tin, contact_phone, rooms_qty, doc_number, pinfl, dtb, staffname, room_id |
booking-single |
Одна бронь по id | booking_id |
booking-doc-status |
МВД сообщает статус договора (Confirmed → E-mehmon забирает договор) |
booking_id, booking_status |
cancel-booking |
Отмена брони (статусы new/paid/partly_paid/accepted) | booking_id; опц. reason |
region_id/district_idв запросах — это коды COATO/SP (как в официальном классификаторе), а не внутренние id.room_idвmake-booking— это значениеidиз массиваrooms[]ответаhotel-info.
Идемпотентность
Каждый запрос несёт уникальный id_request. Повторный запрос с тем же id_request,
по которому уже сформирован ответ, возвращает тот же ответ без повторной обработки
(защита от сетевых ретраев).
Жизненный цикл брони
make-booking → status=new
│ (отель принимает/отклоняет бронь)
├─ accept → status=accepted → POST /emehmon/response/ (notifyStatusChange)
└─ reject → status=rejected → POST /emehmon/response/ (notifyStatusChange)
│
МВД формирует договор → booking-doc-status (Confirmed)
│
E-mehmon GET emehmon-preview/ → забирает договор (contract_hashing, document)
│
договор Accepted → POST /ehotel/booking_accept/ (notifyContractStatus)
│
подтверждение заселения → POST emehmon-confirm/ (QR + PINFL + фото)
│ → contract_status=Accepted, листок создан
гость проживает
│
выезд гостя (dateVisitOff) → POST emehmon-checkout/ (contract_uuid + datetime)
Заселение создаёт регистрацию (листок) и запускает соответствующие госуведомления.
Выезд (confirmCheckout) срабатывает автоматически при выселении гостя в кабинете.
В песочнице эти побочные эффекты отключены/застаблены — см. sandbox.md.