The Case for Commerce_SP
This is pretty long but if you are interested in subscriptions / recurring and are a drupal developer its worth a read and more importantly a comment / feedback please.
A while ago I needed to create a subscription based website. The user would be subscribing monthly/yearly for access to premium content, but we were not going to save cards on file and we didn't want it to be automated billing. We wanted notification emails to be sent out prior to the subscription ending telling them to buy a new one. When they did, their subscription time would be extended.
Very straight forward use case for the commerce_sp module. For those that have not used it, you basically create subscription products with a length of time. There are rules for start, stop, continue subscriptions where you can do stuff like adding/removing roles, etc. The expiration is controlled by a date "validity" field attached directly to the user entity.
This works pretty fantastic if you want to subscribe to a site and there is only one membership level. But what if there are multiple membership levels? How do we keep track of the different roles? How can that work with just a single validity field?
After a bof at Drupal Camp Atlanta recently on this topic we discussed some of the other modules out there specifically commerce_recurring and commerce_licenses.
After that bof, we came to a conclusion that for these types of subscription based sites, we might be better off using commerce_recurring so I started looking into it.
With recurring you have a subscription/recurring product type where you can define a length, recurring length, and end time. On purchase of the product, a subscription entity is created that keeps track of the recurring product, the order, etc. Then on cron, when the subscription is expired, a rule triggers that will automatically create a new order with the same product, and assuming you have cardonfile installed and configured with the rule, automatically bill. This sounds fantastic, even without the card on file, I can just email them the url to the order checkout and have them do it manually. But here is where I ran into problems with this solution:
- If I buy a subscription to something, in my example the sites premium content, and then a day later buy another subscription, I would expect my subscription entity created the first time to just extend that time similar to how commerce_sp would extend the validity.
- With the above in mind as is, most of the time I would be buying access to a role. If I add a role on subscription start, even when I buy a second time and I already have the role, when the first expired I would then lose the role (since I'm not doing auto pay) even though I already purchased a second subscription to extend my time.
With that in mind I am now wondering if there is still a use case for commerce_sp. I figure we have two ways to proceed:
- I don't know of anyone that is using commerce_sp and is NOT adding a role on start of subscription. With that in mind we might as well add a role referencefield to the product type so we dynamically add/remove the role out of the box without having the user modify the rules. If it doesn't have a value, no problem, no role.
- Instead of having a single validity date field on the user we need to either:
- Use field collection to keep track of product => validity relationship on the user entity so if I buy a month of membership A and a year of membership B, those dates are tracked independently of each other and start/end with the appropriate actions.
- Abandon the fields on user approach and use a subscription entity approach like commerce_recurring does, but if I buy the same product my validity should extend, not create a new entity. Entity revisions can help keep track of changes like this for historical data. I rather like this approach but is obviously a lot more work.
- Currently commerce_sp uses scheduled rules to execute the components that end subscriptions. In the very first site I did I used the same platform to schedule notifications as well on start/updates. I think again I rather like the cron approach better. Still have components but let cron execute them, not scheduled rules that for some strange reason could accidentally get deleted?
- Long term thinking: As a module maintainer I cringe at the thought of users installing a module I contribute to and immediately start modifying and overriding stuff like rules. I don't know how to maintain updates to uses with this being the case. I think one idea here is instead of having/telling users to modify the start/end/update rules, we tell them to create components for what they want to happen then they can configure which components to execute on a global and product level. Entityform does something similar with its notification components and its rather convenient.
- Speaking of notifications: I have yet to find a good way to create, maintain, and "schedule" notifications for these subscription products. For example emails to go out 1 month, 1 week, 1 day before expiration, etc. I was thinking about creating a notification entity type that had a title, body (email content) and a interval field. Then each email would be an entity and cron could send em. Add a product reference field and you have per product notifications. Any thoughts? Maybe in a separate discussion?
There are my thoughts. I would be far more comfortable upgrading commerce_sp than I would commerce_recurring just because of my experience with the former. If enough of you say, no we can do that with recurring then sure lets dig in. I would love to hear others thoughts and experiences with either or modules.