My aim is to create reusable code for multiple projects (and also publish it on github) to manage subscriptions. I know about stripe and recurring billing providers, but that's not what this module is aiming for. It should just be a wrapper/helper for calculating account balance, easy notifications to renew a subscription, and handle price calculations.
There are countries you can't use recurring billing because of the providers or payment possibilities having poor or no support for it or are too expensive (micropayments). And there are people that don't want to use recurring billing but pay their bill manually / avingg an invoice at the end of the year. So please don't suggest paypal recurring billing, recurly or similar services.
Let's say you have a model that can subscribe to a subscription plan (e.g.
User). This model has a field that stores the identifier of a subscription plan it is currently subscribed to. So, on every plan change, the change is recorded.
There is a model (e.g.
SubscriptionPlanChanges) with the following fields recording the mentioned changes:
subscriberrelating to the subscribing model (
Userin this case)
from_plandefining the plan identifier the model had before change
to_plandefining the plan identifier the model has selected now
created_atis a date-time field storing the change
valid_untilstores the date until the actual subscription is valid
paid_atis also a date-time field that defines if (and when) subscription was paid
Of course, that layout is discussable.
Question of account balance
When a User changes his/her subscription plan, I need to compare the plan fields, get the pricings, and calculate the deduction for the new plan based on the current plan's
valid_until and its price. Say: You subscribed for a year of plan A but after 6 months, you upgrade to plan B, so you get a deduction of half the paid price for the 6 months of plan A.
What I am wondering: If a user e.g. switches to the free plan, he has a credit which can be deducted if the user wants to switch again. Would you cache that value in an additional field, or calculate through all the records related to that user every time? Would you add/change something about the table layout?
Question of easy comprehensibility
When the end of a subscription period arrives, the user gets notified and has the possiblity to renew his subscription by paying again. The easiest way would be to just update
valid_until with new subscription options. However, I am not sure if you store every data someone might need, like a payment/subscription history.
Another option would be to create an additional record for this, where
to_plan are having the same identifier (thus symbolizing "no change"). But wouldn't that interfer with calculating the account balance in some way?
If someone could point me into the right direction about the logics handling such subscriptions, I'd appreciate it very much.
Thanks for the help by now. I think my question was too vague so I'll try to be more precisely by using less abstraction. Unfortunately, I could not solve my problem yet.
User can select
Subscription Plan A. This currently stores a
SubscriptionPlanChange to keep track of it. After e.g. 5 months,
User upgrades his subscription to
Subscription Plan B. So he pays the price for his new subscription, deducting the price of plan a for the unused 7 months.
After 3 months,
User rolls back to his
Subscription Plan A. He does not have to pay but receives a balance for it so that, at the end of the subscription, he gets that balance deducted for his new subscription.
User can select a subscription plan for a sub-service that has independent subscription plans. Same
Case A and
Case B can apply for that sub-service subscription.
User cancels one of his subscriptions. This results in a top up of his balance.
My question (currently, at least) mainly depends on how to store that data properly so I can reproduce a history of subscriptions for business analysis and calculate balances, get outstanding payments based on the subscriptions etc.
I am also not sure if the balance should be stored in e.g. the users model itself, or if it is not stored but can be calculated any time based on the stored data / history.
Some things to note, although I don't think that they should introduce problems:
- It does not have to be a
User, it could be anything, that's why the
Plansdo not necessarily have to be plans, but could be e.g.
Magazineslike mentioned. That's what I've described with Case C and Case D.