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
apppanel at/appwith login, registration, and profile. ASubscribedmiddleware is part of the panel's auth middleware. - Cashier Billing —
Cashier::useCustomerModel(User::class)and theBillabletrait onUser. Subscriptions use the namedefault. - Observers —
UserObserverassigns the Customer role on creation.ProductObservermirrors products and prices to Stripe. - Event Listeners —
AddUserFreeTrialOnUserCreationreacts to Filament'sRegisteredevent, and the queuedStripeEventListenerreacts to Cashier'sWebhookReceivedevent. - Permission-Driven Authorization — Policies map to
<Model>.<ability>permissions, with aGate::beforebypass 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, orInactive.
- 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.
Navigation and Routes
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.