Users not being removed from group when plan cancelled / expires
Closed this issue · 16 comments
Craft 3.5.5
Commerce 3.2.3
Membership 1.0.0
Hey, @kevadamson! Thanks for reporting.
Do you have webhooks set up? I might need a bit more information about your application to troubleshoot.
@AugustMiller Hm. Could it be because I'm testing on my local server?
Likely so—you can set up a temporary ngrok
tunnel if you want to test webhooks locally, then use that public URL in Stripe.
I believe without functioning webhooks, the Subscriptions::EVENT_AFTER_EXPIRE_SUBSCRIPTION
event is never triggered. Commerce itself may not even know that the Subscription has expired on Stripe's end!
Do keep in mind that the cancellation doesn't affect access, only expiration. A user's subscription could still be active, even if they've canceled—it just won't renew. At the end of that period, the subscription will actually expire and their permissions will be revoked.
Hope this makes sense! ✌️
One more clarification: Webhooks are a requirement of Commerce + Stripe's Subscriptions implementation, not just the Membership plugin!
Whether or not you end up using the plugin, you'll need to get webhooks working in your live environment. 😉
@AugustMiller Thanks for the heads up on ngrok - works a treat!
Ok, that's a relief! 😅 I'm closing this issue, but please ping me here or on Discord if you need anything else!
Just tried this live and user not being removed via an immediate cancellation. My gateway is Stripe Commerce btw.
Created: Sep 2, 2020, 1:49:23 PM
Trial days credited: 0
Next payment: Sep 3, 2020, 1:49:21 PM
Expiry: Sep 3, 2020, 1:49:21 PM
Expiry: Sep 2, 2020, 1:49:45 PM
Cancellation: Sep 2, 2020, 1:49:45 PM
It's showing as being cancelled in the Stripe dashboard as well.
Webhooks:
source.canceled
source.chargeable
source.failed
invoice.payment_succeeded
customer.subscription.deleted
plan.updated
plan.deleted
plan.created
invoice.created
customer.subscription.updated
invoice.payment_failed
Thoughts?
@kevadamson Hey, sorry to have missed this! Didn't see it in my GitHub notifications…
Can you just select "everything" from the Webhook config, and see if it works?
Also, you'll need to make sure your webhook config is the same for test and live environments—otherwise, they'll only fire in one or the other.
FYI, here is a list of the minimum web hooks required for Subscriptions to work:
plan.deleted
plan.updated
invoice.payment_succeeded
invoice.created
customer.subscription.deleted
customer.subscription.updated
Source: https://github.com/craftcms/commerce-stripe/blob/develop/src/base/SubscriptionGateway.php#L465-L490
Yeah still struggling with this. So I've set up and 1 day subscription, when I take out the subscription the plugin adds the user to the user group, but then when I cancel the subscription and allow it to expire, they are still in the user group, and have not been removed ...
Does Craft/Commerce know it's expired? Specifically: in the Subscription's edit screen in the Craft control panel, does it list it as Expired, or Canceled?
Just trying to rule out the possibility that this is a webhook issue! FYI, if your ngrok tunnel was closed, it will start up at a new URL, which means your web hooks will no longer complete—the hook must be re-added in Stripe.
Also worth checking in Stripe to make sure the web hooks are successful (should be a 200-level response)!
Yeah, this looks good.
Only other plugin-side thing I can think to check is if the user has any other active subscriptions—an expiring one won't remove the user from a group if another active subscription prevents it!
Reviewing the Commerce + Stripe source, the only place that calls Commerce::getInstance()->getSubscriptions()->expireSubscription($subscription);
is within a webhook response—so, if this is not functioning as expected, I'm inclined to believe it's an issue with ngrok.
As a list of things to double-check (for anyone else finding this issue):
- Stripe key type (Test vs. Live)
- Correct Ngrok tunnel URL in Stripe webhook
- Successful (200-level) webhook response in Stripe logs
- Subscriptions are indeed being marked as Expired in Commerce
@kevadamson Hey, just following up, here—
I finally took a moment to spin up another test case from scratch, and believe that this is working as expected, even when a subscription expires naturally (in addition to using the Cancel Immediately option).
(I also confirmed the log entry—the user was no longer in the specified grant group)
My hope is that there is just a problem with your webhook delivery—it took me a moment to get things configured via my Nitro virtual machine, but so long as the tunnel was available at a consistent URL during the creation and eventual expiration of a subscription, it appears to work as intended.
It might be worth paying for a custom Ngrok host/subdomain so that you can restart a tunnel without having to reconfigure it in Stripe. I elected to use something like my-business-name.ngrok.io
and then start the tunnel like this:
$ ngrok http -hostname=my-business-name.ngrok.io -host-header=craft-scratch.test craft-scratch.test:80
Best of luck!
In case anyone else comes here looking for help, Stripe has a new CLI that makes the process of testing webhook-dependent applications a lot easier:
stripe listen --forward-to 'https://my-site.nitro/index.php?p=actions/commerce/webhooks/process-webhook&gateway=1'
…where 1
is the presumed ID of the Stripe Gateway in your implementation!
This basically takes the place of an ngrok
tunnel, and just temporarily registers a webhook target so you don't end up with a bunch of bogus testing URLs in the development dashboard.