laravel / cashier-mollie

MIT License
375 stars 63 forks source link

Lifetime subscription #149

Closed Paulsky closed 4 years ago

Paulsky commented 4 years ago

Hello,

I'm wondering which fields I need to set to create a 'lifetime' subscription. This is the scenario; We have a couple of plans; bronze. silver and gold. These plans have an interval of one month. Users can subscribe to these plans. But, a Super Admin can subscribe a User to a Plan (without an actual payment. For example because of some sort of give away contest. ).

If I want to change the subscription to 'lifetime' which fields do I need to set? ends_at and/or next_plan and/or cycle_ends_at? Should I set these to null or , for example, to 31-12-3000?

Or am I now just hacking this package and should I wait for https://github.com/laravel/cashier-mollie/issues/42?

Thank you in advance.

P.S. This package is awesome and a big help! Thank you very much!!!!

sandervanhooft commented 4 years ago

Hi @Paulsky,

Thanks for the ❀️ !

So I understand from your message that you'd like a subscription that:

I see a few ways to solve this:

1. Simplest: generic trial If you're ok with it being marked as a trial, you could set a generic trial with an enddate far far away. The only drawback I can see is ->onTrial() would return true.

2. My recommended approach Semantically speaking it's doubtful this whether your scenario is about a subscription at all (free, no payments?). That's why there actually is no clean cut approach for this in Cashier. I'd argue your scenario is about access management instead.

Personally I'd prefer to store this lifetime access setting outside of Cashier (on a Permission/Role or on the User model). Then write a dedicated check for the permission that checks both the Cashier subscription validity and the lifetime access.

3. Hacky, but may work I haven't tried this, but I think you would be fine deleting the OrderItem related to the Subscription and set the subscription billing_cycle_ends_at a far far away date. This will halt scheduling of new OrderItems.

The only drawback here is that when someday the Cashier mechanism changes, your app may break and finding out what happend will be hard. And you'll need to create the subscription record manually.

(I don't see how #42 would help, but maybe I'm missing something.)

Hope this helps.

Paulsky commented 4 years ago

Thank you very much for your quick and detailed reply I really appreciate it.

Sorry, the described scenario didn't make things clear. I have a scenario which is more like a plan with features based subscription. One of the reasons I chose this package. This is the use case:

A User has multiple shops. A shop has a plan. This plan contains features. For example; the bronze plan has two features; editing the slug of a shop and setting a shop image. But, the silver plan has three features; editing the slug, setting a shop image, and change the font color of the shop. The bronze plan costs the User 5 dollar per month, the silver plan 10 dollars a month. A User can open multiple shops with different plans.

But we give the User the option to make a one time 50 dollar payment for the bronze plan, or 100 dollar for the silver plan. Because #42 (a one time payment) is not available, we give the User the option to do a manual payment; bank transfer, cash (if living nearby) or for example with cryptocurrency. If the payment has been made, a Super Admin can manual set the plan for the target shop.

Does this change your doubting and your recommended approach? Sorry, I hope this is still on topic because there are almost no packages which brought me this far in the development (even Stripe Cashier self is not a option).

sandervanhooft commented 4 years ago

Thanks for clearing that up.

The "free" part I misunderstood, but most of my comment stands. Domain wise, I still think it's an access management problem, not a subscription problem.

Pseudo code:

IF customer has bought lifetime_A_access or bought subscription_A THEN customer can access product_A features

I do understand now that the one-off payment feature would help here. I plan on implementing this in March. (Finalizing & launching Spark first.)

Paulsky commented 4 years ago

@sandervanhooft once again, thank you very much! I decided to go with option 1 (trial) as a temporarily workaround. And develop a solid solution when the one-off payment feature is available. Thank you!πŸ™πŸ™

sandervanhooft commented 4 years ago

Good thinking. Enjoy!

Paulsky commented 4 years ago

So how can I bypass the actual Mollie Payment and subscribe to a Plan? i tried the recommended steps in the 'Without Mandate Up Front' README section.

$lifeTimeEndDate = now()->endOfDay()->addYears(100);  
$shop->trial_ends_at = $lifeTimeDate;  
$shop->save();  

$subscriptionBuilder = $shop->newSubscription('main', 'bronze'))->trialUntil($lifeTimeDate)->create();

But this still returns false: $shop->subscribed('main', 'bronze');

sandervanhooft commented 4 years ago

https://github.com/laravel/cashier-mollie/blob/develop/README.md#without-mandate-up-front

Cashier refers to this type of trial as a "generic trial", since it is not attached to any existing subscription.

The generic trial will end as soon as you start the subscription. This is causing your issue.

Thinking about it, if you wish to limit access to a specific product, go with mandate upfront (you can configure the first payment amount equal to the intended product amount) and set the trial to some eternal date.

Paulsky commented 4 years ago

Thank you for your response. So will the mandate upfront work if the first payment amount is zero? I want to manually set a plan subscription ('for free') for 'lifetime'.

sandervanhooft commented 4 years ago

Free vs paid are entirely different use cases πŸ€·β€β™‚. Mandate upfront is always paid, unless you manually create a debit card mandate at Mollie and not charge it. But that would get hacky again.

The access control scenario would take max 30 mins to implement and goes a long way, I strongly advise to solve this (and future issues) that way.

sandervanhooft commented 4 years ago

That way you would use Cashier what it’s meant for: subscription billing and subscription management. And have the flexibility of managing access to your services however you like.

Paulsky commented 4 years ago

Alright, thank you! That's exactly how I see this package; a great way to manage subscription billing and subscription management. It has everything I need to implement the subscription flow for an User. But as an Admin point of view, I would like to manage User/Store subscriptions, and attach/upgrade/downgrade plans, (re)set trail times and/or delete subscriptions. But, without having to pay (as an Admin). I thought that these functionalities could be easily achieved, by reusing the User functions, but just bypassing the Mollie payment flow (API Call->webhook callback). Because my idea was; a lifetime subscription is still a subscription. But I was wrong, my apologies.

sandervanhooft commented 4 years ago

No problem, enjoy!