views:

111

answers:

4

We have a freemium product, which menas that some functionality is available if the monthly subscription has been paid; if not paid, then the free capabilities remain available.

Here is how I am thinking of processing it, but wanted to check:

1) When someone purchased their subscription, a recurring billing schedule is created.

2) The user will have a field (paid_up) set to "y"

3) When the user logs back in, the authentication script checks if paid_up is "y". If it is, it creates a session token

4) I think I need a batch script which will switch the toggle. Wondering how to do it? Store the date of the last credit card successfully processed?

A: 

Sure, you would create a column called 'last_payment'. If using MySQL, you could create this as a DATE field. Each tme you receive a monthly payment, I'm assuming the credit card billing company would post something to a script on your website. (i.e paypal sends IPNs). Each time this is received, you would do a query such as:

UPDATE members SET `last_payment`=CURDATE() WHERE user_id='$user_id';

I would suggest running a script on CRON that runs once every 24 hours, and does this query:

UPDATE members SET paid_up='N' WHERE DATEDIFF(CURDATE(),last_payment) > '30';

This would update all the records where payment hasnt been made for 30 days or more, and set the paid_up field to N. Then your normal login code would work.

If you don't want to use CRON, you could change your login query to something like this:

SELECT 1 FROM members WHERE 
username='$user' AND password='$password'
AND DATEDIFF(last_payment) <= '30';

By the way, your credit card processing company might have a way of sending you a POST when a subscription is canceled, which would enable you to set the paid_up field to N.

Hope this helps. Feel free to comment if you have any questions :)

Click Upvote
Ah, I could do this...thanks for getting code-specific, always love that.
AFG
If you like this i would appreciate if you clicked that little tick mark next to my name so i could get some rep. for this answer :-)
Click Upvote
A: 

I'd work this from the other end and have a paid-to field with a paid up date stored there. That way you could have users cancel there sub and still get the benefit of the payment they did make.

Brody
Ah nice addition...good supplement to Java's post...
AFG
A: 

If the recurring billing process is something you run on your side, you can include these checks as part of your process. The way I would think about this algorithmically is something like:

For each customer that's due
    Run billing on their account
    If successful:
        Reset retries to 0
        Mark them as a paid customer
        Continue to the next account
    Otherwise:
        Increment their retry counter
        Send an alert to the customer
        If their retry counter reaches a maximum:
             Toggle the switch to mark them as free

You can do the same in batch if something else runs the billing and just tells you the results, just replace "Run billing on their account" with "Read results from last billing attempt". Your retry counter would implement something like a grace period, assuming your billing runs on a daily schedule, so they'd have a chance to fix the billing problem rather than just having their premium features revoked just because their card expired or some such.

brokenbeatnik
A: 

Having written a few of these before, there's a couple of things you should do.

First, as mentioned by others, you want some kind of paid_through_date field. This is important for a number of reasons, but the main one is that it gives you additional flexibility in case of, say, your servers going down, and you decide users should be credited with an additional day of free service. Just push back their paid_through_date value by a day. This also makes free trials simple to implement.

Second, don't use stuff like Authorize.net's Automated Recurring Billing, even if you're working on a subscription system. You want to be in full control over when the payment gets scheduled, and offloading that responsibility to your gateway is just a bad idea in most cases. Most gateways will allow you to store a credit card on their servers. They'll give you back an ID for that card, and you can issue charges against that intermediate ID instead of the card itself.

Third, LOG ALL TRANSACTIONS. I can't overemphasize this enough. In fact, you should probably expose this log to the user as well. Basically just a table of all of the payments they've made, the amounts, and the final balance. It's common to put invoices into this table as well. Invoices have a positive amount, payments and credits have a negative amount, and just sum everything for the user to obtain the final balance. You can introduce arbitrary credits to this table very easily if so desired.

Run a cron script that fires every 24 hours that checks what users need to have an invoice generated. This cron script should have three critical properties: First, if it doesn't run for some reason, you shouldn't lose a day's worth of charges. Second, if it runs more than once in a day, or if it gets aborted mid-way through and rerun, it shouldn't charge people twice. And third, if the date on the server gets changed to 2090 by accident, it shouldn't automatically bill all of your users for millions of dollars. Similarly, resets to dates in the past (Notably, Jan 1, 1970) should also cause it to raise hell. Daylight savings, in my experience, is rarely an issue.

I think that covers most of the big stuff, but there are always little gotchas in billing systems that you have to watch out for.

Bob Aman