Stripe Last Payment Information not Up to Date

Hi! I periodically check for problems and I noticed that many stripe payments aren’t showing up when I download the user list with their respective last payment dates, then I am forced to check them manually, one by one.

Stripe shows the webhook correctly and the status of the transmission is 200 OK.

The user information is also accurate (cus and sub codes match).

Anybody else with the same issue?

1 Like

Hi, Yes im having this issue too - stripe is not updating my membership (DAP). Really frustrating!

1 Like

Hi @clavaque! Any chance you might fix this?

Whenever I run my audits I have to check my Stripe subscriptions one by one, manually, because your plugin isn’t updating the last successful payment date for my Stripe users (or at least a VERY large number of them). :grimacing:

You may have another problem. I had this as long as there was a broken user with domain in the rights field. Since I fixed that user it’s been all right.

Interesting. What do you mean with “domain” in the “rights” field? I don’t think I have such a thing.

I had it by manually creating a user by mistake. Your website domain one field to high in the user profile. Export all users and check.

I’m also not sure I understand this, could you elaborate? Do you mean the WordPress (not s2) user profile field “website”?

What do you mean by “in the rights field” and “one field to high”? Did you mean “in the right field” and “one field too high”?

You say it’s many, so it’s not all. Do you find something in common between the ones that do get updated, or the ones that don’t?

Which is the last payment time that shows for the user that doesn’t reflect the last one that came in? Is it one behind, or several, or does it only show the one when the subscription started? Is this consistent for all users that have the issue?

While we figure this out, could you please keep logging enabled? Then when you get a new payment from a user, check the related entries in the logs, and check the user’s payment times.

If the payment was not updated, can you find the webhook in Stripe and resend it to see if the payment time gets updated then?

You can also enable debug mode in wordpress, so that if there’s an error when receiving the webhook and trying to update the payment times, it may be written in a log on your server that we can then look at for hints.

But I’m very curious about what Felix said, and want to understand that better too, so looking forward to his clarification.


1 Like

Hi! I just double checked and only some present the issue. I turned logging back on to track it, but I remember the site was getting the API Calls, s2Member was recognizing them but for some reason not acting on them.

I notice the “Custom Value” field for some users are “|1” instead of “”. Not sure why, but this doesn’t seem to interfere with the last payment date, since I have ones with the pipe up to date as well as some not up to date.

Custom capabilities aren’t interfering. Paid Subscr. Gateway is correct and the same for all (“stripe”).

I can’t see the CID using the old format and the new format even using “read friendly” is just unfriendly to quickly process and would take me too long.

I just re-sent one webhook for invoice payment succeeded, didn’t work. Status is always ok but last payment wasn’t update in the database.

I sent you more details privately.

The custom domain ended up in the CID value field, if that happens on a single user the whole stripe integration will break down like you described (same if it is in the Subscriber ID field). Maybe also if in the Coupon Code or Custom Capabilities field.
Basically if your domain ends up in any field but the custom domain one - the integration will break.


This is a glitch if this is the case. I have a few users I use that have my url in the website field (WordPress field) and this should not break things.

I also noticed that the issue only applies to some users, not all, but I can’t find anything different in common with the affected accounts.

I know the plugin is ignoring the IPN notification because it shows in the log it won’t do anything. I sent a private message to @clavaque with details.

Thanks for the extra details. I see…

For the log to get the “ignoring this” line, although the event is one that s2 would normally take action on, it means that this conditional did not compute as true:

							   && ($stripe_invoice = $event->data->object) instanceof \Stripe\Invoice
							   && !empty($stripe_invoice->customer) && !empty($stripe_invoice->subscription)
							   && ($stripe_invoice_total = number_format(c_ws_plugin__s2member_pro_stripe_utilities::cents_to_dollar_amount($stripe_invoice->total, $stripe_invoice->currency), 2, '.', '')) > 0
							   && is_object($stripe_subscription = c_ws_plugin__s2member_pro_stripe_utilities::get_customer_subscription($stripe_invoice->customer, $stripe_invoice->subscription))
							   // Ignore webhook for on-session payment, only act on off-session payments.
							   && ((time() - $stripe_subscription->created) > (12 * 60 * 60))
							   && ($ipn_signup_vars = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(0, $stripe_subscription->id))

So it’d be a matter of trying those one by one in a tests page on your site, with PHP execution enabled, and see where it fails. Of course you’ll need to provide the data as part of the test code. Or you could add some stuff to that in the original s2 file, so that it outputs something that gives you a clue about where it fails. s2member-pro/src/includes/classes/gateways/stripe/


1 Like

I don’t know exactly what to do here.

I am wondering, when a payment fails I set up an EOT manually because the plugin fails to demote while the user is delinquent. If a late payment happens I reupgrade manually and I copy and paste the sub and user id’s from Stripe manually. Is there any hidden field missing from that user example I sent you?

Oh, and I don’t know PHP sorry (I can make sense of the logic but I can’t test it out anywhere because I don’t know how) . :grimacing:

Hmm… Okay, here’s something I’d try:

In the file I mentioned (make a backup copy of the original first): s2member-pro/src/includes/classes/gateways/stripe/

Look for this line:

						case 'invoice.payment_succeeded': // Subscription payments.

And add after it:

$stripe['s2member_log'][] = '!empty($event->data->object) = ' . !empty($event->data->object);
$stripe['s2member_log'][] = '($stripe_invoice = $event->data->object) instanceof \Stripe\Invoice = ' . (($stripe_invoice = $event->data->object) instanceof \Stripe\Invoice);
$stripe['s2member_log'][] = '!empty($stripe_invoice->customer) = ' . !empty($stripe_invoice->customer);
$stripe['s2member_log'][] = '!empty($stripe_invoice->subscription) = ' . !empty($stripe_invoice->subscription);
$stripe['s2member_log'][] = '($stripe_invoice_total = number_format(c_ws_plugin__s2member_pro_stripe_utilities::cents_to_dollar_amount($stripe_invoice->total, $stripe_invoice->currency), 2, ".", "")) > 0 = ' . (($stripe_invoice_total = number_format(c_ws_plugin__s2member_pro_stripe_utilities::cents_to_dollar_amount($stripe_invoice->total, $stripe_invoice->currency), 2, '.', '')) > 0);
$stripe['s2member_log'][] = 'is_object($stripe_subscription = c_ws_plugin__s2member_pro_stripe_utilities::get_customer_subscription($stripe_invoice->customer, $stripe_invoice->subscription)) = ' . is_object($stripe_subscription = c_ws_plugin__s2member_pro_stripe_utilities::get_customer_subscription($stripe_invoice->customer, $stripe_invoice->subscription));
$stripe['s2member_log'][] = '((time() - $stripe_subscription->created) > (12 * 60 * 60)) = ' . ((time() - $stripe_subscription->created) > (12 * 60 * 60));
$stripe['s2member_log'][] = '($ipn_signup_vars = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(0, $stripe_subscription->id)) = ' . ($ipn_signup_vars = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(0, $stripe_subscription->id));

Save, upload to your site to replace the original, resend the webhook, and look for the new entry in s2’s stripe-ipn log.


1 Like

I see. Yeah, if the data ends up in the wrong field, then s2 won’t find it, and won’t get to the part where it acts on the webhook as it should.

I don’t think it’d be the field of a single user affecting every user, though… Was it a single user that had it wrong, or did you mean a single field was wrong but for all users?


1 Like

Thanks! I will test it out when I turn my computer on later today after getting up etc.

I meant if the issue would be affecting users I reupgraded in WordPress manually by editing the fields cus and sub ID with stripe information manually as the plugin does not have routines to demote on payment fails and restores on late payments successfully happening, so I have to do it manually because I don’t want to cancel a subscription on the payment processor (so it continues collection) but I want access removed for as long as payment is overdue. I wonder if the affected users are part of this group. I will look into it as well :slight_smile:

1 Like

It will affect all users created after the first one where this happens. No the website field is not affected, but surely you have exactly this problem llike me once

1 Like

Thanks! I just did what you said (get error 500 on Stripe’s end, though, with your modification on, without it it works normally 200 OK)

I sent you the log you mention after the suggested via private message. s2Member keeps ignoring it.

I manually checked a few users and it seems that most, if not all of them, were previously paying via PayPal or had their subscription modified or had EOT due to lack of payment (I set EOT to “now” when it happens so they’re demoted manually, then I “reupgrade” them manually by adjusting their profile level, their gateway, their Subscription ID and CID fields and Custom Capabilities).

Perhaps there’s some sort of hidden field that your plugin processes internally when it creates a subscription that’s lost on EOT, therefore manually upgraded / subscribed users wouldn’t “match” somehow when a user is manually reupgraded or when a user modifies their subscription. :thinking:

Please let me know what to do next and thanks again! :innocent:

My CID is fine for all paying subscribers. Or I have Stripe, PayPal or empty values (Patreon and manually paid subscriptions, for example). No dots or symbols or domains there.

I am not going to check 10 thousand records for my free users, sorry.

Run a database script or export all of them. Actually if you export all you should find the user easily, in front all will be okay, behind all broken.

I had the same problem that users would not expire if subscription cancelled or no more payment. Fixing that user was all it took (well actually I had two as that error happened to me twice while manually creating users).

I don’t know what you mean with “easy”.

If I export readable I don’t see the CID because it’s not exported.

If I export “reimportable” it’s awful to read and I can’t just open with excel and sort / filter by CID either since the information is all mixed up.

I don’t think my problem is this though, since all users would be broken, but only certain users are, instead. We need to figure out what’s different between a good and a bad user. I hope Christian sees something on my test results (I sent him the logs privately) that may diagnose the issue. :thinking:

Thanks anyway! :hugs: