Laravel Cashier: Subscription Billing
Laravel Cashier: Subscription Billing
Laravel Cashier: Subscription Billing
Tip: Install Cashier
composer require laravel/cashier
php artisan cashier:install
Gotcha: Billable Trait
use Billable;
Add to your User model for subscription management.
Tip: Create Subscription
$user->newSubscription('default', 'premium')->create($paymentMethod);
Gotcha: Webhook Handling
Cashier handles Stripe webhooks automatically. Configure the webhook URL in Stripe dashboard.
Tip: Check Subscription
if ($user->subscribed('default')) {
// User has active subscription
}
Gotcha: Trial Periods
$user->newSubscription('default', 'premium')
->trialDays(10)
->create($paymentMethod);
Tip: Use route:cache Carefully
php artisan route:cache is fast, but it doesn't work with closure-based routes. Every time you cache routes, Laravel serializes them. If you have Route::redirect() or closure callbacks, the cache breaks. Stick to controller-based routes in production.
Tip: Model APP_KEY Rotation
Rotating APP_KEY invalidates all encrypted data — cookies, encrypted DB columns, and password reset tokens. If you must rotate (e.g., after a leak), plan a migration that re-encrypts existing data with the new key.
Gotcha: Local Scope Leaks
Global scopes defined in booted() apply to ALL queries on that model — including relationships. An innocent User::all() in admin panel might exclude soft-deleted users if a global scope is active.
Senior Insight
Subscription billing is the highest-risk integration in most Laravel applications. I've seen everything from double charges to silently failed renewals. Cashier handles the Laravel side well, but the real complexity is in webhook handling — Stripe sends webhooks for almost every event, and missing one (like invoice.payment_failed) means a customer loses access without warning. I recommend idempotent webhook handlers with comprehensive logging.
Source: Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/laravel), Spatie Blog (https://spatie.be/blog)