Jump to content
Larry Ullman's Book Forums

Stripe Webhook Logic


Recommended Posts

Hi Larry


I'm wondering if you can help me with this problem.


I have a site that is on a monthly subscription, it allows a certain numbers of postings per paid user account and I want to give people a really decent trial of it like 6 months free. If I give them a 6 month free trial when they sign up via Stripe it will send back a webhook saying the period expires 6 months into the future. Which is great, the only problem is that I use the expiry end date of a user to calculate how many posts the user has made in the last month.


So If a user has a free 6 month trial from today, Stripe sends me back period_end of 29th December 2014, which I update the user expiry to.  I then use the end date 29th December 2014 with a DATE_SUB( 29th December 2014, INTERVAL 1 month) to determine how many posts have been made. So my counts are always thrown out by this.


Stripe emailed me a few months ago and said that they will only send a payment_succeeded webhook if there is an actual charge on the card.


So i'm not really sure what the best way to proceed here is. I want users to have 6 months free, but I always want a webhook each monthly period to update their expiry date. Or some process which allows the end date to be no further than 1 month into the future?





Link to comment
Share on other sites

Hi Larry,


Let me try and explain better. 


1. Larry registers with my site and pays his money

2. Stripe send me back webhooks including the date the payment_period_end (not sure if that's the actual correct webhook name, but you get the idea)

3. I use this date and update the Larry user record to show that Larry's user_plan expires on such a date.


Because anyone could register at any time, you could have a user, who's plan runs from the 1st of each month and another user could have the same plan but started on the 15th of each month I use the user_expiry date in the user record to calculate the correct time period.


So you sign up on the 1st of July and stripe tells me that your monthly plan expires on the 1st of August so that is your expiry date. So when I want to know how many posts (posting is a perk of having a paid plan) you have used for this current month I use BETWEEN the date_expiry of the user record that comes from stripe and is stored in my DB. so that will give me 1st August and I use DATE_SUB(date_expiry, INTERVAL 1 MONTH); to take me back to the 1st of July.


So my count now only looks for posts that were made between 1st July and the 1st August. 


Does that make sense?


So if I have a 6 month free trial on my plan, Stripe's payment_period_end webhook will return 1st January 2015. Which now means all the logic in my models for counts is wrong - So I'm trying to work out a work around for this. Ideally I need payment_succeeded webhooks even if they are for 0.00 to come in each month but I don't believe they do?



Link to comment
Share on other sites

Thanks for the additional explanation. I still think there's a better way here, though. As for the Stripe stuff, they don't process charges for $0 invoice and therefore don't send payment succeeded events for those. But I don't think you should need to rely upon Stripe. If you already store a user's start date and end date in the database, is there a reason you can just count all the posts made between those two dates? Apologies if I'm still not getting it...

Link to comment
Share on other sites

Well I use the end date to determine whether someone has expired. When you sign up for free your user type is 1 and your end dre doesn't really matter as you can't post. When you join a monthly subscription I change your use type to 2 and use the date you've paid up until with stripe as your end date. Each day I run a cron and if you have decided to leave the paid plan and are now past your expired date I reset your user type back to 1.


So in short stripe tells me when a paid user has expired effectively because I use the end of a users paid up to point according to stripe.


Apologies for not explaining this tht well.

Link to comment
Share on other sites

Additionally each month you stay on the plan I get a notification from stripe and continue to keep updating your end date. When you have expired and stopped your plan the cron will eventually rest your user type back to 1 and the end date will stay as it was and is unneeded.


This process allows me to make sure a user has a paid account and their account hasn't expired. It also means that they get I can accurately count how many posts they have made for their colander month subscription. As not everyone will sign up on the same day. So any trial period with stripe over a month throws my logic out so my counts are wrong and additionally I can't set the expiry of a 6 month trial to 1 month in the future as I would need webhooks each month to keep updating their user end date.

Link to comment
Share on other sites

user table
ID, f_name, l_name, date_joined, user_type, date_exp
1 - Larry - Ullman - 11-07-2014, 2, 11-08-2014
ID, type
1 - Free
2 - Paid


So you have joined my website. Registration is $1 per month if you want to be a paid member. Upon registration, I send your payemnt info to Stripe. They send me back the info confirming that you paid and it all went through. I look for a  "period_end": 1405129609, in the response and I use that to create your date_exp



When I am doing usages for the current billing period, I use the date_exp to find out when your paid account finishes and back track 1 month. 




COUNT(id) FROM posts, user ON user.id = posts.user_id WHERE posts.date_added BETWEEN DATE_SUB(user.date_exp, INTERVAL 1 MONTH) AND user.date_exp
That will give me the number of posts in this case any user has made in their particular billing period.
I have a webhook script and it looks for payment_success webhooks. This is how my system sees Larry has paid his new subscription fee. What this does now is take the new period end "period_end": 195246879609 and say Larry's subscription actually runs out now on 11-09-2014 and it takes that date and update your user record's date_exp
Usage is just like stats, oh he'd used 10 posts of his available 15 for this month or whatever. Those kind of things.
But this means I can get an accurate count on stats for that billing month.
Side Note - Although this isn't that related it is worth mentioning, a paid user account has more benefits and permissions that a free account. I have a RBAC set of tables to control this. Say you ended your subscription there would be a time when the current day is greater than your expiry date. I run a cron every day that checks for this occurence, you have a paid user_type and your date_exp is less than today's date. That means you've expired, this cron then resets your user_type to 1 and updates the RBAC tables so you get a free members permissions.
Hopefully I haven't lost you with these steps, apologies if I have. Now is the bit that throws a spanner in the works.
If I sign you up for a monthly subscription but give you a 6 month free trial through Stripe. Stripe will send me back a "period_end" of 11-01-2015. Which is great in that you won't have expired and have all the permissions for 6 months.
When I run my usage stats using the same kinds of queries as above it will look for posts.date_added BETWEEN DATE_SUB(11-01-2015, INTERVAL 1 MONTH) which would be 11th December 2014 and the 11 January 2015. So any usage style stats I have won't work as you can't post into the future (technically)
So I guess my point was, what from a stripe perspective / or code perspective could I do here, I wondered if I didn't know of any cool events. 
I don't have to use Stripe's period_end to populate the date_exp on creation, I could just do it within the DB or Yii with DATE_ADD(NOW(), INTERVAL 1 MONTH). Which is how I started doing it. But with a 6 month free trial, no payment_succeeded events are sent so my script wouldn't update the user's date_exp and they would through no fault of their own become expired.
The only other I thing I've thought of is just charging $0.50 a month for 6 months. So I get the payment_succeeded event, so their account keeps ticking over and I can set their expiry a month in advance, keeping their usage stats from not breaking.
Does that make any sense?
Link to comment
Share on other sites

Okay, thanks for your patience. I'm not positive this will work, but what about subscribing your customers to a plan like normal (e.g., monthly plan). For those you want to give a free 6 months to, you'd create a coupon for 6 months free. Those users won't have payments, of course, but they'll still have monthly invoices. But the amounts would be $0. Then, when an `invoice.created` event occurs, if the invoice is $0, you'd know that's equivalent to `invoice.payment_succeeded` and you'd extend their date_expires period another month.


Would that work?

Link to comment
Share on other sites

  • 1 month later...

  • Create New...