Case 01

Travel booking across multiple suppliers

Hotel search and booking across suppliers, with payment safeguards and recovery for failed trip items.

Ongoing · since Apr 2026

Full-stack engineer and technical lead · end-to-end product and platform work

I work across supplier integrations and the booking workflows around them. The product brings hotel search and booking together across providers, while keeping failed or incomplete trip items visible for recovery.

The problem
Travellers needed one product for hotel search and booking across suppliers with different formats, changing rates, payment events, and fulfilment paths.
What I built
I built hotel adapters, catalogue matching, search and booking flows, payment safeguards, and queued fulfilment. I also owned eSIM delivery end to end and led technical work.
What changed
The product connects supplier catalogues to search and booking. Paid trips can track each item, surface partial failures, and support operational recovery through durable handoffs.
Fig. 01.1Every hotel supplier works differently — different formats, the same hotel twice, prices that change, slow replies.I built the layer that makes them speak one language, and the search, booking and delivery paths on top.

The whole reservation flow in three numbered bands, each step a product icon with a plain label, its technical name beneath, and a dashed flag where something can go wrong. Band 1, make suppliers speak one language: every supplier works differently, over REST and XML APIs (flag: different formats); one adapter per supplier, behind an adapter contract; one universal hotel model, the normalised listing model; and the same hotel shown once, through room matching, deduplication and remembered decisions (flag: the same hotel twice). Band 2, find and book reliably: search by place, asking when the place is unclear, through geospatial place resolution (flag: unclear place); the price re-checked before booking, with just-in-time rates (flag: the price has changed); and booked with the supplier safely, with the order reference saved first and bounded calls (flag: a slow supplier). Band 3, the result, deliver the whole trip: one basket for the whole trip, a trip pack with four item kinds; paid once, through idempotent payment webhooks (flag: a payment sent twice); every item tracked, through queued fulfilment and an admin alert (flag: one item fails); and one voucher, only after confirmation, through an atomic confirmation claim. Transfers, activities and eSIM are separate services plugged into the basket. Queued is not supplier confirmation.

  1. 1Make suppliers speak one language
    1. Different formatsEvery supplier works differentlyREST and XML APIs
    2. One adapter per supplierAdapter contract
    3. One universal hotel modelNormalised listing model
    4. Same hotel twiceSame hotel, shown onceRoom matching · dedup · remembered decisions
  2. 2Find and book reliably
    1. Unclear placeSearch by place; asks when unclearGeospatial place resolution
    2. Price has changedPrice re-checked before bookingJust-in-time rates
    3. Supplier slowBooked with the supplier, safelyOrder ref saved first · bounded calls
  3. 3Deliver the whole trip
    1. One basket for the whole tripTrip pack · 4 item kinds
    2. Payment sent twicePaid onceIdempotent payment webhooks
    3. One item failsEvery item trackedQueued fulfilment · admin alert
    4. One voucher, after confirmationAtomic confirmation claim
    Separate services, plugged in
    • Transfers
    • Activities
    • eSIM
Fig. 01.2 · Film · 0:10
The same hotel can arrive from different suppliers under different names; cross-provider matching shows it as one listing and remembers the decision on the next sync.
Transcript

The same hotel arrives from different suppliers under different names, "Harbour View" and "HARBOURVIEW". Both go into the matching step, and travellers see one Harbour View listing; the match is remembered, so the next supplier sync does not pair them again. Hotel names and supplier formats are examples; this is an illustrative flow, not a recording.

Connect different supplier catalogues

I built adapters for supplier REST and XML APIs, then mapped their inventory to one listing model. Room matching and deduplication bring comparable hotel inventory together across providers.

Multiple hotel adapters use the shared contract, while transfers and activities use separate services. Activity booking and cancellation scenarios ran in a supplier test environment. The execution record does not show supplier certification signoff.

Keep booking and payment recoverable

Rates can expire between search and booking, suppliers can respond slowly, and payment can arrive before fulfilment finishes. The workflow needs to show what happened to each trip item.

I built just-in-time rate checks and bounded supplier calls. Payment webhooks are idempotent, supplier order references are saved before polling, and an atomic confirmation claim gates voucher delivery. Queued fulfilment uses bounded infrastructure retries; a queued item is not supplier-confirmed, and a failed item remains visible as a partial state with an admin alert.

  1. Map supplier data to a shared listing model

    Adapters handled provider-specific contracts. The product used a shared listing model and matching logic.

  2. Make payment retries safe

    Saved supplier references and idempotent webhook handling let the payment and booking workflow handle repeated events safely.

  3. Make recovery diagnosable

    Sentry coverage across the web app, routes, scheduled work, and queue workers supports investigation. Logs do not include PII.

Keep catalogue matching consistent across syncs

Catalogue ingestion runs deduplication. Saved decisions about pairs are excluded from later linking, and the process is bounded. Search resolves places geographically and asks for clarification when candidate locations are far apart.

I also own and lead the AI booking assistant. Case 02 covers its tools, identity, and checkout boundaries; this case covers the commerce system it connects to.

Lead delivery and operations

I lead the client roadmap and technical meetings, write design specifications before implementation, and review delivery work. My work also covers Docker deployment, queue workers, customer communication, admin tools, accessibility, internationalisation, and operational recovery. Trip packs support hotels, transfers, activities, and eSIM as four item kinds; multi-component packages use a separate flow. I owned the standalone eSIM vertical end to end.

What I built

Built

  • Adapters for supplier REST and XML APIs.
  • Room matching and deduplication across suppliers.
  • Hotel search and booking across provider boundaries.

Hardened

  • Idempotent payment webhook handling.
  • Race-safe pricing and queued fulfilment paths.
  • Saved supplier order references and confirmation safeguards.

Operated

  • Sentry coverage and logs without PII.
  • Docker deployment and release work.
  • Ownership and technical leadership of the AI booking assistant.
  • TypeScript
  • Next.js
  • PostgreSQL
  • Prisma
  • Redis
  • BullMQ
  • Docker
  • Sentry