M. Mar
M. Mar

Reputation: 137

How does Laravel handle cancelling stripe subscriptions?

When I call the $user->subscription('main')->cancelNow() method, it does work properly. It sets the ends_at to the current date, and also Stripe is updated, I can see that the subscription was cancelled on Stripe.

However, when I call the $user->subscription('main')->cancel() method, it sets the ends_at to the end of the current period, but it does not update Stripe. The subscription still remains active. So my question is, how will the subscription become cancelled when the current period is over?

Upvotes: 4

Views: 1987

Answers (1)

Steve Chamaillard
Steve Chamaillard

Reputation: 2339

What you said :

when I call the $user->subscription('main')->cancel() method, it sets the ends_at to the end of the current period, but it does not update Stripe

This is false.

Let's first see the cancelNow() code :

/**
 * Cancel the subscription immediately.
 *
 * @return $this
 */
public function cancelNow()
{
    $subscription = $this->asStripeSubscription();

    $subscription->cancel();

    $this->markAsCancelled();

    return $this;
}

/**
 * Mark the subscription as cancelled.
 *
 * @return void
 */
public function markAsCancelled()
{
    $this->fill(['ends_at' => Carbon::now()])->save();
}

This is simply cancelling the subscription on Stripe instantly (because it does not specify a ends_at), and marks it as canceled in your own database.

Now let's see the cancel() code :

/**
 * Cancel the subscription at the end of the billing period.
 *
 * @return $this
 */
public function cancel()
{
    $subscription = $this->asStripeSubscription();

    $subscription->cancel(['at_period_end' => true]);

    // If the user was on trial, we will set the grace period to end when the trial
    // would have ended. Otherwise, we'll retrieve the end of the billing period
    // period and make that the end of the grace period for this current user.
    if ($this->onTrial()) {
        $this->ends_at = $this->trial_ends_at;
    } else {
        $this->ends_at = Carbon::createFromTimestamp(
            $subscription->current_period_end
        );
    }

    $this->save();

    return $this;
}

This is cancelling the subscription on Stripe too, but it passes a ['at_period_end' => true]. That means the subscription will only be canceled on Stripe whenever the period of the subscription was meant to be renewed. But Stripe still got updated ! It then updates your own database also.

So you're fine doing using cancel() and letting Stripe do the rest of your work, you don't need any background jobs or crontabs to handle this !

Upvotes: 7

Related Questions