Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cashier Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/cashier stripe/stripe-php
    

    Publish the migration and config:

    php artisan vendor:publish --provider="Laravel\Cashier\CashierServiceProvider"
    php artisan migrate
    
  2. Configure Stripe: Add your Stripe secret key to .env:

    STRIPE_KEY=your_stripe_secret_key
    STRIPE_ENDPOINT=https://api.stripe.com
    
  3. First Use Case: Attach a Stripe customer to a User model:

    use Laravel\Cashier\Billable;
    
    class User extends Authenticatable implements Billable
    {
        use Billable;
    }
    
  4. Create a Subscription:

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

Key Starting Points

  • Official Docs: Laravel Billing Docs
  • Webhooks: Set up webhooks table and route POST /stripe/webhook to StripeWebhookController.
  • Testing: Use Stripe::fake() for unit tests.

Implementation Patterns

Core Workflows

1. Subscription Management

  • Create/Update:

    // Create a subscription
    $user->newSubscription('main', 'price_123')->create($paymentMethodId);
    
    // Switch plans
    $user->subscription('main')->swap('price_456');
    
    // Cancel (with grace period)
    $user->subscription('main')->cancel();
    
  • Pause/Resume:

    $user->subscription('main')->pause();
    $user->subscription('main')->resume();
    
  • Quantity Adjustments:

    $user->subscription('main')->quantity(5); // For metered billing
    

2. Invoices and Payments

  • Generate Invoice PDF:

    $invoice = $user->invoices()->latest()->first();
    return response()->streamDownload(function () use ($invoice) {
        echo $invoice->download();
    }, 'invoice.pdf');
    
  • Manual Payment:

    $user->invoice()->pay($paymentMethodId);
    

3. Coupons and Trials

  • Apply Coupon:

    $user->newSubscription('main', 'price_123')->withCoupon('SUMMER20')->create($paymentMethodId);
    
  • Trial Period:

    $user->newSubscription('main', 'price_123')->trialDays(7)->create($paymentMethodId);
    

4. Checkout Sessions

  • Stripe Checkout:

    $session = $user->createCheckoutSession([
        'success_url' => route('checkout.success'),
        'cancel_url' => route('checkout.cancel'),
        'line_items' => [
            [
                'price' => 'price_123',
                'quantity' => 1,
            ],
        ],
    ]);
    
  • Embedded Checkout:

    $session = $user->createCheckoutSession([
        'mode' => 'subscription',
        'ui_mode' => 'embedded',
        'client_reference_id' => $user->id,
    ]);
    

5. Webhooks

  • Handle Events:
    use Laravel\Cashier\Http\Controllers\StripeWebhookController;
    
    Route::post('/stripe/webhook', [StripeWebhookController::class, 'handle']);
    
    • Common Events: invoice.paid, customer.subscription.deleted, invoice.payment_failed.
    • Custom Logic: Override handleWebhook in StripeWebhookController.

Integration Tips

1. Model Observers

Track subscription changes:

class UserObserver
{
    public function saved(User $user)
    {
        if ($user->wasRecentlyCreated && $user->subscribed('main')) {
            // Send welcome email
        }
    }
}

2. Middleware for Subscription Checks

public function handle(Request $request, Closure $next)
{
    if ($request->user()->subscribed('main')) {
        return $next($request);
    }
    abort(403, 'Subscription required');
}

3. Dynamic Pricing

Use Stripe Products/Prices API to fetch dynamic prices:

$price = \Stripe\Price::retrieve('price_123');
$user->newSubscription('main', $price)->create($paymentMethodId);

4. Testing

public function test_subscription_creation()
{
    Stripe::fake();

    $user = User::factory()->create();
    $user->newSubscription('main', 'price_123')->create('pm_123');

    Stripe::assertSubscriptionCreated();
}

5. Multi-Currency Support

Configure Stripe for multiple currencies and use:

$user->newSubscription('main', 'price_123')->create($paymentMethodId, [
    'billing_cycle_anchor' => now(),
    'proration_behavior' => 'none',
]);

Gotchas and Tips

Pitfalls

1. Webhook Delays

  • Issue: Stripe webhooks may be delayed or retried.
  • Fix: Implement idempotency in your webhook handlers. Use Stripe::webhook() to verify signatures and handle retries gracefully.

2. Subscription Swaps

  • Issue: Swapping plans may prorate charges unexpectedly.
  • Fix: Use proration_behavior:
    $user->subscription('main')->swap('price_456', [
        'proration_behavior' => 'none', // or 'create_prorations'
    ]);
    

3. Invoice Generation

  • Issue: Invoices may not generate immediately after subscription creation.
  • Fix: Manually trigger an invoice:
    $user->subscription('main')->invoices()->create();
    

4. Payment Method Updates

  • Issue: Updating the default payment method may fail silently.
  • Fix: Check for errors:
    try {
        $user->updateDefaultPaymentMethod('pm_new');
    } catch (\Exception $e) {
        // Handle error (e.g., payment method invalid)
    }
    

5. Taxes and Pricing

  • Issue: Tax calculations may not align with expectations.
  • Fix: Use tax_behavior and ensure Stripe tax settings are configured:
    $user->newSubscription('main', 'price_123')->create($paymentMethodId, [
        'tax_behavior' => 'exclusive', // or 'inclusive'
    ]);
    

6. Testing Edge Cases

  • Issue: Tests may pass locally but fail in production due to Stripe API quirks.
  • Fix: Test with Stripe::fake() and mock specific scenarios:
    Stripe::fake([
        'customer_creation' => 'fail', // Simulate failure
    ]);
    

Debugging Tips

1. Stripe API Logs

Enable Stripe debug mode:

\Stripe\Stripe::setApiKey(config('cashier.key'));
\Stripe\Stripe::setApiVersion('2023-10-16');
\Stripe\Stripe::setLogLevel(\Stripe\Logger::DEBUG);

2. Webhook Testing

Use Stripe CLI to test webhooks locally:

stripe listen --forward-to localhost:8000/stripe/webhook

3. Common Errors

  • InvalidRequestError: Validate all required fields (e.g., payment_method, price).
  • AuthenticationError: Ensure STRIPE_KEY is correct and not expired.
  • ResourceMissing: Handle cases where subscriptions/invoices are deleted externally.

4. Database Sync

If Stripe and your database are out of sync:

php artisan cashier:sync

Extension Points

1. Custom Webhook Logic

Extend StripeWebhookController:

class CustomStripeWebhookController extends StripeWebhookController
{
    protected function handleWebhookEvent($event)
    {
        if ($event->type === 'customer.subscription.deleted') {
            // Custom logic (e.g., send cancellation email)
        }
        parent::handleWebhookEvent($event);
    }
}

2. Custom Invoice Views

Override invoice PDF generation:

// app/Providers/AppServiceProvider.php
public function boot()
{
    Invoice::macro('download', function () {
        $pdf = PDF::loadView('custom.invoice', ['invoice' => $this]);
        return $pdf->output();
    });
}

3. Custom Subscription Logic

Add methods to your User model:

public function isOnFree
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle