Oleksii Siniaiev
RU UK ES EN
Post page navigation

Blog article · Articles

Understanding Laravel Subscriptions with Cashier and Stripe: A Comprehensive Guide

A practical guide to managing Laravel subscriptions with Cashier and Stripe, including setup, model configuration, webhook thinking, and clean billing architecture.

Published: June 21, 2023 Updated: March 21, 2026 2 min read
Send a message See selected work

Laravel Cashier gives Laravel teams a clean way to work with Stripe subscriptions without rebuilding recurring billing from scratch. It wraps common billing flows behind expressive APIs so you can focus on product logic instead of low-level payment plumbing.

Why Cashier is useful in real products

Recurring billing looks simple until you need to support plan changes, trials, invoices, failed payments, cancellations, and webhooks. Cashier reduces that complexity by giving you a standard integration path for Stripe inside a Laravel application.

  • It keeps subscription logic close to your Laravel models.
  • It reduces the amount of custom billing code you need to maintain.
  • It works well for SaaS applications that need predictable upgrade and downgrade flows.

Install and prepare the project

Start by adding Cashier to the project and publishing the database tables required for subscriptions.

composer require laravel/cashier
php artisan cashier:table
php artisan migrate

Then add your Stripe credentials to the application environment.

STRIPE_KEY=your-stripe-key
STRIPE_SECRET=your-stripe-secret

Make the billable model subscription-aware

Cashier expects your billable model, usually User, to use the Billable trait.

use LaravelCashierBillable;

class User extends Authenticatable
{
    use Billable;
}

Once that is in place, Laravel can create and manage subscriptions directly from the model.

Create a subscription

A simple subscription flow can be created with a single expressive call.

$user = User::find(1);

$user
    ->newSubscription('main', 'monthly-premium')
    ->create($paymentMethodId);

That covers the happy path, but production systems should also plan for webhooks, retries, payment failures, and billing status changes. Subscription code becomes much easier to support when those events are modeled explicitly instead of being hidden inside controllers.

Operational concerns teams often miss

  • Use webhooks to keep Stripe and your application state synchronized.
  • Track subscription status clearly in the UI so users understand trials, grace periods, and cancellations.
  • Separate billing rules from presentation logic so pricing changes do not spread across the codebase.
  • Write tests around upgrades, downgrades, and failed payment scenarios.

Cashier works best with clean architecture

Billing is easier to evolve when your code depends on stable boundaries. The architectural approach described in this article on Dependency Injection and Dependency Inversion in Laravel also applies here: keep Stripe-specific behavior behind focused services and contracts where it makes sense.

Key takeaway

Laravel Cashier and Stripe are a strong combination for subscription-based SaaS products. They give you a reliable billing foundation, but long-term success still depends on clean application structure, solid webhook handling, and clear product rules around plans and access.

Share this article

LinkedIn X Email

Explore more

Flowchart showing the correct incident response steps when secrets are leaked in Git

April 11, 2026

When a Leaked Secret in Git Turned Into a Four-Year History Rewrite

A real-world story of leaked API keys, a panicked git filter-branch that rewrote 4…

March 24, 2026

Debugging a Production Site After AI Deployment — What the Browser Sees vs. What You Shipped

After deploying a portfolio site built with AI, I found broken mobile menus, bullet-point…

March 21, 2026

How I Built and Deployed a Custom WordPress Theme with AI Agents in Under 6 Hours

A complete walkthrough of building a zero-JavaScript, multilingual WordPress theme on Bedrock architecture, deployed…