Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Cashier Billing Provider Laravel Package

maartenpaauw/filament-cashier-billing-provider

Integrate Laravel Cashier Stripe subscriptions into Filament multi-tenant panels. Configure plans in cashier.php and make your Billable model the tenant model; supports recurring subscriptions, trials, promo codes, tax IDs, and metered prices.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a thin, opinionated adapter — not a billing system. It slots into an existing Filament panel as a tenant billing provider, wiring Filament's multi-tenancy lifecycle to Laravel Cashier's Stripe implementation. The critical architectural constraint is stated plainly in the README: your Billable model must be the same as your Filament tenant model. That means one Stripe customer per tenant, subscriptions owned at the tenant level, and no per-user billing inside a tenant. For SaaS products where the paying entity is the workspace/organisation, this is a clean, low-friction fit. For products that bill individual users but group them into teams, or that need seat-level proration, this is a hard architectural mismatch and the package should be rejected or forked.

Scope is deliberately narrow: recurring subscriptions only (explicitly flagged as a limitation in the README), Stripe only (no Paddle), and plan definition via a plans array in cashier.php. The package is essentially three things: a BillingProvider registered on the panel, an optional requiresTenantSubscription() gate backed by RedirectIfUserNotSubscribed middleware, and plan-config parsing that maps plan keys to Stripe product_id/price_id pairs with optional trial, promotion-code, tax-ID, and metered-price flags. Feature breadth is modest but the surface area you must support is correspondingly small.

Integration feasibility. High for greenfield, moderate for brownfield. The install is a single composer require plus two lines in the panel provider. Config uses ENV() calls inside cashier.php, which is valid but makes php artisan config:cache a required, ordered deployment step — a stale or missing cache silently yields null product/price IDs. The v3.x line is a layered rewrite (v3.0.0 "Use a layered architecture") that dropped Filament 3 support, so the package now tracks Filament 4 and 5. v3.1.0 additionally requires Laravel 13, PHP 8.5, and Cashier 16, and removed Laravel 11. That aggressive support matrix is the single biggest feasibility gate: you must confirm your Laravel, PHP, Filament, and Cashier versions all land inside one supported package major before committing.

Technical risk. Rate this medium.

  • Maintainer concentration. Effectively a single-author package (maartenpaauw), 104 stars, zero dependents. There is no downstream production base to absorb breakage on your behalf, and no evidence of use at scale.
  • Breaking-change cadence tied to framework majors. The 1.x → 2.x jump changed subscription gating from subscription-name to product-ID checking — a silent behavioural change that can invalidate live subscriptions if product IDs are ever rotated. 2.x → 3.x dropped Filament 3 entirely. Expect a package major bump for every Filament major, and treat Filament upgrades as coupled releases.
  • Blast radius. Billing gates sit on the tenant entry path. A middleware regression (v3.0.1 shipped a fix to allow regular Response instances) means auth/billing gate bugs surface as lockouts or, worse, as free access.
  • No webhook layer documented. The package consumes Cashier's existing Stripe webhook plumbing; if that plumbing is not already hardened in your app, tenant subscription state will drift from Stripe.

Key questions.

  1. Is our paying entity genuinely the tenant, now and for the next 24 months? If per-seat or per-user billing is on the roadmap, this package is a dead end.
  2. Do our Laravel/PHP/Filament/Cashier versions all fall inside a single supported package major today?
  3. Do we need one-time charges, invoicing UI, dunning management, or plan-switching flows? None are evidenced in the docs — verify against source before committing.
  4. What is our tolerance for a single-maintainer dependency on the revenue-critical path? If low, do we vendor/fork the ~small surface area?
  5. Do we already run Cashier webhooks reliably, with idempotency and retry handling?

Integration Approach

Stack fit. The package presumes: a Filament panel with tenant() configured, a Tenant model implementing Billable with the standard Cashier columns (stripe_id, pm_type, pm_last_four, trial_ends_at), a configured Stripe account with products and recurring prices already created, and Cashier installed with webhooks live. If the tenant model is a Team/Workspace and Cashier is currently bolted onto User, expect real migration work — not a package install.

Migration path. Two distinct paths:

  • Greenfield billing. Model the tenant as Billable from day one, add Cashier columns to the tenants table, publish cashier.php with the plans map, register BillingProvider in the panel and decide whether requiresTenantSubscription() applies. Low effort, roughly 2–5 engineering days including Stripe test-mode validation.
  • Brownfield (user-level Cashier already live). Materially harder. You must create tenant-level Stripe customers, migrate or re-create subscriptions, backfill stripe_id on tenants, reconcile existing invoices and trial state, and preserve access continuity during cutover. Budget 2–4 weeks with a Stripe-side runbook and a dual-read period. Do not attempt this without confirming how in-flight trials and past-due states should map.

Compatibility. Pin explicitly. Filament 3 requires package 1.x/2.x (which in turn caps Laravel 12). Filament 4/5 requires package 3.x (Laravel 12/13, Cashier 15/16). Do not float the constraint — a ^3.0 that silently absorbs a future 3.2.0 dropping Laravel 13 is an avoidable outage. Lock the package version in composer.json and record the coupling in your upgrade documentation.

Sequencing. (1) Feasibility spike: one developer, 1–2 days, proves tenant-as-Billable and a Stripe test-mode subscription end-to-end. (2) Schema and config: Cashier columns on tenants, plans map with product/price IDs sourced from secrets, config-cache step added to the deploy pipeline. (3) Panel wiring: tenantBillingProvider() first without the subscription gate — verify the billing UI renders before gating anything. (4) Gate enablement behind a feature flag per panel. (5) Webhook verification and subscription-state reconciliation. (6) Staging soak with Stripe test clocks for trial expiry and dunning. (7) Production rollout to a single cohort, then general availability.

Operational Impact

Maintenance. Low day-to-day, spiky at framework upgrades. The dependency is small and idiomatic; there is no bespoke runtime to operate. The recurring cost is the coupling tax: every Filament, Laravel, Cashier, or PHP major likely forces a package major bump, and the upgrade notes are terse changelog entries rather than migration guides. Allocate a recurring 1–2 days per framework upgrade cycle and treat the package as part of your Filament upgrade epic, not as an independent line item. The repo does carry a test workflow and a changelog, which materially lowers the cost of validating a bump.

Support. Community-only. GitHub issues, no SLA, no commercial backing, no documentation site beyond the README. The README is accurate but assumes Cashier fluency — it will not teach your team Stripe billing. Plan for internal ownership: designate one engineer as the billing subject-matter expert, and expect that person to read package source when edge cases arise. If the revenue path cannot tolerate best-effort upstream support, fork the package into your monorepo; the surface area is small enough that this is a credible option rather than an overreaction.

Scaling. Billing volume is bounded by Stripe, not by this package — no scaling concern on the payment side. The scaling risk is on the read path: requiresTenantSubscription() gates tenant access, which means a subscription check runs on tenant-scoped requests. Confirm how that check resolves state (cached column vs. live Stripe/DB lookup) and cache if necessary. Plan configuration is a static PHP array, so adding or retiring plans is a code change plus a deploy — acceptable, but it means pricing changes are release events, not admin actions. If marketing needs self-service plan changes, that is custom work on top.

Failure modes. Rank by severity:

  1. Total tenant lockout. Misconfigured plans, wrong product ID, or an over-eager gate blocks every tenant from the panel. Mitigation: feature-flag the gate; ship an artisan command or bypass for support staff.
  2. Silent free access. The inverse — gate not registered, or plan config resolving to null — grants service without payment. Mitigation: assertion test that a non-subscribed tenant is redirected.
  3. Webhook drift. Subscription cancelled in Stripe but tenant retains access (or vice versa). Cashier's webhook handling is the dependency; monitor for webhook delivery failures and reconcile periodically.
  4. Config cache mismatch. ENV() values baked at config:cache time; a deploy that caches before secrets are injected yields null price IDs. Enforce ordering in the pipeline.
  5. Product-ID rotation. Since gating keys off product ID, rotating Stripe products silently invalidates existing subscribers. Treat Stripe product IDs as immutable identifiers.
  6. Upstream abandonment. Single maintainer, zero dependents. Mitigation: fork-on-abandonment plan and a documented exit (the layered v3 architecture makes extraction cleaner than earlier versions).

Ramp-up. Shallow for a Laravel developer familiar with Filament — an afternoon to first working test-mode subscription, roughly a week to production confidence. The real ramp is domain ramp: Stripe products, prices, trials, tax IDs, promotion codes, metered pricing, and webhook semantics. That knowledge lives in Stripe's docs and Cashier's source, not in this package. Budget accordingly and do not mistake the package's simplicity for a simplification of the billing problem.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style