Stripe EOT does not demote

What would prevent Stripe from demoting a user when EOT is reached? This seems to be happening consistently where EOT does not bring demotion of the user account.

My shortcode looks like this:
[s2Member-Pro-Stripe-Form level=“1” ccaps=“hips_focus_general_level_august_16th” desc=“Hips Focus General Level August 16th Video - $14.00 for 48 hour access” cc=“USD” custom=“rivervalleyyoga.com” ta=“0” tp=“0” tt=“D” ra=“14.00” rp=“2” rt=“D” rr=“BN” coupon="" accept_coupons=“0” default_country_code=“US” captcha=“0” success="/video-classes/thank-you/" /]

I guess that s2Member is ignoring Stripe’s IPN with the information the user cancelled their recurring subscription.

I found out that it’s not acting up on the information after checking the logs, but I didn’t get a reply either: Stripe's IPN for Cancellation During Trial being Ignored

Hi Gerry.

Does the user profile get an EOT time set after buying the access? After that time is reached, what happens to that time in his profile, is it still there or not anymore?

Create a test user account, add an EOT time in the past, does it get the EOT behavior soon after?

What is your EOT configuration? WP admin > s2Member > Stripe Options > Auto EOT Behavior

Let me know how it goes. :slight_smile:
With logging enabled, what does your auto-eot-system.log file say? WP Admin > s2Member > Log Files

1 Like

I don’t have the log files turned on, but I do have the Stripe EOT behavior set to demote upon the end of term and clear our CCAPS. Yes, s2M does set the EOT after purchase. I’m getting mixed success with the EOT and CCAPS sometimes being cleared and demotion happening, and sometimes not. Perhaps the issue is with the WP-cron? These are also return purchases, not recurring subscriptions.

Thanks for the details, Gerry.

Okay, maybe the cron is just a bit behind… Could you try the hack suggested here? https://f.wpsharks.com/t/8362/2

Create this folder/file with that code in it: /wp-content/mu-plugins/s2-hacks.php

See also: https://s2member.com/kb-article/hacking-s2member-plugin-w-hooksfilters-for-wordpress/

I hope that helps. :slight_smile:

1 Like

A post was split to a new topic: Stripe level subscription downgrade

Hi Cristián, Thank you for pointing me in this direction. I have added the s2-hacks.php file with the code in the suggested location. After doing so, I loaded the URL s2member_auto_eot_system_via_cron=1 and the one account that should have expired but was not, did expire and was demoted… So, I’m not sure if adding the code or running the URL did force the cron to run. There is another account that should expire later today, so I guess I’ll see if it doe it automatically as expected. My question now is simply: does this hack now in place resolve the issue going forward without me having to take any further action? Thank you again!

I was disappointed to find that the user who should have been demoted overnight did not get demoted, so I must have missed something in what I’m supposed to do. I did add the s2-hacks.php file but I don’t understand if that is the whole solution.

Again today, I loaded the URL: /?s2member_auto_eot_system_via_cron=1 and THAT is what made the demotion happen.

Why is this not happening on its own? Where can I look to see if WP_CRON is running and get a log of what it’s doing?

Thanks for your help!

I have my crontab set up to curl that url every few minutes on my server. Maybe you need to do the same.

Hi Sim, thanks for the reply… but this site is in a shared hosting environment on GoDaddy.com… is there a WP plugin that will help me curl that URL perhaps? I guess I’m disappointed that s2M doesn’t actually do this… it’s an advertised functionality that EOT demotes the user.

It sounds like it’s working then. The issue seems to be that wp-cron had not fired until you loaded that URL. This is not under s2’s control, it’s a limitation in WP’s implementation.

wp-cron is not a real “cron” job, it doesn’t fire at the set time. When WP is loaded, wp-cron will check scheduled events and see which are behind the current time. https://developer.wordpress.org/plugins/cron/

If WP doesn’t get loaded, wp-cron doesn’t run. If nobody visits the site, or maybe if a cache is served instead of loading WP, wp-cron will be behind.

But if that user that should have been demoted, logs in, then the cron would have demoted him then, and the effect would still have been the intended one, I think.

A real cron job loading that URL, as Sim mentioned, would help keep things up-to-date, but it’s true that not every host makes it possible.

You could also try a cron-jobs online service, e.g. https://cron-job.org/en/

:slight_smile:

1 Like

I had the problem happen today, when I cancelled a subscription for a customer that was delinquent, but s2member ignored the webhook:

LOG ENTRY: Sat Jan 16th, 2021 @ precisely 1:08 pm UTC
PHP v7.4.13 :: WordPress v5.6 :: s2Member v201225 :: s2Member Pro v201225
Memory 6.09 MB :: Real Memory 2.00 MB :: Peak Memory 6.14 MB :: Real Peak Memory 2.00 MB
redactedurl?s2member_pro_stripe_notify=1
User-Agent: Stripe/1.0 (+https://stripe.com/docs/webhooks)
Array
(
    [event] => Stripe\Event Object
        (
            [id] => Redacted
            [object] => event
            [api_version] => 2020-08-27
            [created] => 1610802532
            [data] => Stripe\StripeObject Object
                (
                    [object] => Stripe\Subscription Object
                        (
                            [id] => Redacted
                            [object] => subscription
                            [application_fee_percent] => 
                            [billing_cycle_anchor] => 1608072674
                            [billing_thresholds] => 
                            [cancel_at] => 
                            [cancel_at_period_end] => 
                            [canceled_at] => 1610802532
                            [collection_method] => charge_automatically
                            [created] => 1605480674
                            [current_period_end] => 1613256674
                            [current_period_start] => 1610664674
                            [customer] => Redacted
                            [days_until_due] => 
                            [default_payment_method] => 
                            [default_source] => 
                            [default_tax_rates] => Array
                                (
                                )

                            [discount] => 
                            [ended_at] => 1610802532
                            [items] => Stripe\Collection Object
                                (
                                    [object] => list
                                    [data] => Array
                                        (
                                            [0] => Stripe\SubscriptionItem Object
                                                (
                                                    [id] => Redacted
                                                    [object] => subscription_item
                                                    [billing_thresholds] => 
                                                    [created] => 1605480675
                                                    [metadata] => Stripe\StripeObject Object
                                                        (
                                                        )

                                                    [plan] => Stripe\Plan Object
                                                        (
                                                            [id] => Redacted
                                                            [object] => plan
                                                            [active] => 1
                                                            [aggregate_usage] => 
                                                            [amount] => 600
                                                            [amount_decimal] => 600
                                                            [billing_scheme] => per_unit
                                                            [created] => 1605157061
                                                            [currency] => usd
                                                            [interval] => day
                                                            [interval_count] => 30
                                                            [livemode] => 1
                                                            [metadata] => Stripe\StripeObject Object
                                                                (
                                                                    [recurring] => true
                                                                    [recurring_times] => -1
                                                                )

                                                            [nickname] => 
                                                            [product] => Redacted
                                                            [tiers_mode] => 
                                                            [transform_usage] => 
                                                            [trial_period_days] => 30
                                                            [usage_type] => licensed
                                                        )

                                                    [price] => Stripe\StripeObject Object
                                                        (
                                                            [id] => Redacted
                                                            [object] => price
                                                            [active] => 1
                                                            [billing_scheme] => per_unit
                                                            [created] => 1605157061
                                                            [currency] => usd
                                                            [livemode] => 1
                                                            [lookup_key] => 
                                                            [metadata] => Stripe\StripeObject Object
                                                                (
                                                                    [recurring] => true
                                                                    [recurring_times] => -1
                                                                )

                                                            [nickname] => 
                                                            [product] => Redacted
                                                            [recurring] => Stripe\StripeObject Object
                                                                (
                                                                    [aggregate_usage] => 
                                                                    [interval] => day
                                                                    [interval_count] => 30
                                                                    [trial_period_days] => 30
                                                                    [usage_type] => licensed
                                                                )

                                                            [tiers_mode] => 
                                                            [transform_quantity] => 
                                                            [type] => recurring
                                                            [unit_amount] => 600
                                                            [unit_amount_decimal] => 600
                                                        )

                                                    [quantity] => 1
                                                    [subscription] => Redacted
                                                    [tax_rates] => Array
                                                        (
                                                        )

                                                )

                                        )

                                    [has_more] => 
                                    [total_count] => 1
                                    [url] => /v1/subscription_items?subscription=Redacted
                                )

                            [latest_invoice] => Redacted
                            [livemode] => 1
                            [metadata] => Stripe\StripeObject Object
                                (
                                    [tax_info] => {"trial_tax":"0.00","trial_tax_per":"0%","tax":"0.00","tax_per":"0%"}
                                )

                            [next_pending_invoice_item_invoice] => 
                            [pause_collection] => 
                            [pending_invoice_item_interval] => 
                            [pending_setup_intent] => 
                            [pending_update] => 
                            [plan] => Stripe\Plan Object
                                (
                                    [id] => Redacted
                                    [object] => plan
                                    [active] => 1
                                    [aggregate_usage] => 
                                    [amount] => 600
                                    [amount_decimal] => 600
                                    [billing_scheme] => per_unit
                                    [created] => 1605157061
                                    [currency] => usd
                                    [interval] => day
                                    [interval_count] => 30
                                    [livemode] => 1
                                    [metadata] => Stripe\StripeObject Object
                                        (
                                            [recurring] => true
                                            [recurring_times] => -1
                                        )

                                    [nickname] => 
                                    [product] => Redacted
                                    [tiers_mode] => 
                                    [transform_usage] => 
                                    [trial_period_days] => 30
                                    [usage_type] => licensed
                                )

                            [quantity] => 1
                            [schedule] => 
                            [start_date] => 1605480674
                            [status] => canceled
                            [transfer_data] => 
                            [trial_end] => 1608072674
                            [trial_start] => 1605480674
                        )

                )

            [livemode] => 1
            [pending_webhooks] => 1
            [request] => Stripe\StripeObject Object
                (
                    [id] => Redacted
                    [idempotency_key] => 
                )

            [type] => customer.subscription.deleted
        )

    [s2member_log] => Array
        (
            [0] => Ignoring this Webhook/IPN. The event does NOT require any action on the part of s2Member.
        )

)

As you can see in the example, the webhook was ignored by the plugin. It does not hapen on all cases, I cancelled 3 delinquent subscriptions, two were demoted, one (the one above) wasn’t. I hope it helps diagnosing what could be wrong…

s2 recodnized the event and tried to handle it, but if it was ignored it could be because s2 didn’t get the other things it needed…

case 'customer.subscription.deleted': // Customer subscription deletion.
  if(!empty($event->data->object)
  && ($stripe_subscription = $event->data->object) instanceof \Stripe\Subscription
  && ($ipn_signup_vars = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(0, $stripe_subscription->id))
)
{
  $processing = TRUE;

Could you check if those conditions would have been true in that particular case you mention? And if not, why weren’t they true, and should they have been? I would like to see if there’s a way to improve that logic…

Thanks!

1 Like

Hum… I don’t know how to confirm if any of those were missing. I demoted the user manually after I found what happened, so I’d have to wait for the next time it happens. Would I be able to find the information you need somewhere in the logs?

Are you using a different field than the sub id we can edit on wordpress’s user profile, meaning is get_user_ipn_signup_vars = Paid Subscr. ID (from the user profile)?

I ask that because when there’s a problem processing a new subscription I upgrade the user manually and I fill up the fields manually.