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 + 1Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /bookings | User | User's bookings |
| GET | /bookings/:id | User | Single booking detail |
| POST | /bookings | User | Create booking |
| PATCH | /bookings/cancel/:id | User | Cancel booking |
| POST | /stripe/create-checkout-session | User | Create Stripe Checkout |
| POST | /stripe/webhook | Public (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
bookingIdin 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:
- Extracts
bookingIdfrom session metadata - Updates booking status to
CONFIRMED - Creates payment record with status
SUCCESS - Increments
bookingsCounton the activity - Syncs the activity to Recombee recommendations
All database operations happen inside a Prisma transaction for atomicity.
Payment Model
| Field | Description |
|---|---|
bookingId | Links to the booking |
amount | Total charged |
currency | USD or NPR |
status | PENDING / SUCCESS / FAILED / REFUNDED |
provider | STRIPE (primary) or PAYPAL (available but not implemented) |
stripePaymentIntentId | Stripe reference ID |
Stripe Configuration
| Environment Variable | Description |
|---|---|
STRIPE_SECRET_KEY | Stripe secret key (sk_test_... or sk_live_...) |
STRIPE_PUB_KEY | Stripe publishable key (pk_test_... or pk_live_...) |
STRIPE_WHSEC_KEY | Stripe webhook signing secret (whsec_...) |
Testing
- Use Stripe test mode keys (
sk_test_...,pk_test_...) - Use
whsec_...from Stripe CLI or Dashboard webhook settings - Test card:
4242 4242 4242 4242with any future expiry and any CVC - 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/:supplierIdThis returns all bookings for activities owned by the given supplier.