Skip to main content
Was this helpful?

Stripe and Paid Bookings

This page is the developer-side companion to the organisation billing and paid booking user guides. Use it when you need to trace the billing stack, run the local payment loop, or update docs and screenshots safely.

Core Backend Modules

Organisation billing and public-booking payment code lives here:

  • backend-nestjs/src/organisations/organisation-stripe-connect.service.ts
  • backend-nestjs/src/organisations/stripe-connect.gateway.ts
  • backend-nestjs/src/payments/public-booking-payment.service.ts
  • backend-nestjs/src/payments/stripe-payments.gateway.ts
  • backend-nestjs/src/payments/stripe-webhook.service.ts
  • backend-nestjs/src/resources/public-booking.service.ts

Useful frontend surfaces:

  • frontend/src/components/reservation/OrganisationBillingSettingsPanel.tsx
  • frontend/src/components/ReservationsPanel.tsx
  • frontend/src/components/public-booking/PublicBookingExperience.tsx
  • frontend/src/services/organisationBillingApi.ts

Booking State Machine

Free booking

draft request -> confirmed reservation

Payment-required booking

draft request -> pending_payment reservation -> Stripe Checkout -> webhook success -> confirmed reservation

Key points:

  • the reservation is created before Stripe succeeds
  • the reservation is not fully confirmed until the webhook updates it
  • the browser redirect is helpful UX, but not the payment source of truth

Local Environment

Use test credentials only in development.

Minimum environment:

STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
FRONTEND_URL=http://127.0.0.1:4173
BACKEND_URL=http://127.0.0.1:8081
STRIPE_CONNECT_RETURN_PATH=/settings/billing/stripe
STRIPE_CONNECT_REFRESH_PATH=/settings/billing/stripe/refresh

PrimeCal also uses the configured public booking return paths when it builds Stripe Checkout return URLs.

Local Webhook Loop

Typical workflow:

  1. start backend
  2. start frontend
  3. seed docs-safe reservation data if needed
  4. connect the organisation in Stripe test mode
  5. create a payment-required public booking
  6. forward Stripe webhooks to POST /api/payments/stripe/webhook
  7. confirm the reservation moves from pending_payment to confirmed

Keep webhook signatures enabled. Do not short-circuit signature verification in normal local development.

API Surfaces To Watch

  • organisation billing:
    • PATCH /api/organisations/:id/billing
    • GET /api/organisations/:id/stripe/status
    • POST /api/organisations/:id/stripe/onboarding-link
    • POST /api/organisations/:id/stripe/dashboard-link
    • POST /api/organisations/:id/stripe/disconnect
  • public booking:
    • POST /api/public/booking/organisations/:slug/reserve
    • GET /api/public/booking/organisations/:slug/checkout-status
    • POST /api/payments/stripe/webhook

Screenshot Automation

For docs work, use the enterprise reservation screenshot runbook plus the local Playwright docs captures:

E2E_DOCS_SCREENSHOTS=true npm run test:e2e:web -- --grep "Docs screenshots"

This automation is meant for docs-safe states only:

  • disconnected billing
  • connected billing
  • paid booking configuration
  • public payment step before Stripe Checkout

When Playwright capture is not enough, finish the sequence with the Browser MCP manual workflow documented in the MCP section.

Safety Notes

  • Never commit live Stripe keys.
  • Never log webhook secrets, full Checkout URLs with sensitive query state, or raw customer payment data.
  • Keep documentation screenshots free of real emails, phone numbers, and customer names.