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

sAnsic's avatar
Level 1

Change of Stripe subscription with propation

Stack: Laravel + Cachier.

I will try to explain the expected result using the example of Laracast subscription (https://laracasts.com/?modal=join-modal):

  1. I subscribed to the annual plan “Individual Plan” for $104
  2. Exactly six months have passed and I want to change my current annual plan from the “Individual Plan” to the “Forever Plan” with a price of $279 per year. I want to change it immediately (without waiting for the end of the current period).

This is the easiest and most obvious option:

$user->subscription()->anchorBillingCycleOn()->swapAndInvoice(NEW_PRICE_ID)

But this is not good for UX. I can create a new subscription with a checkout. After receiving the payment, I can cancel the old subscription and refund the user. But this is also not good for UX (at least because the user has to wait for a refund instead of paying the difference).

So, after clicking the “Select plan” button, I want to get to the checkout page (portal or other built-in Stripe functionality), where the amount to be paid will be reduced by the unused amount of the current subscription ($279 - $104 / 12 * 6). It should be possible to enter a promo code. Then the user will only need to enter the promo code and click the button (Change/Update/Confirm).

How can this be done?

0 likes
4 replies
Nakov's avatar

Let me share my thoughts. So how often will this happen? Is it worth the hassle? Or you just used this as an example but in your case it will be more often?

So those are couple of questions that I will ask myself before doing anything, but here are some points that I will take.

  1. So since the user is logged in and they go their dashboard, for the "Forever" plan you can already have it calculated, and if they decide to click on that button, you will have the "new" price calculated in the back-end.

  2. If they proceed with the steps, and they agree with the price, you can create a coupon using the API: https://docs.stripe.com/billing/subscriptions/coupons?dashboard-or-api=api#coupons

  3. Send that coupon code on their email, and on the dashboard you just show that they should receive an email with coupon that they can use for the upgrade.

  4. The email should also have a link to the payment part on your page, and pre-fill the coupon as well for them.

  • Make sure that you validate the coupon code that you issued with the Stripe customer ID of the customer, because a coupon is not associated with a customer as far as I can see in the API, so you can do that on your side.
sAnsic's avatar
Level 1

Thank you, @Nakov, for your answer.

All of this can be done on dashboard, but I want to outsource it to Stripe. Taxes, fees, multicurrency, payment services, ... I just want to say - Stripe, here is the price (plan) ID and user ID, transfer him to this price and charge the appropriate amount (if possible, charge the difference between the price of the plan and the unused amount of the current plan price). Next, the user should see the familiar Stripe UI, where the user will see the price of the plan, the unused amount of the current plan, the field for entering a promo code, payment method, etc.

By the way, I tried to do this through the Customer Portal, but I didn't find a way to customize the configuration to explicitly indicate which plan (price) the subscription should change to (so that there is no “Update subscription” button)

sAnsic's avatar
Level 1

@Nakov Yes, I've looked at it. But I don't understand what you mean by that.

In the simplest version, I expect the following algorithm:

  1. Unused amount - $52 (proration)
  2. The subscription price is $279
  3. 20% off coupon - $55.8
  4. The amount to be charged from the user = $279 - $52 - $55.8 = $171.2

I can easily do this through the subscription API ($user->subscription()->anchorBillingCycleOn()->withCoupon(COUPON_ID)->swapAndInvoice(NEW_PRICE_ID)), but I can't (don't know how) do it through Stripe UI. I have a doubt that it is possible to do this

Please or to participate in this conversation.