Laravel Cashier (Stripe) - Subscription billing and payment processing
Comprehensive assistance with Laravel Cashier (Stripe) development for subscription billing, payment processing, and Stripe integration in Laravel applications.
This skill should be triggered when:
# Install Cashier
composer require laravel/cashier
# Publish migrations and migrate
php artisan vendor:publish --tag="cashier-migrations"
php artisan migrate
# Publish config (optional)
php artisan vendor:publish --tag="cashier-config"
use Laravel\Cashier\Billable;
class User extends Authenticatable
{
use Billable;
}
// Basic subscription with trial and checkout
$user->newSubscription('default', 'price_monthly')
->trialDays(5)
->allowPromotionCodes()
->checkout([
'success_url' => route('checkout.success'),
'cancel_url' => route('checkout.cancel'),
]);
// Check if user has active subscription
if ($user->subscribed('default')) {
// User is subscribed to "default" plan
}
// Check specific product subscription
if ($user->subscribedToProduct('prod_premium', 'default')) {
// User is subscribed to premium product
}
// Check trial status
if ($user->subscription('default')->onTrial()) {
// User is still in trial period
}
// Store payment method (in view with Stripe.js)
$intent = $user->createSetupIntent();
// Retrieve payment methods
$paymentMethods = $user->paymentMethods();
$defaultMethod = $user->defaultPaymentMethod();
// Add and update payment methods
$user->addPaymentMethod($paymentMethodId);
$user->updateDefaultPaymentMethod($paymentMethodId);
// Swap to different price/plan
$user->subscription('default')->swap('price_yearly');
// Swap and skip trial
$user->subscription('default')->skipTrial()->swap('price_yearly');
// One-time charge
$user->charge(1000, $paymentMethodId, [
'description' => 'One-time charge',
]);
// Create invoice for service
$user->invoiceFor('Premium Support', 5000, [
'description' => '3 months of premium support',
]);
// Refund a charge
$user->refund($chargeId);
// Cancel immediately
$user->subscription('default')->cancel();
// Cancel at end of billing period
$user->subscription('default')->cancelAtEndOfBillingPeriod();
// Resume canceled subscription
if ($user->subscription('default')->onGracePeriod()) {
$user->subscription('default')->resume();
}
// Get all invoices
$invoices = $user->invoices();
// Get upcoming invoice
$upcomingInvoice = $user->upcomingInvoice('default');
// Download invoice PDF
return $user->invoices()->first()->download();
// Redirect to Stripe billing portal
Route::get('/billing', function (Request $request) {
return $request->user()
->redirectToBillingPortal(route('dashboard'));
})->middleware(['auth']);
// Create/get Stripe customer
$stripeCustomer = $user->createOrGetStripeCustomer();
// Update customer details
$user->updateStripeCustomer([
'name' => 'Updated Name',
'email' => '[email protected]',
]);
// Manage tax IDs
$taxId = $user->createTaxId('eu_vat', 'BE0123456789');
$user->deleteTaxId('txi_belgium');
The Billable trait adds subscription and payment functionality to your Eloquent models (typically User). It provides methods for creating subscriptions, processing charges, managing payment methods, and accessing invoices.
Cashier manages recurring billing through subscriptions. Each subscription has:
Stripe payment methods represent stored payment credentials (cards, bank accounts). Cashier provides helpers to:
Stripe sends webhook events for subscription changes, payment failures, invoice updates, etc. Cashier automatically handles common webhooks, but you can extend functionality by listening to specific events.
Stripe Checkout provides a pre-built payment page. Cashier simplifies creating checkout sessions for subscriptions and one-time products, handling the complete payment flow with minimal code.
Cashier provides access to Stripe invoices for both subscriptions and one-time charges. You can retrieve, preview, and download invoices as PDFs.
This skill includes comprehensive documentation in references/:
Use view to read the reference file when you need detailed information about specific features.
Start by:
Billable trait to your User modelnewSubscription()Basic workflow:
// 1. Configure model
use Laravel\Cashier\Billable;
class User extends Authenticatable { use Billable; }
// 2. Create subscription
$user->newSubscription('default', 'price_monthly')->create();
// 3. Check status
if ($user->subscribed('default')) {
// Grant access
}
Focus on:
Explore:
references/other.md for complete implementation detailsRequired environment variables in .env:
STRIPE_KEY=pk_test_your_stripe_publishable_key
STRIPE_SECRET=sk_test_your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_signing_secret
CASHIER_CURRENCY=usd
Important: Use test mode keys (pk_test_, sk_test_) during development and switch to live keys (pk_live_, sk_live_) for production.
// 1. Create checkout session
public function subscribe(Request $request)
{
return $request->user()
->newSubscription('default', 'price_monthly')
->trialDays(14)
->allowPromotionCodes()
->checkout([
'success_url' => route('checkout.success') . '?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => route('checkout.cancel'),
]);
}
// 2. Handle success
public function success(Request $request)
{
$sessionId = $request->get('session_id');
if ($request->user()->subscribed('default')) {
return redirect()->route('dashboard')
->with('success', 'Subscription activated!');
}
}
// Upgrade to annual plan with prorated credit
public function upgrade(Request $request)
{
$subscription = $request->user()->subscription('default');
if ($subscription->active()) {
$subscription->swap('price_yearly');
return back()->with('success', 'Upgraded to annual plan!');
}
}
// Controller: Generate setup intent
public function paymentMethods(Request $request)
{
return view('billing.payment-methods', [
'intent' => $request->user()->createSetupIntent(),
'paymentMethods' => $request->user()->paymentMethods(),
]);
}
// View: Stripe.js integration (Blade)
<form id="payment-form" method="POST" action="{{ route('payment-method.add') }}">
@csrf
<div id="card-element"></div>
<button type="submit">Add Payment Method</button>
</form>
// Controller: Store payment method
public function addPaymentMethod(Request $request)
{
$request->user()->addPaymentMethod($request->payment_method);
return back()->with('success', 'Payment method added!');
}
Use Stripe test card numbers for development:
4242 4242 4242 42424000 0000 0000 00024000 0025 0000 3155Always use test mode API keys during development and testing.
This skill is based on Laravel Cashier for Laravel 12.x. For the latest information, refer to the official documentation at https://laravel.com/docs/billing.