Skip to main content

Get Services - Lấy Danh Sách Dịch Vụ

API Endpoint: POST /api/v1/services/booking/v1/danh-sach-phu-tro-tim-ve


📋 Overview

Lấy danh sách dịch vụ & ghế khả dụng cho chuyến bay đã chọn.

Services Available:

  • Baggage (Hành lý ký gửi): 20kg, 30kg, 40kg, Oversize
  • Food (Suất ăn): Combo meals, drinks
  • Seats (Chỗ ngồi): Standard, Extra legroom, Exit row

When to call: After search flights, before hold/issue booking.


🔌 API Specification

Endpoint

POST {{base_url}}/api/v1/services/booking/v1/danh-sach-phu-tro-tim-ve

Headers

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

Request Body

For New Booking (Before HOLD):

{
"chang_bay": [
{
"index": 0,
"uuid": "1f4a8f90-ba1a-11f0-a743-e69416960d28",
"index_hang_cho": 0
}
],
"hanh_khach": [
{
"index": 1,
"hanh_khach_id": 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
}
]
}

For Existing Booking (MMB):

{
"chang_bay": [
{
"index": 0,
"index_chuyen_bay": 0,
"ve_id": 123
}
]
}

Fields:

FieldTypeRequiredDescription
chang_bayarray✅ YesFlight segments
chang_bay[].indexnumber✅ YesSegment index (0-based)
chang_bay[].uuidstring⚠️ For NewFlight UUID from search (for new booking)
chang_bay[].index_hang_chonumber⚠️ For NewSelected fare index (0-based, for new booking)
chang_bay[].index_chuyen_baynumber⚠️ For MMBFlight index (0-based, for existing booking)
chang_bay[].ve_idnumber/null⚠️ For MMBBooking ID (for existing booking only)
hanh_khacharray⚠️ For NewPassenger information (for new booking)
hanh_khach[].indexnumber⚠️ For NewPassenger index (1-based)
hanh_khach[].hanh_khach_idnumber⚠️ For NewSet to 1 for new booking (temp ID)
hanh_khach[].hostring⚠️ For NewLast name (UPPERCASE)
hanh_khach[].tenstring⚠️ For NewFirst name (UPPERCASE)
hanh_khach[].emailstring⚠️ For NewEmail address
hanh_khach[].so_dien_thoaistring⚠️ For NewPhone number
hanh_khach[].ngay_sinhstring⚠️ For NewDate of birth (DD-MM-YYYY)
hanh_khach[].loai_hanh_khachnumber⚠️ For NewPassenger type: 1=Adult, 2=Child, 3=Infant
hanh_khach[].danh_xungnumber⚠️ For NewTitle: 1=Mr, 2=Mrs, 3=Ms

Important:

  • For new booking (before HOLD): Use uuid, index_hang_cho, and hanh_khach array
  • For existing booking (MMB): Use index_chuyen_bay and ve_id only
  • hanh_khach_id can be set to 1 for new bookings (temporary, will be replaced after booking)
  • Passenger info is needed to calculate age-specific pricing (child/infant discounts)

✅ Success Response

Status: 200 OK

{
"message": "Lấy danh sách phụ trợ thành công",
"data": {
"0": {
"dich_vu": {
"0": [
{
"uuid": "7a3251f4-aee4-11f0-bd8c-86d224031662",
"ma": "encoded-service-code",
"ten": "Bag 30kgs",
"ten_hien_thi": "Gói 30kg",
"nhom": "Hành lý ký gửi",
"mo_ta_nhom": "Baggage",
"mo_ta": "Baggage 30kgs",
"loai_dich_vu": 2,
"so_kg": "30",
"gia_fare": 300000,
"thue_phi": 24000,
"gia_net": 324000,
"hang_bay": "VJ",
"hinh_anh": "http://..."
},
{
"uuid": "7a35fd6e-aee4-11f0-bd8c-86d224031662",
"ten": "Combo 1",
"ten_hien_thi": "Combo ZALO1",
"nhom": "Suất ăn",
"mo_ta_nhom": "Food",
"loai_dich_vu": 1,
"gia_net": 60000,
"hang_bay": "VJ"
}
]
},
"cho_ngoi": {
"1": {
"A": {
"ma_ghe": "1A",
"ma_cho_ngoi": "encoded-seat-code",
"uuid": "7a5a0c96-aee4-11f0-bd8c-86d224031662",
"gia_net": 64800,
"gia_fare": 60000,
"thue_phi": 4800,
"hop_le": true,
"trang_thai": false,
"loi_thoat": true,
"hang_bay": "VJ",
"index_chuyen_bay": 0
}
}
}
}
},
"status": "success",
"code": 200
}

📦 Response Structure

Services (dich_vu)

data["0"].dich_vu["0"]; // Array of services

Service Object:

FieldTypeDescription
uuidstringService UUID (for booking)
mastringEncoded service code
tenstringService name
ten_hien_thistringDisplay name
nhomstringCategory: "Hành lý ký gửi", "Suất ăn"
loai_dich_vunumberType: 1 = Food, 2 = Baggage
gia_netnumberTotal price (VND)
gia_farenumberBase fare
thue_phinumberTax/fee
so_kgstringWeight (baggage only)

Seats (cho_ngoi)

data["0"].cho_ngoi; // Object keyed by row number

Seat Map Structure:

{
"1": { // Row number
"A": { seat_object }, // Column A
"B": { seat_object }, // Column B
...
},
"2": { ... }
}

Seat Object:

FieldTypeDescription
uuidstringSeat UUID (for booking)
ma_ghestringSeat number (e.g., "1A", "12F")
ma_cho_ngoistringEncoded seat code
gia_netnumberSeat price (VND)
hop_lebooleanAvailable: true = can book
trang_thaibooleanOccupied: true = already booked
loi_thoatbooleanExit row: true = yes
index_chuyen_baynumberFlight index (0-based)

💡 Example: cURL

curl -X POST "{{base_url}}/api/v1/services/booking/v1/danh-sach-phu-tro-tim-ve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {access_token}" \
-d '{
"chang_bay": [{
"index": 0,
"uuid": "1f4a8f90-ba1a-11f0-a743-e69416960d28",
"index_hang_cho": 0
}],
"hanh_khach": [{
"index": 1,
"hanh_khach_id": 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
}]
}'

🔍 Filtering Services

Baggage Only

const baggage = services.filter((s) => s.loai_dich_vu === 2);

Food Only

const food = services.filter((s) => s.loai_dich_vu === 1);

Non-Free Services

const paidServices = services.filter((s) => s.gia_net > 0);

🔍 Filtering Seats

Available Seats Only

// Flatten seat map
const allSeats = [];
Object.keys(seatMap).forEach((row) => {
Object.keys(seatMap[row]).forEach((col) => {
const seat = seatMap[row][col];
if (seat) allSeats.push(seat);
});
});

// Filter available
const availableSeats = allSeats.filter(
(s) => s.hop_le === true && s.trang_thai === false,
);

Exit Row Seats

const exitSeats = availableSeats.filter((s) => s.loi_thoat === true);

By Price Range

// Standard seats (cheapest)
const standardSeats = availableSeats.filter((s) => s.gia_net < 50000);

// Premium seats
const premiumSeats = availableSeats.filter((s) => s.gia_net >= 50000);

⚠️ Important Notes

1. Service Types

loai_dich_vuCategoryExamples
1Food (Suất ăn)Combo meals, snacks, drinks
2Baggage (Hành lý)20kg, 30kg, 40kg, Oversize

2. Seat Availability

// Check if seat can be booked
if (seat.hop_le === true && seat.trang_thai === false) {
// Available to book
}
  • hop_le: true = Valid seat (not blocked)
  • trang_thai: false = Not occupied yet

3. UUID Expiration

Important: UUIDs expire quickly (~5-10 minutes)

  • Get fresh services/seats before booking
  • Don't cache UUIDs for long periods
  • If booking fails with "UUID không tồn tại", re-fetch

4. Free vs Paid

Some services/seats may be free (gia_net: 0):

  • Free baggage in DELUXE/SKYBOSS fare
  • Free seat selection in premium cabins
  • Promotional items

5. New Booking vs MMB (Existing Booking)

New Booking (Before HOLD):

{
"chang_bay": [{
"index": 0,
"uuid": "flight-uuid-from-search",
"index_hang_cho": 0
}],
"hanh_khach": [{ /* passenger info */ }]
}

Existing Booking (MMB - Add Services):

{
"chang_bay": [{
"index": 0,
"index_chuyen_bay": 0,
"ve_id": 104
}]
}

Key Differences:

  • New booking: Use uuid + index_hang_cho + hanh_khach
  • MMB: Use index_chuyen_bay + ve_id (no hanh_khach needed)

🔗 Next Steps

After getting services/seats:

  1. Select items → Save UUIDs
  2. Add to booking → See next doc:
    • 04-SELECT-SERVICES-SEATS.md - Choose baggage/food/seats
  3. Hold/Issue → Include in booking request:
    • 05-HOLD-BOOKING.md
    • 06-ISSUE-TICKET.md

📝 Notes

  • Returns both services (baggage, food) and seats in one API call
  • UUIDs expire quickly - fetch fresh before booking
  • New booking: Requires uuid, index_hang_cho, and hanh_khach array
  • MMB (existing): Requires index_chuyen_bay and ve_id only
  • loai_dich_vu: 1 = Food, 2 = Baggage
  • Check hop_le: true and trang_thai: false for available seats
  • Seat prices vary by position (exit row more expensive)
  • Some items may be free (gia_net: 0) depending on fare class
  • Passenger info needed for age-based pricing (child/infant discounts)