Travelopia

Payments portal · Tech Lead · Oct 2023 — Present · 1 min read

A 12-step payment workflow for high-value luxury itineraries, with automatic refunds on failure.

Internal tool
Create a payment link from a SoftTrip reservation
Step payment workflow
12
Brands
3
Currency
Multi

The problem

Staff needed to take and refund payments on high-value itineraries across three brands, and every payment had to land correctly in both the card processor and the reservation system.

What we did

  • Built a payments dashboard with reservation-level tracking, status (Active, Overdue), user and date filters, and brand-level visibility.
  • Created payment links from SoftTrip reservation details, and manual charges with due dates, reasons and credit card fee waivers with reason tracking.
  • Built refund flows that pull transaction history by SoftTrip reservation ID for partial or full refunds.
  • Orchestrated each payment through a 12-step AWS Step Functions state machine: validation, CyberSource tokenisation and charge, SoftTrip financial recording, confirmation email, and automated refund on failure.

Key decisions

  1. 01

    Step Functions to orchestrate each payment

    Trade-off: More infrastructure than a single API call, in exchange for visible, retryable steps for every payment.

  2. 02

    Automatic refund when a later step fails

    Trade-off: More states to design and test, so a guest is never charged for a payment that was not recorded.

  3. 03

    Retries with exponential backoff and dead-letter queues

    Trade-off: Failures resolve later instead of instantly, but none are silently dropped.

Architecture

PaymentsportalNestJS + tRPCPostgreSQLStepFunctionsCyberSourceSoftTripEmailSQS DLQ

Hover or tab through the components to trace the data path.

  • Payments portal — Dashboard, payment links, charges, refunds
  • NestJS + tRPC — Validates requests, starts workflows
  • PostgreSQL — Payment and transaction records (Prisma)
  • Step Functions — 12-step payment state machine
  • CyberSource — Tokenisation and charge
  • SoftTrip — Reservations and financial recording
  • Email — Confirmation emails
  • SQS DLQ — Retries with backoff, dead-letter queue

Screenshots

  • Manual charge with fee waiver

  • Refund from transaction history

Result

Every payment runs through the same 12-step workflow, and a failure anywhere triggers an automatic refund instead of a manual clean-up.

What I learned

  1. 01

    For money movement, make every step observable before making it fast.

  2. 02

    Design the failure path first; the happy path is the easy part.

Stack

  • AWS Step Functions
  • Lambda
  • CyberSource
  • NestJS
  • tRPC
  • Prisma
  • PostgreSQL
  • AWS SQS
  • TypeScript

Want something like this for your business?