Does Laravel Work With Stripe?
Laravel and Stripe integrate seamlessly through the official Cashier package, making payment processing straightforward for PHP developers.
Quick Facts
How Laravel Works With Stripe
Laravel Cashier is the official package that abstracts Stripe's API into Laravel conventions, handling subscriptions, one-time payments, invoicing, and webhook management. The integration leverages Laravel's service container and eloquent models, allowing you to attach billing functionality directly to your User model with minimal boilerplate. Developers define subscription plans in Stripe's dashboard, then manage them through Laravel methods like `$user->newSubscription('default', 'price_xxx')->create($paymentMethod)`. Webhook handling is particularly elegant—Cashier automatically registers a route and validates Stripe signatures, letting you define event handlers as simple class methods. The developer experience mirrors Laravel's philosophy: you work with PHP objects rather than raw HTTP calls, migrations handle database schema for subscription tracking, and queue jobs handle async operations like invoice processing.
Best Use Cases
Quick Setup
composer require laravel/cashier-stripe<?php
// routes/web.php
Route::post('/subscribe', function (Request $request) {
$user = Auth::user();
$paymentMethod = $request->input('payment_method');
$user->addPaymentMethod($paymentMethod);
$user->newSubscription('default', 'price_monthly')
->create($paymentMethod);
return redirect('/dashboard')->with('success', 'Subscribed!');
});
// In your User model
use Laravel\Cashier\Billable;
class User extends Model
{
use Billable;
}
// Check subscription status
if ($user->subscribed('default')) {
// User has active subscription
}
// Cancel subscription
$user->subscription('default')->cancel();Known Issues & Gotchas
Webhook signature verification fails in development with incorrect STRIPE_WEBHOOK_SECRET
Fix: Use `stripe listen --forward-to localhost:8000/stripe/webhook` to tunnel Stripe events locally and get the correct signing secret from the output
Stripe price IDs don't sync automatically when you change plans in Stripe dashboard
Fix: Update your config/cashier.php or .env file with new price IDs; consider using Stripe's API to fetch active prices programmatically
Payment method failures silently fail if webhook processing is delayed or skipped
Fix: Ensure your queue worker is running and implement retry logic in webhook handlers; test with `php artisan tinker` to verify subscriptions process correctly
Cashier's subscription model assumes single currency per user, complicating multi-currency stores
Fix: Store currency in user profile and manually validate it matches Stripe payment intent currency, or use Stripe's API directly for complex scenarios
Alternatives
- •Symfony + Stripe API: Lower-level control but more boilerplate for subscription logic
- •Django + django-stripe or Paddle: Python alternative with similar abstraction; Paddle offers simpler revenue share model
- •Next.js/Node.js + Stripe SDK with custom backend: More control and flexibility but requires building subscription infrastructure
Resources
Related Compatibility Guides
Explore more compatibility guides