Owner: Dev Team | Last Updated: 2026-02-21 | Status: Current
Data flows for the key business processes of Booking.
1. Customer opens embed widget
└── EmbedController returns Vue SPA
2. Widget loads available experiences
└── GET /api/v1/xp/available
└── ExperienceService::getAvailableExperiences()
└── Redis cache check → DB fallback
3. Customer selects experience + date + tickets
└── CheckAvailabilityService validates capacity
4. Cost calculation
└── POST /api/v1/payments/create
└── BookingService::getBookingCost()
├── ExperiencePricing (base price)
├── DynamicPricingService (adjustments)
├── Coupon validation & discount
├── GiftCard validation & deduction
├── Tax calculation (TAX_RATE)
└── StripeService::createPaymentIntent()
└── Stripe API (manual capture)
5. Customer completes payment
└── Stripe.js confirmPayment()
└── Stripe processes card
6. Booking confirmation
└── POST /api/v1/payments/capture
└── BookingService::createBooking()
├── Customer create/update
├── OrderService::embedCreateOrder()
│ ├── Order created
│ ├── OrderExperience created
│ └── OrderExperienceItem created
├── PaymentService::createPayment()
├── StripeService::capturePaymentIntent()
├── GiftCardTransaction update
├── LeadService::handleLeadAfterPayment()
└── OrderPaidAction (notifications)
├── Customer confirmation email
└── Admin notification
1. Lead Creation (from embed or manual)
└── LeadService::createLead()
├── Lead created (status: NEW)
├── LeadExperience created
├── LeadHistory (system record)
└── LeadCreateAction (notification)
2. Manager Assignment
└── LeadService::assignUser()
├── Lead.assigned_id updated
└── LeadHistory (system record)
3. Manager Interaction
└── LeadService::addComment()
└── LeadHistory (manager comment)
4. Payment Link Sent
└── Lead.status → PAYMENT
└── Lead.step → PAYMENT
5. Customer Pays
└── BookingService::createBooking()
└── LeadService::handleLeadAfterPayment()
└── Lead.status → CLOSED
6. Automated Processing
├── Hourly: ProcessAbandonedLeads
│ └── Leads without response → flagged
├── Daily 09:00: SendLeadsDigest
│ └── Email digest to managers
└── Scheduled: SendScheduledLeadsDigest
└── Per-user schedule settings
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Client │ │ Booking │ │ Stripe │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ Request cost │ │
│─────────────────>│ │
│ │ Create PI │
│ │ (manual capture)│
│ │─────────────────>│
│ │ client_secret │
│ │<─────────────────│
│ client_secret │ │
│<─────────────────│ │
│ │ │
│ confirmPayment │ │
│──────────────────┼─────────────────>│
│ │ │
│ Payment OK │ │
│<─────────────────┼──────────────────│
│ │ │
│ Create booking │ │
│─────────────────>│ │
│ │ Capture PI │
│ │─────────────────>│
│ │ Captured │
│ │<─────────────────│
│ │ │
│ Confirmation │ │
│<─────────────────│ │
│ │ │
│ │ Webhook event │
│ │<─────────────────│
│ │ Process webhook │
│ │─────────────────>│
1. Bokun sends availability request
└── POST /api/v1/cm/availability
└── AvailabilityController
└── Check capacity for dates
2. Bokun reserves booking
└── POST /api/v1/cm/booking/reserve
└── BookingController
├── Validate capacity
├── Create temporary reservation
└── Return confirmation code
3. Bokun confirms booking
└── POST /api/v1/cm/booking/confirm
└── BookingService (ChannelManager)
├── Create Order
├── Create ChannelManagerExternalBooking
└── Update capacity
4. Bokun cancels/amends
└── POST /api/v1/cm/booking/cancel|amend
└── Update/cancel existing booking
02:00 AM → SyncExperiencesCommand
└── CompanySyncService
├── CompanyTourSyncService
│ └── ProxyService → External Tours API
│ └── Sync tours data
└── CompanyBikeSyncService
└── ProxyService → External Bikes API
└── Sync bikes data
1. Auto-creation from booking
└── OrderService::createInvoiceOrderData()
└── Invoice created with line items
2. Manual creation
└── InvoiceController::store()
└── InvoiceService::create()
3. Payment recording
└── InvoiceController::addPayment()
├── InvoicePayment created
├── remaining_amount updated
└── Status → Paid (if fully paid)
4. Send to customer
└── SendInvoiceAction
└── Email with PDF attachment
1. Refund requested
└── RefundController::store()
├── Refund created (status: PENDING)
└── Notification to admin
2. Admin approves
└── ChangeRefundStatusAction
├── Refund.status → APPROVED
└── StripeService::refund()
└── Stripe processes refund
3. Refund processed
└── Refund.status → PROCESSED
├── Payment record (type: REFUND)
├── OrderExperience.is_refunded = true
└── Customer notification
| Date | Author | Change |
|---|---|---|
| 2026-02-21 | Documentation Team | Initial creation |
Prev: Overview | Next: Data Models | Up: Architecture