DEV Community

Aleson França
Aleson França

Posted on

Laravel Cashier: Manage Subscriptions with Stripe or Paddle the Easy Way

If you're building a SaaS with Laravel, sooner or later you’ll need to handle recurring payments. Laravel offers a robust solution for that: Cashier. In this post, I’ll show you how to integrate it with Stripe or Paddle and how to manage subscriptions, plan changes, and cancellations easily.


Using Laravel Cashier with stripe

Install package

composer require laravel/cashier
php artisan vendor:publish --tag="cashier-migrations"
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

In your User model:

use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;
}
Enter fullscreen mode Exit fullscreen mode

In your .env file:

STRIPE_KEY=pk_test_xxx
STRIPE_SECRET=sk_test_xxx
Enter fullscreen mode Exit fullscreen mode

Create a Subscription

$user = User::find(1);

$user->newSubscription('default', 'premium-plan-id')
     ->create($paymentMethodId);
Enter fullscreen mode Exit fullscreen mode

You can get the paymentMethodId using Stripe Elements.


Canceling and Managing a Subscription

$user->subscription('default')->cancel();

$user->subscription('default')->cancelNow();
Enter fullscreen mode Exit fullscreen mode

Switch Plans

$user->subscription('default')->swap('new-plan-id');
Enter fullscreen mode Exit fullscreen mode

One Time Charge (No subscription)

$user->charge(2500, $paymentMethodId); // $25.00
Enter fullscreen mode Exit fullscreen mode

Using Laravel Cashier with Paddle

To use Paddle, you need a separate package:

Installation

composer require laravel/cashier-paddle
php artisan vendor:publish --tag="cashier-paddle-migrations"
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

In your .env file:

PADDLE_VENDOR_ID=your_vendor_id
PADDLE_VENDOR_AUTH_CODE=your_auth_code
Enter fullscreen mode Exit fullscreen mode

Creating a Subscription

$user = User::find(1);

return $user->newSubscription('default', 'plan-id')
            ->checkout([
                'success_url' => route('dashboard'),
                'cancel_url' => route('checkout.cancelled'),
            ]);
Enter fullscreen mode Exit fullscreen mode

With Paddle, the checkout is hosted on Paddle's platform.


Canceling a Subscription

$user->subscription('default')->cancel();
Enter fullscreen mode Exit fullscreen mode

Handling Webhooks

Both Stripe and Paddle send webhook events when something happens, such as:

  • Payment failed

  • Card expired

  • Subscription canceled

  • Subscription created

You can set up webhook routes in Laravel like this:

Route::post('/webhook/stripe', [WebhookController::class, 'handleStripe']);
Route::post('/webhook/paddle', [WebhookController::class, 'handlePaddle']);
Enter fullscreen mode Exit fullscreen mode

Tips

  • Use jobs to handle webhook events asynchronously

  • Use middleware to block access to premium features for inactive users

  • Create artisan commands to check for expired subscriptions


Conclusion

Laravel Cashier removes most of the complexity when dealing with recurring payments and subscriptions. With native support for both Stripe and Paddle, you can choose the provider that fits your business best.

If you're building a SaaS product with Laravel, this is one of the most complete and production-ready solutions available today.

Top comments (0)