- We offer certified developers to hire.
- We’ve performed 1500+ Web/App/eCommerce projects.
- Our clientele is 1000+.
- Free quotation on your project.
- We sign NDA for the security of your projects.
- Three months warranty on code developed by us.
A modern flight booking platform is no longer expected to stop at flight search, fare comparison, passenger details, and ticket payment. Travelers increasingly expect to customize their journey before completing a reservation. They want to choose a preferred seat, purchase additional baggage, select extra services, understand what is included in their fare, and see the total price before they pay.
For businesses building a flight booking platform, these capabilities create both a better customer experience and a significant ancillary revenue opportunity. Seat selection and baggage options can be integrated into an online travel agency platform, airline booking application, corporate travel portal, flight marketplace, or travel management system. However, implementing them correctly requires considerably more than adding two checkboxes to a booking form.
Seat availability is dynamic. Baggage allowances vary by airline, route, cabin, fare family, passenger type, and ticket conditions. Some seats are complimentary while others carry additional charges. Baggage can be included, partially included, or sold as an optional ancillary service. Prices can change between shopping and booking. A seat selected during one stage can become unavailable during another. A baggage option can have airline-specific rules. Some services may require confirmation through the airline or distribution provider before the reservation can be finalized.
This means the platform needs a carefully designed ancillary-service architecture that connects the customer-facing interface with airline content, GDS APIs, NDC APIs, airline APIs, booking systems, payment infrastructure, order management, and post-booking servicing.
The goal is not simply to “add seat selection and baggage.”
The goal is to build a reliable workflow in which the platform can:
This article explains the technical architecture, business logic, APIs, user experience, database structure, security considerations, development process, testing strategy, operational challenges, and cost factors involved in adding seat selection and baggage options to a flight booking platform.
Flight booking has traditionally focused on selling the base airfare. Modern airline retailing is increasingly based on a broader concept in which the traveler purchases a combination of transportation and optional services.
Seats and baggage are two of the most recognizable ancillary services.
For a booking platform, these services matter for three major reasons:
A traveler booking a long-haul flight may care deeply about seat location. A family may want seats together. A business traveler may prefer an aisle seat. A passenger traveling with heavy luggage may need an additional checked bag. A budget traveler may prefer to avoid paying for an optional service.
If the platform presents these choices clearly, the customer can customize the booking according to their needs.
If the platform hides the options or presents inaccurate information, the experience can quickly become frustrating.
Seat selection allows passengers to choose a specific seat from the available seating inventory of an aircraft or flight segment.
Depending on the airline and distribution channel, the platform may receive information such as:
The platform then translates this information into a user-friendly seat-selection interface.
For example, a passenger might see:
The underlying airline system may provide much more technical information than the customer needs to see. The booking platform therefore requires a transformation layer that converts supplier data into a consistent internal format.
Baggage options can include both baggage allowance information and purchasable additional baggage.
A platform may need to communicate:
For example, a fare could include:
Another fare on the same flight might include:
The traveler may then be offered an additional 10 kg, 20 kg, or one extra checked bag, depending on what the airline and distribution channel support.
This distinction is critical.
A platform should never assume that every passenger receives the same baggage allowance simply because they are traveling on the same flight.
From a technical perspective, seat selection and baggage frequently belong to the broader category of ancillary services.
Ancillary services can include:
A scalable architecture should therefore avoid designing seat selection and baggage as isolated features.
Instead, build an ancillary-service framework that can support additional services later.
This approach reduces development duplication and makes the platform easier to expand.
For example, instead of creating:
SeatService
and separately:
BaggageService
the platform can introduce an internal concept such as:
AncillaryService
with service-specific implementations.
The service can contain attributes such as:
Seat and baggage services can then use the same foundational transaction architecture.
A typical seat-selection workflow looks like this:
The exact process varies according to the airline, GDS, NDC provider, airline API, and booking model.
Some systems allow seat selection before ticket issuance. Others may require a booking record or offer reference before ancillary services can be added.
Therefore, the application should not assume one universal sequence.
The baggage workflow follows a similar pattern.
The system should distinguish between:
Included baggage
and
Purchased additional baggage
These are not the same thing.
For example:
Included: 15 kg checked baggage
Purchased: Additional 20 kg
Total permitted allowance: Subject to airline rules and applicable conditions
The platform should avoid presenting the calculated total as an unconditional guarantee if the supplier’s rules do not support that interpretation.
One of the most important technical decisions is determining where flight ancillary data will come from.
A flight booking platform may integrate with:
Common GDS ecosystems include providers such as Amadeus, Sabre, and Travelport.
NDC-based distribution can provide richer airline retailing capabilities for participating carriers, including more detailed offers and ancillary services.
The actual capabilities vary by airline and integration.
A platform should therefore treat supplier capability as a variable instead of assuming that every source supports identical seat and baggage functionality.
When a platform uses a GDS, the application typically communicates with the GDS through APIs.
The overall architecture can be represented conceptually as:
Mobile App / Web App
↓
Booking Platform Backend
↓
Flight Search Service
↓
GDS / Airline / NDC Provider
↓
Airline Inventory and Reservation Systems
The frontend should not directly communicate with the GDS.
The backend should act as an abstraction and orchestration layer.
This architecture provides several advantages:
Suppose the platform initially integrates with one supplier.
Later, the business wants to add another provider.
If the entire application is written around one provider’s proprietary response format, adding another source can become expensive.
A supplier abstraction layer solves this problem.
For example, the application can define internal methods such as:
searchFlights()
getSeatMap()
getBaggageOptions()
priceAncillaries()
addSeat()
addBaggage()
confirmBooking()
cancelAncillary()
Each supplier adapter then implements the appropriate operations.
Conceptually:
Booking Platform
|
v
Supplier Abstraction Layer
|
————————–
| | |
GDS A GDS B NDC C
The user interface remains largely independent of the underlying supplier.
This is particularly valuable for platforms that plan to support multiple airlines, regions, currencies, or distribution channels.
The seat map is one of the most visible components of the feature.
A poorly designed seat map can make a sophisticated booking platform feel unreliable.
The interface should make it immediately clear:
A common interface uses an aircraft-style visual arrangement.
For example:
FRONT
A B C D E
Row 10 □ □ □ □ □
Row 11 □ □ X □ □
Row 12 $ $ $ $ $
Row 13 E E E E E
Row 14 □ □ □ □ □
REAR
The actual aircraft configuration must come from supplier data rather than being hard-coded.
Different aircraft can have:
Therefore, the frontend should render the seat map dynamically.
A normalized seat object might contain fields such as:
{
“segmentId”: “SEG001”,
“row”: 12,
“column”: “A”,
“seatNumber”: “12A”,
“available”: true,
“price”: 1200,
“currency”: “INR”,
“seatType”: “WINDOW”,
“characteristics”: [
“WINDOW”,
“STANDARD”
],
“paid”: true
}
This is only an internal example.
Real supplier responses can be substantially more complex.
The platform should preserve important supplier metadata while exposing a simplified representation to the frontend.
A robust seat-selection engine should be capable of representing characteristics such as:
The application should not infer these attributes solely from the seat letter.
For example, seat “A” is frequently a window seat, but relying on that assumption across every aircraft configuration and supplier is unsafe.
Supplier metadata should remain the source of truth.
Seat pricing introduces another layer of complexity.
A seat may be:
The backend should therefore model seat price independently from the seat itself.
For example:
Seat:
12A
Availability:
Available
Seat category:
Preferred
Price:
INR 1,200
Currency:
INR
Tax:
Included or supplier-defined
The application should not assume that the price displayed during initial shopping remains valid indefinitely.
The final price should be validated through the relevant supplier workflow before confirmation.
Seat selection becomes more complex when a booking contains multiple passengers.
Consider a family of four.
The system needs to support:
The platform must prevent accidental assignment of the same seat to multiple passengers.
It also needs to maintain a relationship between:
A suitable internal relationship might look like:
Booking
|
+– Passenger 1
| |
| +– Segment 1
| |
| +– Seat 12A
|
+– Passenger 2
|
+– Segment 1
|
+– Seat 12B
This becomes especially important for itineraries containing multiple flight segments.
A traveler may book:
Delhi → Dubai → London
There are at least two flight segments.
The platform should treat seat selection separately for each segment.
For example:
Passenger preferences may differ between the two.
A traveler may choose:
The UI should make the segment distinction obvious.
A common usability pattern is:
Flight 1: Delhi to Dubai
[Seat Map]
Flight 2: Dubai to London
[Seat Map]
This prevents users from assuming that one seat selection applies to the entire journey.
Baggage information should be visible before the customer commits to a fare.
For example:
Economy Saver
Economy Flex
The platform should avoid ambiguous language such as:
“Free baggage included”
unless the actual allowance is clearly defined elsewhere.
Travelers need to know:
One of the most important baggage concepts is the difference between weight-based and piece-based allowances.
A weight-based rule might be represented as:
20 kg
A piece-based rule could be:
1 piece
Maximum 23 kg
These are not equivalent.
A platform’s data model should distinguish:
allowanceType = WEIGHT
from:
allowanceType = PIECE
For weight-based baggage, relevant information can include:
For piece-based baggage:
This distinction is essential for displaying accurate baggage information.
If the supplier supports paid baggage, the platform can present options such as:
However, the available options must come from the airline or supplier rules.
The platform should not create arbitrary baggage products unless it has a separate commercial arrangement with the airline.
Baggage pricing can vary according to:
Therefore, the platform should store baggage prices as service-level data rather than applying a generic fee.
Example:
Service:
Additional Checked Bag
Quantity:
1
Price:
₹3,200
Currency:
INR
Passenger:
Adult 1
Segment:
Delhi → Dubai
This makes the transaction traceable.
The checkout experience should not force customers to navigate through confusing screens.
A logical sequence can be:
Traveler chooses the flight and fare.
Traveler enters passenger information.
Traveler chooses seats for applicable passengers and segments.
Traveler reviews included baggage and adds optional baggage.
Additional services can be presented where relevant.
The customer sees:
The customer completes payment.
The platform confirms the reservation and ancillary services.
This flow is intuitive because each decision contributes directly to the final order.
The total booking amount must update whenever a customer changes an ancillary selection.
For example:
Flight fare ₹12,500
Taxes ₹2,100
Seat 14A ₹1,000
Additional baggage ₹2,800
————————————
Total ₹18,400
If the customer changes to a free seat:
Flight fare ₹12,500
Taxes ₹2,100
Seat ₹0
Additional baggage ₹2,800
————————————
Total ₹17,400
The frontend should update the displayed total, but the backend must remain authoritative.
The client should never be treated as the final source of truth for payment amounts.
One of the most important security and reliability practices is server-side price validation.
Suppose the browser sends:
{
“seat”: “14A”,
“seatPrice”: 1000
}
The server should not blindly trust the supplied price.
Instead, it should validate the selection against the supplier or the platform’s authoritative pricing data.
A secure conceptual workflow is:
Customer selects seat
↓
Frontend sends seat identifier
↓
Backend validates availability
↓
Backend validates price
↓
Backend validates passenger eligibility
↓
Backend recalculates total
↓
Payment amount generated
↓
Payment gateway receives authoritative amount
This protects the platform against tampered requests and pricing inconsistencies.
Seat inventory is dynamic.
Two customers may attempt to select the same seat at approximately the same time.
For example:
Customer A selects 14A.
Customer B also selects 14A.
The platform needs a strategy for handling this situation.
Depending on supplier capabilities, the system may:
The application should never guarantee a seat solely because it appeared available a few seconds earlier.
If the platform creates temporary selections, they should have an expiration mechanism.
For example:
Seat selection created:
16:32:00
Expires:
16:47:00
After expiration, the platform can release the temporary selection according to its own rules and supplier capabilities.
A background job can identify expired ancillary reservations.
Conceptually:
Pending Selection
|
v
Expiration Check
|
———-
| |
Valid Expired
| |
Keep Release
The exact expiration period should depend on supplier behavior rather than an arbitrary application assumption.
Baggage should be associated with the correct passenger.
Consider a booking with:
The platform should allow the traveler to specify who receives the additional baggage.
Example:
Adult 1
Additional baggage: 20 kg
Adult 2
Additional baggage: None
Child 1
Additional baggage: 10 kg
This is important because airline baggage rules may differ by passenger type.
The data model should therefore avoid storing baggage solely at booking level.
A better model is:
Booking
|
+– Passenger
|
+– Segment
|
+– Baggage Service
International flight booking platforms often need to support multiple currencies.
The seat may be priced in:
The platform should maintain clear rules around:
A platform should avoid silently converting prices without documenting the conversion logic.
For example:
Supplier price:
USD 25.00
Display currency:
INR
Exchange rate:
Platform-defined rate
Displayed amount:
₹X
At payment and settlement time, the system should preserve the original supplier amount and the converted transaction amount where applicable.
Ancillary services may have tax implications depending on jurisdiction and transaction structure.
The platform should therefore avoid assuming:
Seat price = final charge
Instead, the pricing model can distinguish:
Base ancillary price
Tax
Platform fee
Discount
Final ancillary price
Whether each component exists depends on the business model and supplier data.
The checkout should provide transparent pricing.
Customers should be able to understand why the final amount changed after selecting a seat or baggage option.
A scalable platform should have a data model that can support multiple ancillary types.
A conceptual schema could include:
id
supplier_reference
status
currency
total_amount
created_at
updated_at
id
booking_id
passenger_type
first_name
last_name
date_of_birth
id
booking_id
origin
destination
carrier
flight_number
departure_time
arrival_time
id
booking_id
passenger_id
segment_id
service_type
supplier_service_code
description
quantity
unit_price
tax
total_price
currency
status
supplier_reference
created_at
updated_at
ancillary_service_id
seat_number
row_number
column
seat_category
ancillary_service_id
allowance_type
weight
weight_unit
pieces
This approach creates a reusable foundation for future ancillary services.
Creating separate tables such as:
seat_purchases
baggage_purchases
meal_purchases
insurance_purchases
can work for a small system.
However, as the platform expands, a generic ancillary-service entity can reduce architectural fragmentation.
A scalable approach might be:
ancillary_services
|
+– seat_details
|
+– baggage_details
|
+– meal_details
|
+– lounge_details
The parent table manages common transactional attributes.
Specialized tables store service-specific information.
This makes the architecture easier to extend.
A modern booking backend may expose internal APIs such as:
GET /api/bookings/{id}/seat-map
GET /api/bookings/{id}/baggage-options
POST /api/bookings/{id}/ancillaries
PATCH /api/bookings/{id}/ancillaries/{ancillaryId}
DELETE /api/bookings/{id}/ancillaries/{ancillaryId}
POST /api/bookings/{id}/ancillaries/validate
These are conceptual examples.
The actual API design should depend on the platform’s architecture, supplier capabilities, authentication strategy, and business requirements.
An internal API can return normalized data such as:
{
“segmentId”: “SEG001”,
“cabin”: “ECONOMY”,
“rows”: [
{
“rowNumber”: 12,
“seats”: [
{
“seatNumber”: “12A”,
“position”: “WINDOW”,
“status”: “AVAILABLE”,
“price”: 1200,
“currency”: “INR”
},
{
“seatNumber”: “12B”,
“position”: “MIDDLE”,
“status”: “AVAILABLE”,
“price”: 800,
“currency”: “INR”
}
]
}
]
}
The frontend should consume this normalized structure instead of being tightly coupled to a supplier-specific API response.
A normalized baggage response might look like:
{
“segmentId”: “SEG001”,
“passengerId”: “PAX001”,
“includedAllowance”: {
“type”: “WEIGHT”,
“weight”: 15,
“unit”: “KG”
},
“options”: [
{
“code”: “BAG20”,
“description”: “Additional 20 kg”,
“weight”: 20,
“unit”: “KG”,
“price”: 2800,
“currency”: “INR”
}
]
}
Again, this is an internal representation rather than a universal supplier format.
Rather than hard-coding separate workflows, the platform can create a common service engine.
The engine can manage:
Each ancillary type then supplies its own rules.
For example:
Ancillary Engine
|
+– Seat Adapter
|
+– Baggage Adapter
|
+– Meal Adapter
|
+– Lounge Adapter
This architecture becomes increasingly valuable as the platform expands.
A seat-selection engine should account for business rules such as:
Some restrictions are airline-specific.
Therefore, the platform should store supplier-provided restrictions rather than attempting to create universal assumptions for every airline.
Baggage rules can include:
A baggage module should therefore be rules-driven rather than based on static labels.
External APIs can fail.
A robust platform should assume that:
The platform should therefore implement:
A customer should not see a raw error such as:
HTTP 502 BAD GATEWAY
Instead, the application can provide:
We could not confirm this seat right now. Please refresh the seat map and try again.
The backend logs should contain the technical details required for investigation.
Payment and ancillary-service APIs should be designed to prevent duplicate operations.
Imagine the customer clicks:
Add baggage
and the mobile connection becomes unstable.
The request reaches the server, but the response never reaches the application.
The customer taps the button again.
Without idempotency, the platform might purchase the same baggage service twice.
An idempotency key can help:
Idempotency-Key:
BOOKING123-BAG-PAX001-REQUEST001
The server can recognize duplicate requests and return the existing transaction result rather than creating a second purchase.
This is particularly important for:
Seat and baggage fees should become part of the final order total.
For example:
Base fare ₹10,000
Taxes ₹2,000
Seat selection ₹800
Baggage ₹2,500
——————————–
Total ₹15,300
The backend should calculate this amount.
The payment gateway should receive the authoritative total generated by the backend.
The frontend should not be permitted to determine the final payment amount.
Suppose the customer selects:
The payment fails.
The platform must determine what happens to those selections.
Possible strategies include:
The correct behavior depends on the supplier and booking flow.
The platform should communicate clearly if a previously selected service needs to be revalidated.
Ancillary booking introduces partial-failure cases.
For example:
Flight booking: SUCCESS
Seat assignment: SUCCESS
Baggage purchase: FAILED
Or:
Flight booking: SUCCESS
Seat assignment: FAILED
Baggage purchase: SUCCESS
The platform should have an explicit state model for such situations.
A booking should not simply be marked “failed” when the flight itself has already been successfully ticketed.
Possible internal statuses include:
PENDING
CONFIRMED
FAILED
PARTIALLY_CONFIRMED
CANCELLED
REFUND_PENDING
REFUNDED
This allows customer support and automated recovery systems to understand what actually happened.
A state machine can make the workflow more reliable.
For example:
AVAILABLE
↓
SELECTED
↓
PRICE_VALIDATED
↓
PAYMENT_PENDING
↓
PAYMENT_CONFIRMED
↓
SUPPLIER_CONFIRMATION_PENDING
↓
CONFIRMED
Failure paths can include:
PAYMENT_FAILED
SUPPLIER_FAILED
EXPIRED
CANCELLED
REFUND_PENDING
REFUNDED
This is much safer than storing a single boolean such as:
isPurchased = true
because real airline transactions have multiple states.
The baggage interface should answer three questions immediately:
A clear interface could look like:
Included baggage
15 kg checked baggage
Add baggage
○ Additional 10 kg: ₹1,700
○ Additional 20 kg: ₹2,800
○ Additional 30 kg: ₹3,900
Selected
20 kg additional baggage
Additional cost
₹2,800
The traveler should not have to navigate multiple pages simply to understand the available options.
A common UX mistake is presenting paid baggage before clearly explaining what is already included.
The platform should first establish the baseline.
For example:
Your selected fare includes 15 kg checked baggage.
Then:
Need more? Add additional baggage.
This creates transparency and reduces the risk that customers accidentally purchase something they already have.
A significant percentage of travel searches and bookings occur on mobile devices.
A desktop seat map cannot simply be compressed onto a smartphone.
Mobile seat selection may require:
The user should always know:
A sticky bottom summary can be useful:
Passenger: John
Seat: 14A
Price: ₹1,000
[Continue]
A legend should explain the visual states.
For example:
The colors and symbols should be supplemented by text or accessible labels.
Color alone should not be the only mechanism used to communicate availability.
A flight booking platform should make seat and baggage selection usable by customers with different accessibility needs.
Important considerations include:
A seat button should expose meaningful information to assistive technology.
Instead of:
Button: 14A
the accessible label could communicate:
Seat 14A, window, available, ₹1,000
This gives the traveler meaningful context.
Family seating is a common reason travelers use seat-selection functionality.
The platform should make adjacent seats easy to identify.
For example:
Adult 1
[14A]
Adult 2
[14B]
Child
[14C]
The interface could show selected seats across the same row.
However, the application should not promise adjacent seating unless the supplier confirms it.
A better message is:
We found three adjacent seats. Seat availability can change until your booking is confirmed.
This sets appropriate expectations.
Certain seats may have eligibility restrictions.
Exit-row seats, for example, may have additional requirements.
The platform should rely on airline and supplier rules rather than allowing every passenger to select every seat.
If the supplier marks a seat as restricted, the platform should prevent unauthorized selection.
The UI can explain:
This seat has passenger eligibility restrictions.
The exact restriction should be displayed only when appropriate and supported by the underlying data.
Passenger type can affect baggage eligibility.
The platform should therefore represent passenger categories explicitly.
For example:
ADT = Adult
CHD = Child
INF = Infant
The actual rules depend on airline policy.
The baggage engine should not apply adult rules automatically to every passenger.
Supplier systems frequently identify services using codes.
For example, a baggage service could have:
Service code:
BG20
A seat service could have:
Seat:
14A
The platform should preserve supplier codes where possible.
A normalized internal representation can store:
internalServiceId
supplierServiceCode
supplier
segmentId
passengerId
This improves traceability and simplifies support investigations.
For every ancillary transaction, maintain both:
For example:
Internal ancillary ID:
ANC-982734
Supplier reference:
SUP-ABCD1234
This makes it possible for customer support and engineering teams to trace a transaction across systems.
It also helps during reconciliation.
Every important ancillary action should be logged.
Examples include:
The audit record can include:
Sensitive payment information should never be unnecessarily stored in application logs.
Flight booking platforms process sensitive customer and transaction information.
The platform should apply strong security controls across:
API credentials for GDS, NDC, airline, and payment providers should never be embedded in the mobile or browser application.
They belong on secured backend infrastructure.
The frontend should never contain supplier credentials such as:
GDS_API_KEY
GDS_SECRET
AIRLINE_API_TOKEN
Instead:
Frontend
↓
Application Backend
↓
Secure Secret Store
↓
Supplier API
Secrets should be rotated according to organizational security policies.
Production credentials should also be separated from development and testing credentials.
If the platform processes card payments, payment architecture should be designed according to the applicable payment security requirements.
Whenever possible, businesses can reduce their exposure by using payment-provider-hosted components or tokenization mechanisms rather than handling raw card data directly.
The booking platform should focus on securely receiving payment outcomes and transaction references.
A malicious user could attempt to modify:
{
“seatPrice”: 1
}
instead of:
{
“seatPrice”: 1200
}
The backend must ignore client-supplied prices as authoritative values.
Instead:
Client:
seat = 12A
Backend:
retrieve authoritative price
Backend:
calculate total
Payment:
use backend-generated amount
This is one of the most important security principles for ancillary commerce.
The system should use:
For example, the database can prevent duplicate active services for the same:
booking
passenger
segment
service
when the business rules do not allow duplicates.
Caching requires careful consideration.
Flight availability changes rapidly.
Long-lived seat-map caching can cause stale information.
A safer approach may involve:
The platform should never assume that cached seat availability guarantees inventory.
Seat-map responses can be relatively large, especially for multiple cabins.
Performance techniques include:
The goal is to make seat selection feel immediate while preserving accuracy.
A production booking platform should monitor:
Operational dashboards can help identify problems before they become widespread.
For example:
Seat Map Success Rate: 98.9%
Average Response Time: 1.4 sec
Baggage Success Rate: 99.2%
Ancillary Confirmation: 98.4%
Price Validation Errors: 0.7%
The exact metrics depend on the platform.
A booking request can travel through several services:
Mobile App
↓
API Gateway
↓
Booking Service
↓
Ancillary Service
↓
Supplier Adapter
↓
GDS/NDC
↓
Airline
Without a correlation ID, diagnosing failures can be difficult.
A request can carry:
X-Correlation-ID:
BOOKING-20260912-93827
That identifier can appear in internal logs across the request chain.
This enables engineers to reconstruct what happened.
Seat selection should be tested beyond basic happy-path scenarios.
Important test cases include:
Automated tests should cover the business logic.
End-to-end tests should validate the complete booking flow.
Baggage testing should include:
Edge cases are especially important because baggage rules can vary substantially.
A useful test scenario is:
The system should not silently charge a different amount.
Transparency is important for customer trust.
Concurrency testing should simulate multiple customers selecting the same seat.
For example:
User A → selects 14A
User B → selects 14A
User C → selects 14A
The system should ensure that the supplier’s confirmed state wins.
The platform should not create three confirmed assignments for one physical seat.
Mobile customers can experience:
The booking platform should handle these situations without creating duplicate purchases.
Idempotency and transaction-state management are particularly important here.
Test the complete sequence:
Search
→ Select flight
→ Enter passengers
→ Select seat
→ Add baggage
→ Review
→ Pay
→ Confirm
Then test alternative paths:
Search
→ Select flight
→ Skip seat
→ Add baggage
→ Pay
And:
Search
→ Select flight
→ Select seat
→ Skip baggage
→ Pay
Customers should not be forced to purchase ancillary services.
This is one of the most important operational scenarios.
Suppose:
Ticket:
Confirmed
Seat:
Failed
Baggage:
Confirmed
The system should communicate clearly:
Your flight booking and baggage have been confirmed. We could not confirm the selected seat.
The platform may then:
The correct workflow depends on supplier capabilities.
Ancillary refunds should be treated as transactions.
The system can maintain:
Ancillary Charge
↓
Refund Requested
↓
Supplier Refund
↓
Payment Refund
↓
Refund Confirmed
The platform should track:
This is preferable to simply changing an ancillary record from “paid” to “cancelled.”
Not every seat or baggage service is necessarily refundable under identical conditions.
The platform should display applicable rules when available.
For example:
Seat selection may be non-refundable after confirmation.
or:
Additional baggage can be cancelled subject to airline conditions.
The wording should reflect actual supplier terms.
Avoid universal statements when airline policies differ.
A mature booking platform should give support teams visibility into ancillary transactions.
An agent should be able to see:
Booking:
ABC123
Passenger:
John Smith
Segment:
Delhi → Dubai
Seat:
14A
Seat Status:
Confirmed
Seat Price:
₹1,000
Baggage:
Additional 20 kg
Baggage Status:
Confirmed
Baggage Price:
₹2,800
Support teams should also be able to identify supplier references and transaction histories.
The administration dashboard can provide:
Analytics can then help the business understand how travelers use ancillary services.
Useful metrics include:
Seat selection conversion
Seat purchases / Eligible bookings × 100
Baggage attachment rate
Bookings with paid baggage / Eligible bookings × 100
Ancillary revenue per booking
Total ancillary revenue / Total bookings
Ancillary failure rate
Failed ancillary transactions / Ancillary transactions × 100
These metrics can reveal whether the feature is delivering both customer and business value.
Once the technical foundation works reliably, the business can optimize presentation.
Potential strategies include:
However, optimization should never compromise transparency.
Customers should understand what they are purchasing.
Baggage can also be presented through carefully designed choices.
For example:
Your fare includes 15 kg. Add 20 kg for ₹2,800.
The platform can make the additional option easy to understand without misleading the customer.
Businesses can test:
Any automated recommendation should still respect supplier availability and eligibility.
The platform can potentially offer ancillary bundles such as:
Travel Comfort Bundle
Preferred seat
+
Additional baggage
+
Priority boarding
Whether such bundling is technically and commercially possible depends on supplier support.
The architecture should treat the bundle as a collection of services rather than assuming it is one airline product.
A scalable architecture can be divided into modules.
Responsible for:
Responsible for:
Responsible for:
Responsible for:
Responsible for:
Responsible for:
Responsible for:
This separation improves maintainability.
A conceptual architecture could look like:
WEB / MOBILE APP
|
v
API GATEWAY
|
———————————
| | |
Flight Service Booking Service User Service
|
v
Ancillary Engine
/ \
/ \
Seat Service Baggage Service
\ /
\ /
Supplier Layer
/ | \
GDS NDC Airline API
|
v
Payment Service
|
v
Payment Gateway
This structure separates user interaction from supplier integration and transaction processing.
The technology stack can vary based on business requirements.
A typical platform might use:
The most important factor is not the popularity of a particular framework.
The architecture should support reliability, maintainability, security, scalability, and supplier integration.
Every airline or distribution source may represent information differently.
One provider might describe seat availability as:
AVAILABLE
Another may use:
O
Another might use a different supplier-specific code.
The platform should translate these values into a consistent internal representation.
For example:
Supplier-specific:
O
Internal:
AVAILABLE
Likewise:
Supplier-specific:
20KG
Internal:
{
“type”: “WEIGHT”,
“value”: 20,
“unit”: “KG”
}
Normalization keeps the frontend simple.
A multi-airline booking platform may eventually integrate multiple inventory sources.
The architecture should support:
Supplier A
Supplier B
Supplier C
Supplier D
The ancillary layer can determine:
This is why supplier metadata must remain attached to the booking and ancillary transaction.
A useful internal concept is a supplier capability matrix.
For example:
| Capability | Supplier A | Supplier B | Supplier C |
| Flight search | Yes | Yes | Yes |
| Seat map | Yes | Yes | Partial |
| Paid seats | Yes | Yes | No |
| Baggage purchase | Yes | Partial | Yes |
| Ancillary refund | Yes | Partial | No |
| Real-time pricing | Yes | Yes | Yes |
This allows the application to adapt the user experience.
If a supplier does not support baggage purchase, the UI should not display a purchase option.
Not every airline will provide the same ancillary functionality.
The platform should degrade gracefully.
For example:
Airline A
Seat selection available
Baggage purchase available
Airline B
Seat selection available
Baggage purchase unavailable
Airline C
Seat selection unavailable
Baggage purchase available
The customer should still be able to complete the booking where possible.
The absence of an ancillary feature should not unnecessarily prevent flight booking.
Hard-coding rules such as:
All economy passengers get 15 kg
is dangerous.
Airline rules can vary by:
The system should use authoritative supplier information wherever possible.
Static rules should only be used for documented business requirements that are intentionally controlled by the platform.
There is a strategic UX question:
Should seat and baggage options be loaded immediately during flight search?
Usually, loading every ancillary detail for every search result can be expensive.
A better approach can be:
Search flights
↓
Display flight results
↓
Customer selects itinerary
↓
Load detailed ancillary information
This reduces unnecessary supplier requests.
The exact approach depends on API capabilities and business requirements.
The flight details page should provide a summary of ancillary eligibility.
For example:
Selected fare
Economy Flex
Included
Optional
This lets customers make an informed decision before reaching payment.
A major UX principle is price transparency.
The customer should not discover the seat or baggage fee only after entering payment information.
Instead:
Flight:
₹12,500
Seat:
₹1,000
Baggage:
₹2,800
Total:
₹16,300
should be visible before final payment.
This can reduce abandoned bookings caused by unexpected price increases.
The platform can also incorporate ancillary differences into fare comparison.
For example:
| Feature | Basic | Flex |
| Cabin baggage | 7 kg | 7 kg |
| Checked baggage | Not included | 20 kg |
| Standard seat | Paid | Included |
| Changes | Restricted | More flexible |
This helps customers compare the actual value of fares rather than comparing only the base ticket price.
Seat and baggage data should be considered dynamic.
A robust workflow therefore includes multiple validation points:
When the customer selects a service.
Before generating the final payment amount.
When confirming the ancillary with the supplier.
This layered validation approach reduces the probability of selling an unavailable or incorrectly priced service.
Technical errors should be translated into useful customer messages.
Instead of:
AncillaryServiceException: code 421
show:
This baggage option is no longer available. Please choose another option.
Instead of:
SEAT_UNAVAILABLE
show:
Seat 14A was just selected by another traveler. Please choose another available seat.
The technical error should still be logged internally.
A customer may keep the seat map open for several minutes.
The platform should be able to refresh availability.
A simple option is:
Refresh seat availability
When refreshed:
This is particularly important when inventory is volatile.
Native and cross-platform mobile apps need to handle connectivity interruptions.
The application should avoid assuming:
Button clicked = transaction completed
Instead, the application can show:
Confirming your seat selection…
If the response is lost, the app should query booking status rather than automatically submitting the same purchase again.
This is another reason idempotent backend APIs are important.
After successful booking, the confirmation message should contain:
For example:
Booking confirmed
Passenger:
John Smith
Flight:
Delhi → Dubai
Seat:
14A
Included baggage:
15 kg
Additional baggage:
20 kg
Additional baggage purchased:
₹2,800
The final confirmation should reflect confirmed information rather than merely requested information.
A subtle but important architectural distinction is:
requestedSeat = 14A
versus:
confirmedSeat = 14A
The platform should not display a service as confirmed until the relevant supplier transaction has succeeded.
This becomes critical when supplier calls fail after payment.
If the platform eventually plans to offer:
then the current seat and baggage implementation should be designed as the first stage of a broader ancillary-commerce platform.
A generic model can support:
Ancillary Type:
SEAT
BAGGAGE
MEAL
LOUNGE
PRIORITY
INSURANCE
Each service can have specialized attributes while sharing:
This reduces long-term technical debt.
Flight inventory changes continuously.
Airline policies vary.
Prices must be validated server-side.
Ancillaries can be segment-specific.
Different passengers may have different services.
Supplier capabilities differ.
Ticketing and ancillary confirmation can have different outcomes.
Network failures can produce duplicate transactions.
Travelers frequently use mobile devices.
Customers should know what is already included.
It is an inventory and transaction workflow.
Transaction history is essential for troubleshooting and reconciliation.
A development team can implement the feature in phases.
Document:
Determine:
Create:
Build:
Implement:
Develop:
Run:
Track:
Building a reliable flight booking platform with ancillary services generally requires more than one frontend developer.
A typical project may involve:
The exact team size depends on the platform’s complexity.
A small MVP can begin with a smaller team, while a multi-airline enterprise platform may require dedicated specialists.
Seat selection and baggage should not be treated as a tiny add-on to a basic flight search application.
The complexity increases when the platform requires:
A simple informational seat display is relatively straightforward.
Real-time seat booking and baggage purchasing integrated with airline inventory is substantially more complex.
An MVP can focus on:
An advanced platform can add:
Starting with a focused MVP can reduce unnecessary complexity while creating a foundation for later expansion.
The most important principle is simple:
Treat seat selection and baggage as transactional airline services, not decorative checkout features.
A successful implementation needs:
When these components work together, the platform can provide travelers with a seamless way to customize their flight while giving the business a scalable foundation for broader ancillary commerce.
The next stage of the architecture is to connect these components into a complete end-to-end booking workflow, including GDS and NDC integration, seat-map retrieval, baggage-service discovery, pricing validation, payment authorization, ancillary confirmation, post-booking changes, refunds, analytics, security, and production deployment.