A FIELD GUIDE TO LARAVEL · VOLUME II · THE ECOSYSTEM
ENTRY II.9 · BILLING
Spark
Spark · Product · first recorded 14 April 2016, the Spark installer v1.0.0 on Packagist
SaaS billing scaffolding on top of Cashier. A paid package from a private Composer repository that gives a Laravel app a customer billing portal: plans, swaps, payment methods and invoices, against Stripe or Paddle.
Specification
Kind Package, paid licence, private Composer repo. Built on Cashier
Interface A billing portal at /billing/{billable}; plans in config/spark.php
Client Stripe, or Paddle as merchant of record
Installed by spark.laravel.com repo · laravel/spark-stripe · spark:install · migrate
Voice spark:install · cashier:webhook (Stripe)
Scales by One billable type per app; per-seat plans count seats in a closure
Range Cloud: yes. Needs a reachable webhook URL
Forge, VPS: yes, the same as Cloud
Vapor: yes. Nothing resident; a webhook is a request
Neighbours
Cashier is the library underneath: subscriptions, trials and invoices on the model, with redirects to Stripe Checkout and Stripe's billing portal. Spark adds a billing portal inside your app and the plan configuration, for Stripe or Paddle. If a pay button is all you need, Cashier alone will do.
Field marks
config/spark.php
Spark\Billable on the User model
STRIPE_WEBHOOK_SECRET
App\Providers\SparkServiceProvider
Fig. II.9.1 · the billing portal, exploded
Parts
1 Billable model. App\Models\User with Spark\Billable, integer id, and for Stripe trial_ends_at cast to datetime.
2 Plans, in config/spark.php: name, monthly and yearly price ids, features, options. archived keeps old subscribers.
3 Portal. Served at /billing. Subscribe, swap plan, change payment method, download invoices. Spark's views, not yours.
4 Cashier. Spark does no billing of its own. Cashier Stripe or Cashier Paddle makes the calls and owns the subscriptions.
5 Webhook. /spark/webhook for Stripe, made by cashier:webhook; Paddle uses /paddle/webhook. Needed in local dev too.
6 Provider. Stripe, or Paddle as merchant of record handling VAT. One licence covers either; custom providers are not offered.
Hidden joinery
trial_days sits at the billable level by default; set per plan it demands a payment method up front, and Stripe Checkout wants at least two days. checkPlanEligibility in SparkServiceProvider can refuse a swap with a ValidationException. The Composer repository needs an auth.json you never commit.
Every line checked on 2026-10-08 against spark.laravel.com/docs, Packagist and Stripe's portal docs.
TITLE
Spark · the billing portal
SOURCES
spark.laravel.com/docs/introduction · spark.laravel.com/docs/installation · spark.laravel.com/docs/kb/faq · spark.laravel.com/docs/spark-stripe/configuration · spark.laravel.com/docs/spark-stripe/plans · spark.laravel.com/docs/spark-paddle/configuration · packagist.org/packages/laravel/spark-installer · docs.stripe.com/customer-management · laravel.com/docs/13.x/billing
STATUS
Verified · 2026-10-08
SHEET
II.9 of 48
REV
A · 2026-10-08
DRAWN
BS
FINISH
All faces, including the back