Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

louisph's avatar

Laravel Cashier - Subscription and plans

Hi guys,

I don't understand how to correctly handle subscription and plans. I will tell you what I'm doing actually and what's the problem.

I want to have one subscription my website with multiple plan and periodicity, example:

  • Tier 1
    • Monthly: Free
    • Annual: Free
  • Tier 2:
    • Monthly: $9
    • Annual: $90
  • Tier 3:
    • Monthly: $14
    • Annual: $140
  • Tier 4:
    • Monthly: $17
    • Annual: $170

First question: Should I create a free plan on Stripe (Tier 1) or not ?

On Stripe side I did:

  • Product:
    • Tier 1 (prod_*):
      • Prices (price_*):
        • Monthly: Free
        • Annual: Free
    • Tier 2 (prod_*):
      • Prices (price_*):
        • Monthly: $9
        • Annual: $90
    • Tier 3 (prod_*):
      • Prices (price_*):
        • Monthly: $14
        • Annual: $140
    • Tier 4 (prod_*):
      • Prices (price_*):
        • Monthly: $17
        • Annual: $170

When a user want to subscribe to a plan I do:

return Auth::user()?->newSubscription(
            'default',
            $thePriceId, // ex: price_1O1ahLLts5G6gNbOzlFku5Q2
        )
            ->allowPromotionCodes()
            ->checkout(
                [
                    'success_url' => $myDashboardUrl,
                    'cancel_url'  => $mySubscriptionPlanIndexUrl,
                ]
            );

This work well for the first subscription, but when a user want to upgrade plan, like Tier 2 monthly to Tier 3 monthly, It seems on Stripe to create a new subscription on Stripe, and my user have two subscriptions instead of one, and it seems also that the TIer 2 subscription is not canceled. I don't want my user to play each month for Tier 2 monthly and Tier 3 monthly.

PS: I'm using Stripe Checkout and Stripe Customer Portal.

I think I've misunderstood something :(

Thanks guys for your help

0 likes
7 replies
LaryAI's avatar
Level 58

To handle subscription and plans in Laravel Cashier, you can follow these steps:

  1. Create Products and Prices on Stripe:

    • Create a product for each tier (Tier 1, Tier 2, Tier 3, Tier 4) on Stripe.
    • For each product, create prices for both monthly and annual billing periods.
  2. Set up the Plans in Laravel Cashier:

    • In your Laravel application, define the plans in the config/cashier.php file.
    • Each plan should have a unique identifier, a name, and the corresponding Stripe price ID.
  3. Handle Subscription Creation and Upgrades:

    • When a user wants to subscribe to a plan, use the newSubscription method on the authenticated user.
    • Pass the plan identifier and the corresponding Stripe price ID to the newSubscription method.
    • Use the allowPromotionCodes method to enable promotion codes for the subscription.
    • Use the checkout method to redirect the user to the Stripe Checkout page for payment.
    • Specify the success and cancel URLs for the checkout process.

Here's an example of how the code might look:

use Illuminate\Support\Facades\Auth;

return Auth::user()->newSubscription(
    'default',
    $thePriceId // ex: price_1O1ahLLts5G6gNbOzlFku5Q2
)
    ->allowPromotionCodes()
    ->checkout([
        'success_url' => $myDashboardUrl,
        'cancel_url' => $mySubscriptionPlanIndexUrl,
    ]);

Regarding the issue with upgrading plans, Laravel Cashier should handle plan upgrades automatically. When a user upgrades from Tier 2 monthly to Tier 3 monthly, it should cancel the Tier 2 subscription and create a new Tier 3 subscription. However, it seems that this is not happening in your case.

To troubleshoot this issue, you can check the following:

  • Make sure you have the latest version of Laravel Cashier installed.
  • Verify that the plan identifiers and Stripe price IDs are correctly set up in your Laravel application.
  • Check the Stripe logs and events to see if any errors or unexpected behavior occurred during the upgrade process.

If the issue persists, you can reach out to the Laravel Cashier community or the Laracasts forum for further assistance.

tisuchi's avatar

@louisph Try this:

$user = Auth::user();
if (!$user->subscribed('default')) {
    $user->newSubscription('default', $thePriceId)
         ->allowPromotionCodes()
         ->checkout([
             'success_url' => $myDashboardUrl,
             'cancel_url'  => $mySubscriptionPlanIndexUrl,
         ]);
} else {
    $user->subscription('default')->swap($thePriceId);
}
1 like
louisph's avatar

@tisuchi

if I do:

$user->subscription('default')->swap($thePriceId);

Yes that will swap plan, but the user won't be charged for it :(

1 like
tisuchi's avatar

@louisph Then maybe simply this:

$user = Auth::user();
if ($user->subscribed('default')) {
    $user->subscription('default')->swap($newPlanPriceId);
}

1 like
louisph's avatar

@tisuchi If I do this the user will be charged for it ? I don't get how the user pays for the new plan.

I would to do something like:

$user = Auth::user();
$toCheckout = null;
if (!$user->subscribed('default')) {
	$toCheckout = $user->newSubscription('default', $thePriceId);
} else {
    $toCheckout = $user->subscription('default')->swap($thePriceId);
}

$toCheckout->-allowPromotionCodes()>checkout([
             'success_url' => $myDashboardUrl,
             'cancel_url'  => $mySubscriptionPlanIndexUrl,
         ]);

To you get what I mean ?

1 like
louisph's avatar
$user->subscription('default')->swap($thePriceId)

It swap the plan and change the billing amount for the next time.

$user->subscription('default')->swapAndInvoice($thePriceId)

It swap the plan and charge user immediately.

I wanted to redirect my user to Stripe Checkout page instead of change the plan and charge him directly. But if it's not possible I will to it like you showed to me :)

Should I create free plan (Tier 1) in Stripe and subscribe user to it when he register ?

1 like

Please or to participate in this conversation.