bpuig / laravel-subby

Laravel Plan and Subscriptions manager.
https://bpuig.github.io/laravel-subby
MIT License
102 stars 42 forks source link

"Canceled subscriptions with an ended period can't be renewed." #52

Closed boryn closed 3 years ago

boryn commented 3 years ago

What to do if a user cancels a subscription and (after some time) he wants to reactivate the subscription? We cannot do it.

$user->subscription('main')->cancel();

they got cancelled as expected, they come back after 6 months, they pay and we want again create a subscription for them:

$plan = Plan::find(1);
$user->newSubscription('main', $plan);

and we got: A subscription with tag main is duplicated for this subscriber.

I am not sure why canceled subscription cannot be set active again? Do we treat cancelled subscriptions "as history"?

Maybe the library should create a new row for the new subscription with the same tag and allow only one active (not cancelled) row? Should we have a broader unique index with canceled_at field? Thereotically MySQL allows multiple NULLs in a column with a unique constraint, but would it be a good solution?

boryn commented 3 years ago

IMHO it should be totally fine to renew a cancelled subscription with ->renew(). If someone wants to keep history / log it should be done in a separate place and plan_subscriptions should reflect the current state of the Subscription.

bpuig commented 3 years ago

To be honest, I don't know why cancel has that weird behaviour, this is from Rinvex's package and when i found it I was like 😕 ???

I'll take a look.

bpuig commented 3 years ago

Do we treat cancelled subscriptions "as history"?

Not exactly as history, because only the last one is kept, there is no more backwards history. If you do not want the possibility to uncancel, you would just delete it instead of cancel or have some custom process that changes it's tag to history-n when it both conditions ended and canceled are met. And then it would be a history.

It stays like that in case it needs to be uncanceled.

How to do renewals, I see two different ways:

Uncancel and renew

$subscription->uncancel()->renew()

Uncancel and changePlan

$subscription->uncancel()->changePlan($plan)

You can always call uncancel() when renewing or changing plan because if it's not cancelled it won't make a difference and if its cancelled it will be uncanceled.

I think the package needs to be able to do everything without being bloated. So for now maybe how it's done is enough, everyone implements their renewal process.

boryn commented 3 years ago

Actually I was unuware of the uncancel() method. Is it mentioned in the docs? On the other hand why ->renew() cannot do the uncancel?

bpuig commented 3 years ago

I think it does not uncancel automatically to avoid mistakes. This was like that in rinvex, I do not think it's a bad idea per se, it makes the function renew a bit more safe in terms of charging a new period on someone who cancelled. Having a method for uncancel that can be explicitly called, I don't see much hassle having to preppend it to renewal.

Docs updated in ee1a464c2b96b6f72d3d1e0bfb675b33f76d0e75