laravel/cashier
Laravel Cashier (Stripe) adds a fluent, expressive API for subscription billing in Laravel. Manage subscriptions, coupons, plan swaps, quantities, cancellation grace periods, and invoice PDF generation—without writing boilerplate billing code.
Laravel Cashier (Stripe integration) is a highly aligned solution for any Laravel-based SaaS or subscription-driven application requiring Stripe billing. Its event-driven architecture (via webhooks) and model integration (e.g., User model traits) make it a seamless fit for:
The package abstracts Stripe’s complexity behind Laravel’s eloquent models, reducing boilerplate while maintaining type safety (PHP 8.5+ support) and Stripe API parity.
VerifyWebhookSignature middleware included).fake() for Stripe mocking).Key dependencies:
| Risk Area | Assessment | Mitigation Strategy |
|---|---|---|
| Stripe API Changes | Stripe’s API evolves rapidly (e.g., v16 SDK breaking changes). | Monitor Stripe API changelog and Cashier’s releases. |
| Webhook Reliability | Critical for syncing subscriptions/payments. | Implement idempotency, retries, and dead-letter queues (e.g., Laravel Horizon). |
| Tax/Compliance | Regional tax rules (e.g., VAT, GST) require careful configuration. | Use Stripe’s tax_rates and validate with local experts. |
| Downtime Impact | Stripe outages or API throttling can disrupt billing. | Cache subscription states locally; use Stripe’s backup payments. |
| Migration Complexity | Upgrading between major versions (e.g., v15→v16) may require schema changes. | Test upgrades in staging; use Laravel’s migrate:fresh for rollback safety. |
Business Model:
prices API handles this, but tax rules must be configured per region.Payment Flows:
Invoice model covers this.Compliance:
log() middleware.Scaling:
Customization:
dompdf; extend via Invoice::render() or replace the driver.Monitoring:
failed_jobs table (for webhook retries).Cashier is optimized for Laravel’s stack and integrates natively with:
HasPaymentMethods and HasSubscriptions traits to User or custom models.HandleWebhook).Non-Laravel Considerations:
illuminate/support and illuminate/database are installed.| Scenario | Steps |
|---|---|
| New Laravel Project | 1. Install via Composer: composer require laravel/cashier. 2. Publish config: php artisan vendor:publish --provider="Laravel\Cashier\CashierServiceProvider". 3. Set up Stripe keys in .env. 4. Add traits to User model. |
| Existing Stripe Integration | 1. Audit custom Stripe logic (e.g., subscription creation). 2. Replace with Cashier methods (e.g., createSubscription()). 3. Migrate webhooks to Cashier’s HandleWebhook. 4. Test in staging. |
| Legacy Billing System | 1. Backfill Stripe customers/subscriptions via API. 2. Sync historical data (e.g., invoices) to Laravel. 3. Gradually migrate users to Cashier. |
| Multi-Tenant SaaS | 1. Extend User model to include tenant_id. 2. Use Stripe’s customer metadata for tenant tracking. 3. Customize webhooks to route events per tenant. |
| Component | Compatibility Notes |
|---|---|
| Laravel Versions | v16.x: Laravel 13.x; v15.x: Laravel 12.x. Avoid mixing major versions (e.g., v15 Cashier on Laravel 14). |
| PHP Versions | v16.x: PHP 8.5+; v15.x: PHP 8.1+. Use php -v to check compatibility. |
| Stripe SDK | v16.x: Stripe PHP SDK v16+; v15.x: SDK v15+. Pin versions in composer.json to avoid surprises. |
| Databases | All supported, but SQLite may need adjustments for migrations (e.g., Schema::disableForeignKeyConstraints()). |
| Payment Methods | Supports cards, SEPA, iDEAL, etc. Custom methods require Stripe’s payment links or direct API calls. |
| Webhooks | Requires HTTPS endpoint. Use Laravel’s VerifyWebhookSignature middleware. For high traffic, consider a load-balanced setup with retries. |
Phase 1: Setup & Configuration
stripe listen --forward-to localhost:8000/stripe/webhook).Phase 2: Core Subscription Flows
createSubscription(), cancelSubscription(), and swap() methods.Phase 3: Payment & Billing
Invoice generation and PDFs.invoice_settings.default_payment_method.HandleWebhook for real-time events (e.g., invoice.paid).**Phase 4:
How can I help you explore Laravel packages today?