Bug: Stripe Subscription payment failing - users not demoted

Thanks for the update.

no - the users are not active anymore on Stripe.

Do you mean the subscription for that user is not active on Stripe anymore?

My guess somehow is that s2member is not reacting to the 4 attemps anymore as paypal only tries 3 times.

s2 doesn’t count the failed payments, it only acts on the event webhooks I mentioned above. Whether the payment fails 2 or 100 times before ending the subscription, is up to Stripe.

Stripe tried 6 times unsuccessfully (over the course of 29 days). Only after the last try they failed the payment finally.

Okay… But the subscription to which that invoice belongs, is still active?

See my screenshots above - the subscription is cancelled. This screenshot is from a user who wrongly did not get demoted (also the webhook shows success)

Full event:

customer.subscription.deleted

10/4/19, 7:24:15 PM

ID

evt_1FPuVnJQmekOBFQg59P2ugWK

Date

10/4/19, 7:24:15 PM

Type

customer.subscription.deleted

Source

Automatic

{
“object”: {
“id”: “sub_6wL0AxFq3zAwIQ”,
“object”: “subscription”,
“application_fee_percent”: null,
“billing”: “charge_automatically”,
“billing_cycle_anchor”: 1473178711,
“billing_thresholds”: null,
“cancel_at”: null,
“cancel_at_period_end”: false,
“canceled_at”: 1570209854,
“collection_method”: “charge_automatically”,
“created”: 1441642711,
“current_period_end”: 1599322711,
“current_period_start”: 1567786711,
“customer”: “cus_6wL0iDwy8p64Z3”,
“days_until_due”: null,
“default_payment_method”: null,
“default_source”: null,
“default_tax_rates”: [
],
“discount”: null,
“ended_at”: 1570209854,
“items”: {
“object”: “list”,
“data”: [
{
“id”: “si_18U1fnJQmekOBFQgAX8NEUkQ”,
“object”: “subscription_item”,
“billing_thresholds”: null,
“created”: 1441642712,
“metadata”: {
},
“plan”: {
“id”: “s2_d894076243d10732d30a2e08307d17b1”,
“object”: “plan”,
“active”: true,
“aggregate_usage”: null,
“amount”: 1300,
“amount_decimal”: “1300”,
“billing_scheme”: “per_unit”,
“created”: 1421149410,
“currency”: “eur”,
“interval”: “day”,
“interval_count”: 365,
“livemode”: true,
“metadata”: {
“recurring”: “true”,
“recurring_times”: “-1”
},
“nickname”: null,
“product”: “prod_BTfeaPxdkk8sCa”,
“tiers”: null,
“tiers_mode”: null,
“transform_usage”: null,
“trial_period_days”: 365,
“usage_type”: “licensed”
},
“quantity”: 1,
“subscription”: “sub_6wL0AxFq3zAwIQ”,
“tax_rates”: [
]
}
],
“has_more”: false,
“total_count”: 1,
“url”: “/v1/subscription_items?subscription=sub_6wL0AxFq3zAwIQ”
},
“latest_invoice”: “in_1FFk8sJQmekOBFQgMJcR7IzU”,
“livemode”: true,
“metadata”: {
“tax_info”: “{“trial_tax”:“0.00”,“trial_tax_per”:“0%”,“tax”:“0.00”,“tax_per”:“0%”}”
},
“pending_setup_intent”: null,
“plan”: {
“id”: “s2_d894076243d10732d30a2e08307d17b1”,
“object”: “plan”,
“active”: true,
“aggregate_usage”: null,
“amount”: 1300,
“amount_decimal”: “1300”,
“billing_scheme”: “per_unit”,
“created”: 1421149410,
“currency”: “eur”,
“interval”: “day”,
“interval_count”: 365,
“livemode”: true,
“metadata”: {
“recurring”: “true”,
“recurring_times”: “-1”
},
“nickname”: null,
“product”: “prod_BTfeaPxdkk8sCa”,
“tiers”: null,
“tiers_mode”: null,
“transform_usage”: null,
“trial_period_days”: 365,
“usage_type”: “licensed”
},
“quantity”: 1,
“schedule”: null,
“start”: 1441642711,
“start_date”: 1441642711,
“status”: “canceled”,
“tax_percent”: null,
“trial_end”: 1473178711,
“trial_start”: 1441642711
}
}

Check your configuration here: https://dashboard.stripe.com/account/billing/automatic

Screenshot_2019-10-08%20Dashboard%20%E2%80%93%20Cristi%C3%A1n%20L%C3%A1vaque%20%E2%80%93%20Stripe%20%5BTest%5D

They should be fine (though a bit different):
I really want to give the customer over 25 days to update his credit card on failed charges - and try the maximum amount of times. Custom is only 4 tries possible, smart can be up to 7 times as I could see in some logs

1 Like

Thanks.

the subscription is cancelled. This screenshot is from a user who wrongly did not get demoted (also the webhook shows success)
Full event:
customer.subscription.deleted

So that subscription’s user did not get demoted? Does his WP profile have the correct subscription ID? That’s how s2 finds the user the webhook is referring to.

In any case, I have tested this in the past days after updating the webhooks integration with Stripe, and when I ended the subscription on Stripe’s side, s2 got the webhook and set the EOT on the user’s account correctly.

Can you reproduce this with a test user subscription with the latest beta I sent you?

I look forward to your update. :slight_smile:

okay - I think I can use the new beta from now on. But I don’t know how to reproduce. I can only wait for another customer to fail his payments (haven’t got that many any more - because I only sold subscriptions via Stripe for 1 year in 2015 - and then stopped after noticing that the demotions did not work).

The profile always still has the correct subscription ID.
I’ll put the Stripe IPN log of all relevant details into a next reply.

sorry - have to attach it zipped to pass Stripe_IPN_log_relevant.zip (16.2 KB)

Create a 50cent/day subscription pro-form, signup a new user for it, and then cancel the subscription over at Stripe. See if you get the * customer.subscription.deleted webhook and if s2 set the EOT for the user.

The profile always still has the correct subscription ID.

Got it.

I’ll put the Stripe IPN log of all relevant details into a next reply.

Thanks, I’ll take a look.

I think I can use the new beta from now on.

Good. I can’t say for sure what happened with the previous integration in this regard, but it’s possible that it’s not an issue anymore with the updated integration.

:slight_smile:

That will not work - as if user actively cancels the subscription - the problem does not happen I think. It only affects those users who’s payments are failing. Active cancelation of subscription by user is correctly demoted.

Also strangely as mentioned - if the user bought the subscription as part of a renewal - the demotion usually works (though not all the time).

Ok…

I’ll see how I can reproduce this…

I set my Stripe test account’s billing options to cancel the subscription as soon as possible on failed payments. We’ll see how it goes.

:slight_smile:

Actually - funny thing or not so funny. I just realised that all members who are not demoted - have the wrong s2member payment notification email being sent (so the user info is incorrect). This also means that for me the bug mentioned in the other topic not only affects paypal button buy now payments - but also all Stripe Subscription payments. Wrong user in the payments notification API email.

I did check that
Paid Subscr. ID:
and
Paid Subscr. CID:

are always correct (checked for 5 not demoted members) - so the ID/CID copied out from the member profile - matched the member and all his payments in Stripe dashboard search.

Now of course as I stopped selling Stripe subscriptions long time ago due to this problem - I have no more logs from the time of account creation.
However usually members who prolonged - are not affected. Member logged in do not see cached pages - so maybe there is some freak caching issue going on. But what kind of cache could affect that the member is not demoted? The visible data in the member profile is all correct if I confirm it via Stripe - still they are not demoted while those members who paid while being logged in are mostly (I think I found some who were not demoted too) correctly demoted. Caching only happens for not logged in visitors.

I’m using WP Fastest Cache currently, but used WP Supercache and others in the past. However at least the email api error has stayed consistently. I also use autoptimize - but that also affects logged in users - so I highly doubt it has any effect. Furthermore I explicitly excluded the membership sites from any caching with WP Fastest Cache and when loading the pages not logged in they don’t seem to be cached either.

Interesting find! Thank you for the update.

Do you have object caching enabled? That sometimes gives random problems. Maybe it’s playing a part here?

It’s curious that there’s an overlap between the wrong user in the payment notifications on signup, and this.

If the sub ID in the user’s profile matches the one in Stripe, then s2 should be able to find the user when it gets the webhook.

I did see one entry in your log a customer.subscription.deleted webhook, with s2’s “ignoring this webhook” note. That could be because it didn’t find the WP user with the subscr ID sub_6wL0AxFq3zAwIQ.

Now that you saw a possible relationship with the other issue, and you seem to have an idea of how to reproduce the other issue, you could try that with the new integration and see if you get this behavior on subscription end.

If the problem is the ID, then even using the cancellation pro-form logged in as the test user, may get the same result as the one cancelled by Stripe for failed payments.

Anyway, I look forward to what you find with the updated integration.

:slight_smile:

was entered correctly for the user in the database. As written in the other thread - the users get created correctly. The sub ID/CID is in all cases correct. I can search for those IDs in the wordpress user search and find the users

And while I do use caching - on my checkout page there is only jss/css minification - no caching. And I’ve never used object caching or server wide caching like Varnish or similar.

1 Like

Gotcha.

How long should it take if a user cancels a stripe subscription - until his account shows an EOT?
(still in paid time).
I also do not know how I could filter for users that actively cancelled a stripe subscription vs not paying and the subscription deleted for missed payment.

I just cancelled the subscription for one user which was created with a wrong s2member api payment notification email. But cannot see anything has happened so far.

I just cancelled the subscription for one user which was created with a wrong s2member api payment notification email.

Can you find the event in s2’s Stripe IPN log?

I also do not know how I could filter for users that actively cancelled a stripe subscription vs not paying and the subscription deleted for missed payment.

They’d be handled the same way, setting the EOT time at the end of the paid term.

Actually stripe IPN ignored - this should not be the case I guess:

LOG ENTRY: Tue Oct 8th, 2019 @ precisely 10:37 pm UTC
PHP v7.3.9-1+ubuntu18.04.1+deb.sury.org+1 :: WordPress v5.2.3 :: s2Member v191007-beta :: s2Member Pro v191007-beta
Memory 9.61 MB :: Real Memory 2.00 MB :: Peak Memory 9.65 MB :: Real Peak Memory 2.00 MB
openmtbmap.org/?s2member_pro_stripe_notify=1
User-Agent: Stripe/1.0 (+https://stripe.com/docs/webhooks)
-------- Function/Caller: ( get_event ) --------
-------- Input vars: ( Tue, 08 Oct 19 22:37:01 +0000 ) --------
Array
(
[event_id] => evt_1FRRIeJQmekOBFQg35tOKOLz
)

-------- Output string/vars: ( Tue, 08 Oct 19 22:37:02 +0000 ) --------
Stripe\Event Object
(
[id] => evt_1FRRIeJQmekOBFQg35tOKOLz
[object] => event
[api_version] => 2018-08-23
[created] => 1570574220
[data] => Stripe\StripeObject Object
(
[object] => Stripe\Subscription Object
(
[id] => sub_6q4J4tpdNFWaoJ
[object] => subscription
[application_fee_percent] =>
[billing] => charge_automatically
[billing_cycle_anchor] => 1471732768
[billing_thresholds] =>
[cancel_at] => 1597876768
[cancel_at_period_end] => 1
[canceled_at] => 1570574220
[collection_method] => charge_automatically
[created] => 1440196768
[current_period_end] => 1597876768
[current_period_start] => 1566340768
[customer] => cus_6q4I8fEG2wZq0F
[days_until_due] =>
[default_payment_method] =>
[default_source] =>
[default_tax_rates] => Array
(
)

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

                                        [plan] => Stripe\Plan Object
                                            (
                                                [id] => s2_d894076243d10732d30a2e08307d17b1
                                                [object] => plan
                                                [active] => 1
                                                [aggregate_usage] => 
                                                [amount] => 1300
                                                [amount_decimal] => 1300
                                                [billing_scheme] => per_unit
                                                [created] => 1421149410
                                                [currency] => eur
                                                [interval] => day
                                                [interval_count] => 365
                                                [livemode] => 1
                                                [metadata] => Stripe\StripeObject Object
                                                    (
                                                        [recurring] => true
                                                        [recurring_times] => -1
                                                    )

                                                [nickname] => 
                                                [product] => prod_BTfeaPxdkk8sCa
                                                [tiers] => 
                                                [tiers_mode] => 
                                                [transform_usage] => 
                                                [trial_period_days] => 365
                                                [usage_type] => licensed
                                            )

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

                                    )

                            )

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

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

                [pending_setup_intent] => 
                [plan] => Stripe\Plan Object
                    (
                        [id] => s2_d894076243d10732d30a2e08307d17b1
                        [object] => plan
                        [active] => 1
                        [aggregate_usage] => 
                        [amount] => 1300
                        [amount_decimal] => 1300
                        [billing_scheme] => per_unit
                        [created] => 1421149410
                        [currency] => eur
                        [interval] => day
                        [interval_count] => 365
                        [livemode] => 1
                        [metadata] => Stripe\StripeObject Object
                            (
                                [recurring] => true
                                [recurring_times] => -1
                            )

                        [nickname] => 
                        [product] => prod_BTfeaPxdkk8sCa
                        [tiers] => 
                        [tiers_mode] => 
                        [transform_usage] => 
                        [trial_period_days] => 365
                        [usage_type] => licensed
                    )

                [quantity] => 1
                [schedule] => 
                [start] => 1570574220
                [start_date] => 1440196768
                [status] => active
                [tax_percent] => 
                [trial_end] => 
                [trial_start] => 
            )

        [previous_attributes] => Stripe\StripeObject Object
            (
                [cancel_at] => 
                [cancel_at_period_end] => 
                [canceled_at] => 
                [start] => 1440196768
                [trial_end] => 1471732768
                [trial_start] => 1440196768
            )

    )

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

[type] => customer.subscription.updated

)

LOG ENTRY: Tue Oct 8th, 2019 @ precisely 10:37 pm UTC
PHP v7.3.9-1+ubuntu18.04.1+deb.sury.org+1 :: WordPress v5.2.3 :: s2Member v191007-beta :: s2Member Pro v191007-beta
Memory 9.66 MB :: Real Memory 2.00 MB :: Peak Memory 9.71 MB :: Real Peak Memory 2.00 MB
openmtbmap.org/?s2member_pro_stripe_notify=1
User-Agent: Stripe/1.0 (+https://stripe.com/docs/webhooks)
Array
(
[event] => Stripe\Event Object
(
[id] => evt_1FRRIeJQmekOBFQg35tOKOLz
[object] => event
[api_version] => 2018-08-23
[created] => 1570574220
[data] => Stripe\StripeObject Object
(
[object] => Stripe\Subscription Object
(
[id] => sub_6q4J4tpdNFWaoJ
[object] => subscription
[application_fee_percent] =>
[billing] => charge_automatically
[billing_cycle_anchor] => 1471732768
[billing_thresholds] =>
[cancel_at] => 1597876768
[cancel_at_period_end] => 1
[canceled_at] => 1570574220
[collection_method] => charge_automatically
[created] => 1440196768
[current_period_end] => 1597876768
[current_period_start] => 1566340768
[customer] => cus_6q4I8fEG2wZq0F
[days_until_due] =>
[default_payment_method] =>
[default_source] =>
[default_tax_rates] => Array
(
)

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

                                            [plan] => Stripe\Plan Object
                                                (
                                                    [id] => s2_d894076243d10732d30a2e08307d17b1
                                                    [object] => plan
                                                    [active] => 1
                                                    [aggregate_usage] => 
                                                    [amount] => 1300
                                                    [amount_decimal] => 1300
                                                    [billing_scheme] => per_unit
                                                    [created] => 1421149410
                                                    [currency] => eur
                                                    [interval] => day
                                                    [interval_count] => 365
                                                    [livemode] => 1
                                                    [metadata] => Stripe\StripeObject Object
                                                        (
                                                            [recurring] => true
                                                            [recurring_times] => -1
                                                        )

                                                    [nickname] => 
                                                    [product] => prod_BTfeaPxdkk8sCa
                                                    [tiers] => 
                                                    [tiers_mode] => 
                                                    [transform_usage] => 
                                                    [trial_period_days] => 365
                                                    [usage_type] => licensed
                                                )

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

                                        )

                                )

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

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

                    [pending_setup_intent] => 
                    [plan] => Stripe\Plan Object
                        (
                            [id] => s2_d894076243d10732d30a2e08307d17b1
                            [object] => plan
                            [active] => 1
                            [aggregate_usage] => 
                            [amount] => 1300
                            [amount_decimal] => 1300
                            [billing_scheme] => per_unit
                            [created] => 1421149410
                            [currency] => eur
                            [interval] => day
                            [interval_count] => 365
                            [livemode] => 1
                            [metadata] => Stripe\StripeObject Object
                                (
                                    [recurring] => true
                                    [recurring_times] => -1
                                )

                            [nickname] => 
                            [product] => prod_BTfeaPxdkk8sCa
                            [tiers] => 
                            [tiers_mode] => 
                            [transform_usage] => 
                            [trial_period_days] => 365
                            [usage_type] => licensed
                        )

                    [quantity] => 1
                    [schedule] => 
                    [start] => 1570574220
                    [start_date] => 1440196768
                    [status] => active
                    [tax_percent] => 
                    [trial_end] => 
                    [trial_start] => 
                )

            [previous_attributes] => Stripe\StripeObject Object
                (
                    [cancel_at] => 
                    [cancel_at_period_end] => 
                    [canceled_at] => 
                    [start] => 1440196768
                    [trial_end] => 1471732768
                    [trial_start] => 1440196768
                )

        )

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

    [type] => customer.subscription.updated
)

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

)

And I noticed something strange when exporting the canceled users via csv file. The current period is shown for 1 year longer than paid:

e.g. payment failed ultimately and subscription deleted - but I have the following entries:
Plan Quantity Interval Amount Status Created (UTC) Start (UTC) Current Period Start (UTC) Current Period End (UTC)
s2_e2c014693f9941122468457209b6912a 1 day 1300 canceled 17/08/2015 06:46 17/08/2015 06:46 16/08/2019 06:46 15/08/2020 06:46

The last successful payment was on the 16.08.2018. User did not cancel actively but payments failed.

Both events are “customer.subscription.updated”, which s2Member doesn’t do anything with.