Stripe: downgrade a user at "period end"

Solution 1:

As @Safinn and @Martin have mentioned, you can cancel the subscription using at_period_end: true to action the cancellation on a specific date.

In order to downgrade to a different plan, the way I get around it is to do the above and then create a free trial of the new plan ending on the same date/time. This way the old plan will be cancelled on the same date that the new plan's trial will end (causing it to be active).

This lets Stripe handle the downgrade entirely their end (which should be more straightforward IMHO), rather than setting up webhooks or tracking dates in your database.

Solution 2:

Yes, using the more recent version of the Stripe API.

(the Stripe tokens you may be using in Temboo's SDK are compatible with Stripe's normal PHP Library)

  • Create a product with multiple pricing plans
  • Subscribe a customer to one of these plan ids
  • When updating a customer to a new plan simply do as follows:

    $sub = $myUser->data['stripe_subscription_id'];
    $subscription = \Stripe\Subscription::retrieve($sub);
    \Stripe\Subscription::update($sub, [    
        'cancel_at_period_end' => false,
        'items' => [
            [
                'id' => $subscription->items->data[0]->id,
                'plan' => $plan,
            ],
        ],
        'prorate' => false,
        'trial_end' => $subscription->current_period_end
    ]);
    $subscription->save();
    

By setting prorate to false, trial_end to $subscription->current_period_end and cancel_at_period_end to false, you effectively tell Stripe:

Do not charge this user until the day that their current billing ends (cancel at period end), do not refund them any money on the plan switch (prorate) and start billing again at the end of their current billing cycle (trial end.)

Which has the effect of changing their billing to the new plan when their old plan ends.