Main Flows
Key request and purchase flows through the application.
See the documentation index for business context and domain overview for domain-level detail and code locations.
Tenant Request Flow
sequenceDiagram
participant Browser
participant TenantMiddleware as TenantDomainMiddleware
participant Tenancy
participant InertiaMiddleware as HandleInertiaRequests
participant Controller
participant VuePage as Vue Page (Inertia)
Browser->>TenantMiddleware: HTTP request (custom domain or subdomain)
Note over TenantMiddleware: Resolves tenant from Host / X-Forwarded-Host<br/>(Buyer reverse proxy or in-house DNS)
TenantMiddleware->>Tenancy: Load Tenant by host, call init()
Tenancy-->>TenantMiddleware: Tenant context set
TenantMiddleware->>InertiaMiddleware: Pass request
InertiaMiddleware->>InertiaMiddleware: Share theme, locale, wallet props
InertiaMiddleware->>Controller: Dispatch to route handler
Controller-->>Browser: Inertia::render('pageName', [...props])
Browser->>VuePage: Hydrate Vue component with propsPurchase Flow
End-to-end flow from catalogue through payment, asynchronous Tillo fulfilment, customer notification, and optional Buyer webhooks (e.g. cashback).
flowchart TD
A["Mall / Product pages"] --> B["Add to basket\n(BasketController)"]
B --> C["Checkout\n(CheckoutController)"]
C --> D{Active payment gateway}
D -->|Stripe| E["stripePayment page\nStripe Checkout Session"]
D -->|Checkout.com| F["checkout page\nembedded form"]
D -->|TrueLayer| G["Redirect to\nhosted payment page"]
D -->|PPS / LeisureChoice| H["checkoutVoucher page\nsync card issuance"]
D -->|TenantWallet| I["checkoutTenantWallet page\nbalance debit"]
E & F & G -->|Webhook received| J["OrderService::receivePayment()"]
H & I --> J
J --> K["Order marked 'paid'\nOrderConfirmed dispatched"]
K --> L["CreateFulfillment\n(Artisan command / job)"]
L --> M["FulfillmentItem rows created\nOrderGiftCard jobs dispatched"]
M --> N["Tillo async API\norderCard() + status poll jobs"]
N -->|Success| O["Gift card code stored\nItemFulfilled dispatched"]
N -->|Webhook from Tillo| P["TilloWebhookReceived\nupdates item status"]
O --> Q["Customer email notification"]
O --> R["Outbound webhook to Buyer\n(per gift card, optional)"]
O & P --> S["EventAuditingListener\n(DynamoDB)"]
K --> SAuth: Storefront
Credentials are stored encrypted per tenant. After login, a two-hour session is issued; on expiry the user returns to the Buyer’s site and may re-enter StoreFront with a new token if still authenticated there.
flowchart LR
subgraph storefrontAuth ["Storefront Auth (per-tenant)"]
Customer["Customer browser"] --> AuthController["AuthController\n(login / callback)"]
AuthController --> Factory["AuthProviderFactory"]
Factory --> JWT["JWTProvider"]
Factory --> OIDC["OIDCProvider"]
Factory --> OAuth["OAuthProvider"]
JWT & OIDC & OAuth --> Session["Session guard\n(customers, ~2h)"]
Session -->|Expired| BuyerSite["Redirect to Buyer site"]
BuyerSite -->|New token| AuthController
endAuth: Hub
flowchart LR
subgraph hubAuth ["Hub Auth (JWT)"]
AdminUI["Hub Admin UI"] --> BearerToken["Bearer JWT"]
BearerToken --> JWTMiddleware["VerifyJWTTokenMiddleware"]
JWTMiddleware --> TenantLookup["TenantLookupMiddleware\n(Core user ID → tenant IDs)"]
TenantLookup --> HubControllers["Hub controllers"]
end