Sincere Travels — Amadeus GDS booking
Flight search, PNR, e-ticketing and ConnectIPS payments, straight against Amadeus SOAP and NDC web services.
Background
Sincere Travels sells flights online in Nepal. The backend talks directly to the Amadeus global distribution system rather than through a reseller API. I own the backend: a consumer API behind the booking site and a dashboard API for the operations team.
The problem
Amadeus web services are SOAP and XML with WS-Security headers, stateful sessions and a booking flow of eight or more calls where any one can fail after money has moved. There is no SDK. Reseller APIs hide this but take a cut on every ticket and lag on availability.
The business also needed its own pricing: airline commissions, per-segment rules and Nepali taxes layered on the Amadeus fare, editable by staff without a deploy. And the whole thing had to take payment through Nepali gateways, not Stripe.
Approach
- Implement the classic GDS flow by hand: Fare_MasterPricerTravelBoardSearch for search, Fare_CheckRules, Air_SellFromRecommendation, PNR_AddMultiElements, Fare_PricePNRWithBookingClass, Ticket_CreateTSTFromPricing, then ticket issue per passenger reference. Typed envelopes with xmlbuilder and fast-xml-parser.
- Add the Amadeus NDC channel alongside: OfferPrice, OrderCreate, OrderPay, OrderRetrieve. NDC offers are de-duplicated against identical non-NDC fares so the customer sees one price.
- Build a rules engine: airline commissions, segment rules, active pricing rules and NQ taxes as data, all editable from the dashboard API.
- Payments through ConnectIPS with RSA-signed requests, plus Fonepay and Khalti. Guards against double ticket issue and against price drift between quote and issue.
- Ticket delivery as a BullMQ job: Puppeteer renders a Handlebars template to PDF and emails it. Separate queues for test and production, monitored with Bull Board.
- Operational safety: an audit log of every Amadeus call, a DB-backed rate limiter, OTP accounts with RSA-signed JWTs, and a hand-written OpenAPI 3 spec served at /api/docs.
Architecture
Outcome
- Live at sinceretravels.com since 2023, issuing real tickets against Amadeus production.
- NDC channel added in 2026 without changing the customer-facing search contract.
- Largest single share of commits on the backend over three years.
Lessons
- For a stateful vendor flow, log every request and response before anything else. The Amadeus audit log solved more support tickets than any other feature.
- Put money guards (double issue, price drift) in the service layer, not the UI. They caught cases the UI never saw.