Subscriptions: Moving the cycle date

Sometimes the answer is the most simpler one

Italo Baeza Cabrera
3 min readDec 5, 2022
Photo by Sticker Mule on Unsplash

Long time ago, I was working for a client who had a very archaic subscription system. It was very rigid, had some hacky ways to change some subscription data, and had no CI/CD at all.

One of the most problematic situations was to change the subscription date. An user was forced to cancel the subscription, lose all their data, and start all over again in the system. That’s were an external admin came in to do that work manually, and move the data raw on the production database. Sweaty hands all around.

Seeing how that was problematic, I created my own solution to move subscription dates with my Subscription library.

Extending, not recreating

Most (sane) subscriptions systems have an start, and end, and a cycle count. Each time the cycle count is incremented, the end date is pushed forward.

For example, a 1 month subscription that starts January 10th will be extended to February 10th, March 10th, and so on.

The reason why this data exists is to correctly move dates. If a monthly subscription starts January 31th, the next cycle should start February 29th. By doing some magic with PHP dates, we can ensure the cycle end doesn’t bleed to the next month, like March 2th.

The most sane way to change the subscription cycle to start for a new date is to extend the current cycle to the desired date, and charge the user the extended days at the same time.

For example, let’s think about a $ 60/mo subscription. It starts January 10th. The user wants to change the billing cycle to start each 20th. For that, we will extend the current cycle by 10 days, so the next cycle starts February 20th.

We will charge $ 20 for the change, keeping the next subscription bill the same.

Laragear Subscription does exactly that, but also modifies the internal date start so the next cycle reflects the change. The magic is handled automatically by the adjustStartTo() method.

$user->subscription->adjustStartTo(today()->addDays(10));

$user->subscription->save();

One of the neat things about doing this is that you’re not left in the dark when calculating how much to charge for the extension. Using the same example of the 10 days, we will proceed charge the user the extension amount by calculating the extended time given by adjustStartTo().

$extended = $user->subscription->adjustStartTo(today()->addDays(10));

$cost = $extended->totalDays * (60 / 30); // $ 20

return "You will be charged $ {$cost} to accomodate the cycle change.";

This way we can keep a subscription data intact, and by charging upfront the subscription change we can ensure the user consents to the decision.

There are other ways to change the subscription cycles, sure, like creating a new subscription and deleting the old, but to me it doesn’t gets cleaner than this since renewing the subscription works as expected when the start point is modified.

--

--

Italo Baeza Cabrera

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor. https://italobc.com