Skip to main content

Hold Booking - Giữ Chỗ

API Endpoint: POST /api/v1/services/booking/v1/dat-chuyen


📋 Overview

Tạo booking trong trạng thái HOLD (giữ chỗ). Booking sẽ có thời hạn thanh toán (~4 giờ).

Status: trang_thai: 0 (HOLD)

Flow:

1. Search flights → Get flight UUID
2. Hold booking → Get PNR, ve_id
3. Payment (optional) → Issue ticket (trang_thai: 1)

🔌 API Specification

Endpoint

POST {{base_url}}/api/v1/services/booking/v1/dat-chuyen

Headers

{
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer {access_token}"
}

Request Body

Basic Example (No Services):

{
"api": "VJ",
"nhieu_chang": 0,
"chuyen_bay": [
{
"index": 1,
"uuid": "852ffde2-aeb0-11f0-8b81-86d224031662",
"phi_dai_ly": 0,
"index_hang_cho": 0,
"loai_phi_dai_ly": "Cơ bản"
}
],
"hanh_khach": [
{
"index": 1,
"ho": "NGUYEN VAN",
"ten": "TEST",
"email": "test@example.com",
"so_dien_thoai": "0987654321",
"ngay_sinh": "01-01-1990",
"the_thanh_vien": "",
"loai_hanh_khach": 1,
"danh_xung": 1,
"cha_me_id": null,
"ho_chieu": null
}
],
"thong_tin_booker": {
"ho": "TRAN THI",
"ten": "BOOKER",
"email": "booker@example.com",
"so_dien_thoai": "0912345678"
},
"dich_vu": [],
"cho_ngoi": [],
"ma_khuyen_mai": "",
"trang_thai": 0,
"xac_nhan_ve_dup": "",
"xac_nhan_thay_doi_gia": "",
"tong_gia_ve": 0,
"xac_nhan_cho_du_bi": ""
}

Complete Example (With Services & Insurance):

{
"api": "VJ",
"nhieu_chang": 0,
"bao_hiem": {
"uuid": "4dc7da23-8723-57e7-848f-5706bcf32257"
},
"chuyen_bay": [
{
"index": 1,
"uuid": "1f4a8f90-ba1a-11f0-a743-e69416960d28",
"phi_dai_ly": 0,
"index_hang_cho": 0,
"loai_phi_dai_ly": "Cơ bản"
}
],
"hanh_khach": [
{
"index": 1,
"ho": "NGUYEN VAN",
"ten": "TEST",
"email": "app@example.com",
"so_dien_thoai": "0702349398",
"ngay_sinh": "01-02-1993",
"the_thanh_vien": "",
"loai_hanh_khach": 1,
"danh_xung": 1,
"cha_me_id": null,
"ho_chieu": null
}
],
"thong_tin_booker": {
"ho": "AGENCY",
"ten": "BOOKER",
"email": "app@example.com",
"so_dien_thoai": "0702349398"
},
"dich_vu": [
{
"index_chang_bay": 1,
"index_chuyen_bay": 1,
"index_hanh_khach": 1,
"uuid": "044a181a-093d-8541-a41e-879caac6d017"
},
{
"index_chang_bay": 1,
"index_chuyen_bay": 1,
"index_hanh_khach": 1,
"uuid": "da38876a-cbcc-cfb3-76c0-f3fb5f6632db"
}
],
"cho_ngoi": [],
"ma_khuyen_mai": "",
"trang_thai": 0,
"xac_nhan_ve_dup": "",
"xac_nhan_thay_doi_gia": "",
"tong_gia_ve": 0,
"xac_nhan_cho_du_bi": ""
}

Fields:

FieldTypeRequiredDescription
apistring✅ YesAirline API: "VJ" for VietJet
nhieu_changnumber✅ YesMulti-city flag (0 = one-way/round-trip, 1 = multi-city)
chuyen_bayarray✅ YesFlight segments to book
chuyen_bay[].indexnumber✅ YesSegment index (1-based)
chuyen_bay[].uuidstring✅ YesFlight UUID from search result
chuyen_bay[].phi_dai_lynumber✅ YesAgency fee (0 for no fee)
chuyen_bay[].index_hang_chonumber✅ YesFare index from search (0-based)
chuyen_bay[].loai_phi_dai_lystring✅ YesFee type: "Cơ bản" or "Nhập"
hanh_khacharray✅ YesPassenger list
hanh_khach[].indexnumber✅ YesPassenger index (1-based)
hanh_khach[].hostring✅ YesLast name (UPPERCASE)
hanh_khach[].tenstring✅ YesFirst name (UPPERCASE)
hanh_khach[].emailstring✅ YesPassenger email
hanh_khach[].so_dien_thoaistring✅ YesPhone number
hanh_khach[].ngay_sinhstring✅ YesDate of birth (DD-MM-YYYY)
hanh_khach[].the_thanh_vienstringMembership card number (optional)
hanh_khach[].loai_hanh_khachnumber✅ YesPassenger type: 1 = Adult, 2 = Child, 3 = Infant
hanh_khach[].danh_xungnumber✅ YesTitle: 1 = Mr, 2 = Mrs, 3 = Ms
hanh_khach[].cha_me_idnumber/null✅ YesParent passenger index for infant (null if not infant)
hanh_khach[].ho_chieuobject/null⚠️Passport info (required for international flights)
thong_tin_bookerobject✅ YesBooker information
thong_tin_booker.hostring✅ YesBooker last name
thong_tin_booker.tenstring✅ YesBooker first name
thong_tin_booker.emailstring✅ YesBooker email (for booking confirmation)
thong_tin_booker.so_dien_thoaistring✅ YesBooker phone
bao_hiemobjectInsurance (optional)
bao_hiem.uuidstringInsurance UUID (if selected)
dich_vuarray✅ YesServices (baggage, food) - Empty [] if none selected
dich_vu[].index_chang_baynumber⚠️Journey index (1-based) - Required if services added
dich_vu[].index_chuyen_baynumber⚠️Flight index (1-based) - Required if services added
dich_vu[].index_hanh_khachnumber⚠️Passenger index (1-based) - Required if services added
dich_vu[].uuidstring⚠️Service UUID from Step 2.4 - Required if services added
cho_ngoiarray✅ YesSeat selection - Empty [] if none selected
ma_khuyen_maistringPromotion code
trang_thainumber✅ YesBooking status: 0 = HOLD, 1 = ISSUED
xac_nhan_ve_dupstring✅ YesDuplicate ticket confirmation (empty for new)
xac_nhan_thay_doi_giastring✅ YesPrice change confirmation (empty)
tong_gia_venumber✅ YesTotal price (0 for HOLD)
xac_nhan_cho_du_bistring✅ YesStandby seat confirmation (empty)

✅ Success Response

Status: 200 OK

{
"message": "Giữ chỗ thành công. ",
"data": {
"ve": {
"id": 82,
"pnr": "AAMJ52",
"uuid": "853d1766-aeb0-11f0-8b81-86d224031662",
"trang_thai": 0,
"ngay_het_han": "22-10-2025 06:03:00",
"hang_bay": "VJ",
"so_hieu": "VJ 9001",
"hanh_trinh": "SGN - HAN",
"ngay_bay": "25-10-2025 08:00:00",
"gia_net": 4189100,
"thue": 630500,
"ho_ten_booker": "TRAN THI BOOKER",
"email_1": "test@example.com",
"so_dien_thoai_1": "0987654321",
"email_2": "booker@example.com",
"so_dien_thoai_2": "0912345678",
"nguoi_dai_dien": "NGUYEN VAN TEST",
"tong_hanh_khach": 1,
"tong_nguoi_lon": 1,
"tong_tre_em": 0,
"tong_em_be": 0,
"ngay_book": "22-10-2025 02:02:42",
"updated_at": "22-10-2025 02:02:42"
},
"hanh_khach": [
{
"id": 107,
"ve_id": 82,
"ho": "NGUYEN VAN",
"ten": "TEST",
"email": "test@example.com",
"so_dien_thoai": "0987654321",
"ngay_sinh": "01-01-1990",
"loai_hanh_khach": 1,
"danh_xung": 1
}
],
"chang_bay": [
{
"key_chang_bay": 0,
"hang_bay": "VJ",
"so_hieu": "VJ 9001",
"hanh_trinh": "SGN - HAN",
"diem_di": "SGN",
"diem_den": "HAN",
"ngay_di": "25-10-2025 08:00:00",
"ngay_den": "25-10-2025 09:00:00",
"hang_ve": "T1_DLX",
"loai_hang_ve": "Deluxe",
"cabin": "DELUXE",
"gia_net": 4189100
}
]
},
"status": "success",
"code": 200
}

Key Response Fields:

FieldTypeDescription
data.ve.idnumberBooking ID (ve_id) - Critical for MMB operations
data.ve.pnrstringPNR - Booking reference code
data.ve.uuidstringBooking UUID
data.ve.trang_thainumberStatus: 0 = HOLD, 1 = ISSUED
data.ve.ngay_het_hanstringPayment deadline (usually +4 hours)
data.ve.gia_netnumberTotal net price
data.hanh_khach[].idnumberPassenger ID (hanh_khach_id) - For services/seats
data.chang_bay[].key_chang_baynumberFlight segment key - For services/seats

💡 Example: cURL

curl -X POST "{{base_url}}/api/v1/services/booking/v1/dat-chuyen" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"api": "VJ",
"nhieu_chang": 0,
"chuyen_bay": [{
"index": 1,
"uuid": "852ffde2-aeb0-11f0-8b81-86d224031662",
"phi_dai_ly": 0,
"index_hang_cho": 0,
"loai_phi_dai_ly": "Cơ bản"
}],
"hanh_khach": [{
"index": 1,
"ho": "NGUYEN VAN",
"ten": "TEST",
"email": "test@example.com",
"so_dien_thoai": "0987654321",
"ngay_sinh": "01-01-1990",
"the_thanh_vien": "",
"loai_hanh_khach": 1,
"danh_xung": 1,
"cha_me_id": null,
"ho_chieu": null
}],
"thong_tin_booker": {
"ho": "TRAN THI",
"ten": "BOOKER",
"email": "booker@example.com",
"so_dien_thoai": "0912345678"
},
"dich_vu": [],
"cho_ngoi": [],
"ma_khuyen_mai": "",
"trang_thai": 0,
"xac_nhan_ve_dup": "",
"xac_nhan_thay_doi_gia": "",
"tong_gia_ve": 0,
"xac_nhan_cho_du_bi": ""
}'

Response:

{
"message": "Giữ chỗ thành công. ",
"data": {
"ve": {
"id": 82,
"pnr": "AAMJ52",
"trang_thai": 0,
"ngay_het_han": "22-10-2025 06:03:00",
"gia_net": 4189100
},
"hanh_khach": [{ "id": 107 }],
"chang_bay": [{ "key_chang_bay": 0 }]
},
"status": "success"
}

Save these values:

  • data.ve.idve_id (82)
  • data.ve.pnrpnr ("AAMJ52")
  • data.hanh_khach[0].idhanh_khach_id (107)
  • data.chang_bay[0].key_chang_baykey_chang_bay_0 (0)

⚠️ Important Notes

1. Names Must Be UPPERCASE

// ✅ Correct
ho: "NGUYEN VAN";
ten: "TEST";

// ❌ Wrong
ho: "Nguyen Van";
ten: "test";

2. Date Format

ngay_sinh: "01-01-1990"; // DD-MM-YYYY

3. Passenger Index vs Fare Index

{
"hanh_khach": [{
"index": 1 // ← Passenger index (1-based)
}],
"chuyen_bay": [{
"index": 1, // ← Segment index (1-based)
"index_hang_cho": 0 // ← Fare index (0-based from search)
}]
}

4. Save These Values

After HOLD, save for later operations:

  • ve_id - For get details, add services, payment
  • pnr - For customer reference
  • hanh_khach_id - For add services/seats
  • key_chang_bay_0 - For add services/seats

5. Payment Deadline

ngay_het_han: "22-10-2025 06:03:00"; // Usually +4 hours

Booking expires if not paid before deadline.

6. Services Array (dich_vu)

Empty (No Services):

"dich_vu": []

With Services (Baggage + Meal):

"dich_vu": [
{
"index_chang_bay": 1,
"index_chuyen_bay": 1,
"index_hanh_khach": 1,
"uuid": "044a181a-093d-8541-a41e-879caac6d017"
},
{
"index_chang_bay": 1,
"index_chuyen_bay": 1,
"index_hanh_khach": 1,
"uuid": "da38876a-cbcc-cfb3-76c0-f3fb5f6632db"
}
]

Service Item Structure:

  • index_chang_bay (1-based) - Journey/segment index (always 1 for one-way)
  • index_chuyen_bay (1-based) - Flight index within journey (always 1 for direct flight)
  • index_hanh_khach (1-based) - Which passenger gets this service
  • uuid - Service UUID from Step 2.4 (Get Services List)

Important:

  • UUIDs must come from Step 2.4 (danh-sach-phu-tro-tim-ve)
  • UUIDs expire in ~5-10 minutes - fetch fresh before booking
  • For multiple passengers, add separate service items for each
  • Can leave empty [] and add services later via MMB

7. Insurance (bao_hiem) - Optional

"bao_hiem": {
"uuid": "4dc7da23-8723-57e7-848f-5706bcf32257"
}
  • Optional field for travel insurance
  • Get UUID from insurance options (if available)
  • Omit entire bao_hiem object if not selected

🐛 Common Issues

Missing Flight UUID

Response:

{
"message": "Không tìm thấy chuyến bay",
"status": "error"
}

Solution: Ensure uuid is from recent search result (not expired)


Invalid Date Format

Response:

{
"message": "Ngày sinh không hợp lệ",
"status": "error"
}

Solution: Use DD-MM-YYYY format (not YYYY-MM-DD)


Lowercase Names

Response:

{
"message": "Tên phải viết HOA",
"status": "error"
}

Solution: Convert names to UPPERCASE before sending


📊 Booking States

trang_thaiStatusDescription
0HOLDBooked but not paid - Has payment deadline
1ISSUEDTicket issued - Payment completed

Transitions:

HOLD (0) --[Payment]--> ISSUED (1)

🔗 Next Steps

After HOLD, you can:

  1. Add Services../manage-booking/UPDATE-SERVICES.md
  2. Add Seats../manage-booking/BUY-SEAT.md
  3. Payment05-PAYMENT.md (HOLD → ISSUED)

📝 Notes

  • HOLD booking has payment deadline (~4 hours)
  • Can add services/seats before payment
  • Names must be UPPERCASE
  • Date format: DD-MM-YYYY
  • Passenger index: 1-based
  • Fare index: 0-based
  • Save ve_id, pnr, hanh_khach_id, key_chang_bay for later use