Skip to content

Bookings & Payments ​

Booking Flow ​

User browses activity → Clicks "Book Now"
         │
         ▼
Booking form (date, group size) → POST /bookings
         │
         ▼
Booking created (status: PENDING_PAYMENT)
         │
         ▼
POST /stripe/create-checkout-session → Stripe Checkout URL
         │
         ▼
User completes payment on Stripe
         │
         ▼
Stripe webhook → POST /stripe/webhook
    (checkout.session.completed)
         │
         ▼
Prisma transaction:
  - Booking status → CONFIRMED
  - Payment record → SUCCESS
  - Activity.bookingsCount + 1

Endpoints ​

MethodEndpointAuthDescription
GET/bookingsUserUser's bookings
GET/bookings/:idUserSingle booking detail
POST/bookingsUserCreate booking
PATCH/bookings/cancel/:idUserCancel booking
POST/stripe/create-checkout-sessionUserCreate Stripe Checkout
POST/stripe/webhookPublic (Stripe)Stripe webhook handler

Create Booking ​

POST /api/v1/bookings
Body: {
  activityId: number,
  startDate: string (ISO date),
  days: number,
  groupSize: number
}
Response: { booking: { id, status: "PENDING_PAYMENT", totalPrice } }

Creates a booking with PENDING_PAYMENT status and calculates totalPrice based on the activity's price × groupSize × days.

Create Stripe Checkout ​

POST /api/v1/stripe/create-checkout-session
Body: {
  activityId: number,
  startDate: string,
  days: number,
  groupSize: number,
  bookingId: number
}
Response: { sessionUrl: string }

Creates a Stripe Checkout Session and returns the URL for redirect. The session includes:

  • Line item with activity title, price, quantity
  • bookingId in metadata for webhook processing
  • Success URL → /success
  • Cancel URL → /cancel

Stripe Webhook ​

POST /api/v1/stripe/webhook
Headers: stripe-signature: whsec_...

The webhook verifies the Stripe signature using STRIPE_WHSEC_KEY, then:

  1. Extracts bookingId from session metadata
  2. Updates booking status to CONFIRMED
  3. Creates payment record with status SUCCESS
  4. Increments bookingsCount on the activity
  5. Syncs the activity to Recombee recommendations

All database operations happen inside a Prisma transaction for atomicity.

Payment Model ​

FieldDescription
bookingIdLinks to the booking
amountTotal charged
currencyUSD or NPR
statusPENDING / SUCCESS / FAILED / REFUNDED
providerSTRIPE (primary) or PAYPAL (available but not implemented)
stripePaymentIntentIdStripe reference ID

Stripe Configuration ​

Environment VariableDescription
STRIPE_SECRET_KEYStripe secret key (sk_test_... or sk_live_...)
STRIPE_PUB_KEYStripe publishable key (pk_test_... or pk_live_...)
STRIPE_WHSEC_KEYStripe webhook signing secret (whsec_...)

Testing ​

  1. Use Stripe test mode keys (sk_test_..., pk_test_...)
  2. Use whsec_... from Stripe CLI or Dashboard webhook settings
  3. Test card: 4242 4242 4242 4242 with any future expiry and any CVC
  4. For local webhook testing: stripe listen --forward-to localhost:3000/api/v1/stripe/webhook

Cancel Flow ​

PATCH /api/v1/bookings/cancel/:id
Response: { booking: { status: "CANCELLED" } }

Cancels a booking. Note: refund logic is not implemented in the API — cancellations require manual processing through the Stripe dashboard.

Supplier Booking Management ​

Suppliers can view bookings for their activities through the supplier dashboard (frontend) which calls:

GET /api/v1/bookings/supplier/:supplierId

This returns all bookings for activities owned by the given supplier.

Built with VitePress