Disable features from subscription when it expires
Im having trouble figuring out how to handle this. So I have a subscription that allows users to highlight recipes in searches so they show up closer to the top of the list. This is handled super simple with them being able to select a limited number of recipes and have a boolean field for the recipes that is set to true if it is sponsored.
What I cant find with the payment stuff is how I would set up to turn the boolean field to false when their subscription ends. Since its not immediately if they still have time left on the current months subscription
What I cant find with the payment stuff is how I would set up to turn the boolean field to false when their subscription ends. Since its not immediately if they still have time left on the current months subscription
Stripe sends a webhook when the subscription is canceled, which changes the
All you do to check the subscription status is call the following which returns a boolean.
Pay::Subscription.active?
to return false
. A subscription won't cancel until the end of the period unless you call cancel_now!
which will do it immediately.All you do to check the subscription status is call the following which returns a boolean.
current_team.subscribed?
Stripe CLI for forwarding webhooks is required to test any of this stuff in development of course.
Sorry I got all of that and have the checking for setting the features up and showing the extras options when they have a subscription. My problem is when the subscription ends (not when they cancel) I need to change a boolean variable on recipes that are affected by it. Was thinking a nightly cron job but seems inefficient.
Ah, gotcha! Then I would just add a webhook listener.
We use the StripeEvent gem behind the scenes in Pay to update subscriptions, etc so you would just do the same thing. I'm pretty sure StripeEvent lets you add multiple callbacks for the same event, so you can just add your own on
We already initialize it with API keys and everything, so you should be fine to just drop it in an initializer. https://github.com/integrallis/stripe_event
Need to go add docs to Pay & Jumpstart for how to do this.
We use the StripeEvent gem behind the scenes in Pay to update subscriptions, etc so you would just do the same thing. I'm pretty sure StripeEvent lets you add multiple callbacks for the same event, so you can just add your own on
subscription.deleted
to update the related records.We already initialize it with API keys and everything, so you should be fine to just drop it in an initializer. https://github.com/integrallis/stripe_event
Need to go add docs to Pay & Jumpstart for how to do this.
Negatory, Briantree and Stripe webhooks are totally different. There's a Braintree webhooks controller in Pay you can look into. Would need to extend that.
Actually, you could probably add an `after_commit` callback on the Subscription model to make your updates if the status previously changed to `canceled`. That might be easier than dealing with webhooks.
Actually, you could probably add an `after_commit` callback on the Subscription model to make your updates if the status previously changed to `canceled`. That might be easier than dealing with webhooks.
Hmmm, the pay_subscription table gets updated when they cancel though and not at the end of the grace period. Looking to make the changes when the grace period runs out.
Doesnt look like the model gets updated again when the grace period runs out...right?
I'll have to look more into the webhooks with the pay gem then and see what I can do with that and when braintrees webhoooks are sent out for the different events.
Also might be a bug but looking at the
Doesnt look like the model gets updated again when the grace period runs out...right?
I'll have to look more into the webhooks with the pay gem then and see what I can do with that and when braintrees webhoooks are sent out for the different events.
Also might be a bug but looking at the
subscription.active?
function, Im getting a false return when the subscription is cancelled but the on_grace_period?
returns true. Looking at the subscription model:def active? ends_at.nil? || on_grace_period? || on_trial? end
Shouldn't that return true if
I ran just that same check and got true, but when I use the
on_grace_period?
is returning true?I ran just that same check and got true, but when I use the
subscription.active?
it returns falseThis is where Stripe + Braintree gets too tricky to make work similarly without doing a bunch of extra work. Stripe will trigger a webhook and update the status when it is canceled. Braintree doesn't have an event though I don't think.
I guess you could even schedule a job to run at the time it should end the grace period and when the job runs make sure they're still canceled (and haven't resumed) before doing the updates.
That line of code does return true if it's on grace period because it's OR between those. What's wrong?
I guess you could even schedule a job to run at the time it should end the grace period and when the job runs make sure they're still canceled (and haven't resumed) before doing the updates.
That line of code does return true if it's on grace period because it's OR between those. What's wrong?
Yeah I was thinking scheduling a job to run when the grace period ends also. Or a nightly cron job that grabs any subscriptions with the same ends_at date as the day the job runs.
For the pay gem subscriptions model, the active? function is returning false even though the on_grace_period? returns true. Running the commands in the console, here's my commands and results for reference (u is the team that the subscription is assigned to)
For the pay gem subscriptions model, the active? function is returning false even though the on_grace_period? returns true. Running the commands in the console, here's my commands and results for reference (u is the team that the subscription is assigned to)
[6] pry(main)> u.subscription.active? Pay::Subscription Load (0.5ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] => false [7] pry(main)> u.subscription.on_grace_period? Pay::Subscription Load (0.5ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] => true [8] pry(main)> u.subscription.ends_at.nil? Pay::Subscription Load (0.4ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] => false [9] pry(main)> u.subscription.on_trial? Pay::Subscription Load (0.4ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] => false [10] pry(main)> (u.subscription.ends_at.nil? || u.subscription.on_grace_period? || u.subscription.on_trial?) Pay::Subscription Load (0.5ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] Pay::Subscription Load (0.3ms) SELECT "pay_subscriptions".* FROM "pay_subscriptions" WHERE "pay_subscriptions"."owner_id" = $1 AND "pay_subscriptions"."name" = $2 ORDER BY "pay_subscriptions"."id" DESC LIMIT $3 [["owner_id", 1], ["name", "default"], ["LIMIT", 1]] => true
So the last command you can see that if I enclose all the or conditions in parenthesis it returns true...didnt think that was necessary but tried it just to see what it would return.
This stuff is always trickier than I'd like. I think either option would be good. They'd be the most reliable that way since the webhooks aren't consistent. The cron seems safer in case your background workers lost jobs if something bad happened.
And I bet the difference is that it's the Subscription status. Make sure you're browsing the SCA branch.
https://github.com/excid3/pay/blob/sca/app/models/pay/subscription.rb#L53
I still need to cut a release for v2.0 which will be all SCA.
I do believe there is a bug that the Stripe cancel should not change the status, because it's still technically active status in SCA until they cancel it.
And I bet the difference is that it's the Subscription status. Make sure you're browsing the SCA branch.
https://github.com/excid3/pay/blob/sca/app/models/pay/subscription.rb#L53
I still need to cut a release for v2.0 which will be all SCA.
I do believe there is a bug that the Stripe cancel should not change the status, because it's still technically active status in SCA until they cancel it.
gotcha, thanks for the quick responses. Ill start working on a cron job, as that seems the most straight forward for me and fullproof method.
The active status doesnt effect my use very much cause all my checks use the on_grace_period? as a fallback. Ive been testing with braintree sandbox and everything worked right out of the box with jumpstart.
The active status doesnt effect my use very much cause all my checks use the on_grace_period? as a fallback. Ive been testing with braintree sandbox and everything worked right out of the box with jumpstart.
Notifications
You’re not receiving notifications from this thread.