Skip to content
TilloTech Docs

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 props

Purchase 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 --> S

Auth: 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
    end

Auth: 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