Preamble
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.
Situation
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:
subscriber
relating to the subscribing model (User
in this case)from_plan
defining the plan identifier the model had before changeto_plan
defining the plan identifier the model has selected nowcreated_at
is a date-time field storing the changevalid_until
stores the date until the actual subscription is validpaid_at
is 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 paid_at
and 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 from_plan
and 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.
UPDATE
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.
Case A
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.
Case B
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.
Case C
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.
_Case D_
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 theSubscriber
is polymorphic Plans
do not necessarily have to be plans, but could be e.g.Magazines
like mentioned. That's what I've described with Case C and Case D.