Architecture

The SaaS Template is a Laravel 12 application with a single Filament 4 panel and Stripe billing through Cashier. The User model is the Cashier billable entity. Subscription state is exposed as computed attributes, enforced by a panel-wide middleware, and kept in sync with Stripe through webhooks and model observers.

Overview

  • Filament Panel — The app panel at /app with login, registration, and profile. A Subscribed middleware is part of the panel's auth middleware.
  • Cashier Billing — Cashier::useCustomerModel(User::class) and the Billable trait on User. Subscriptions use the name default.
  • Observers — UserObserver assigns the Customer role on creation. ProductObserver mirrors products and prices to Stripe.
  • Event Listeners — AddUserFreeTrialOnUserCreation reacts to Filament's Registered event, and the queued StripeEventListener reacts to Cashier's WebhookReceived event.
  • Permission-Driven Authorization — Policies map to <Model>.<ability> permissions, with a Gate::before bypass for Super Admin.
  • Operations — Activity log, email log, health checks, backups, and Sentry, as in the Web App Template.

Subscription Model

Two traits on User hold the billing logic.

  • Name
    hasActiveTrial
    Type
    attribute
    Description

    True when the user is on a generic trial or the default subscription is on trial.

  • Name
    hasPaidActiveSubscription
    Type
    attribute
    Description

    True when the default subscription is active and not on trial.

  • Name
    hasAnyActiveSubscription
    Type
    attribute
    Description

    Trial or paid.

  • Name
    subscriptionStatus
    Type
    attribute
    Description

    One of Super Admin, Active, Free Trial, or Inactive.

  • Name
    trialDaysLeft
    Type
    attribute
    Description

    Days remaining on the current trial, or 0.

  • Name
    addTrial($days)
    Type
    method
    Description

    Creates a trial subscription, or extends the trial of an active one. Minimum 2 days.

  • Name
    cancelTrial()
    Type
    method
    Description

    Ends the trial when a payment method exists, otherwise cancels the subscription immediately.

Super Admin accounts are never gated and never see trial messaging.

Modules

Models

app/Models/

User (Billable, HasRoles, LogsActivity), Product (soft deletes, slug routing, features cast to array), Role, Permission, Activity, Email, Sms.

Filament Resources

app/Filament/Resources/

ProductResource, UserResource, RoleResource, ActivityResource, EmailResource, SmsResource.

Filament Pages

app/Filament/Pages/

BillingInformation (hidden from navigation), HealthCheckResults, ViewLog.

Controllers & Middleware

app/Http/

SubscriptionController (subscribe, billingPortal). Middleware: Subscribed and Customer (403 unless Customer or Super Admin).

Observers

app/Observers/

UserObserver and ProductObserver.

Listeners

app/Listeners/

AddUserFreeTrialOnUserCreation, StripeEventListener, FilamentEmailLogger.

Traits

app/Traits/

HasSubscriptionAttributes and ImplementSubscriptionFunctions.

Jobs & Commands

app/Jobs/ and app/Console/Commands/

SendSmsJob, app:add-permissions-to-new-modules, demo:seed, demo:reset.

Helpers

app/helpers.php

authUserIsSuperAdmin(), authUserIsCustomer(), getModels(), and getFirstMonthlySubscriptionPriceIdFromStripe().

Database

database/

Migrations for Cashier customer, subscription, and subscription item tables, plus products, permissions, activity log, health, and email and SMS logs. Seeders: Permission, Role, RoleHasPermission, User, Product, and Demo.

Public

  • Name
    /
    Type
    Redirect
    Description

    Redirects to the panel dashboard.

  • Name
    /app/login
    Type
    Login
    Description

    Filament login. Excluded from subscription gating.

  • Name
    /app/register
    Type
    Registration
    Description

    Filament registration. Triggers the 30-day trial.

  • Name
    /subscription/buy/{product:slug}
    Type
    Checkout
    Description

    Creates a Stripe Checkout session for the product's first monthly price. Creates a rate-limited guest account for visitors who are not signed in.

  • Name
    /stripe/webhook
    Type
    Webhook
    Description

    Cashier webhook endpoint.

Authenticated

  • Name
    /subscription/billing-portal
    Type
    Billing Portal
    Description

    Requires auth. Redirects to the Stripe billing portal and returns to the dashboard.

  • Name
    /app/billing-information
    Type
    Billing Page
    Description

    Lists products with Buy links. Redirects to the billing portal when the user has a trial or paid subscription. Reachable without a subscription.

  • Name
    /app
    Type
    Dashboard
    Description

    Filament dashboard. Customers need an active subscription or trial.

  • Name
    /app/profile
    Type
    Profile
    Description

    Edit profile details.

Navigation Groups

  • Name
    Shop
    Type
    Group
    Description

    Products (sort 0).

  • Name
    Social
    Type
    Group
    Description

    Users (sort 1).

  • Name
    Settings
    Type
    Group
    Description

    Roles (3), Activity Log (4), View Log (5), Health Check Results.

  • Name
    Communication
    Type
    Group
    Description

    Emails (6) and SMS (7).

Scheduled Tasks

  • Name
    backup:clean / backup:run
    Type
    Weekly
    Description

    Fridays at 03:00 and 03:30.

  • Name
    Health heartbeat
    Type
    Every minute
    Description

    Spatie schedule check heartbeat.

  • Name
    demo:reset
    Type
    Daily
    Description

    03:00, registered only in demo mode on an allowed host.

Was this page helpful?