Canceled membership access issue

Using Membership 2 with Stripe gateway, cancelled membership still has access to protected pages. Although subscription is successfully marked as cancelled from Stripe.

I also noticed multiple instances of absint(...) being used in that same class-ms-gateway-stripeplan.php(Line 274 and 316) that end up calculating an incorrect amount. The final charge for the client is different than what has been set in the plugin.
Using ceil(abs(...)) might be a better solution.

  • Lindeni Mahlalela

    Hello David @ BBS

    I hope you are doing great today, thank you for your patience while we were still looking into this issue, I hope we resolve it soon.

    I have read the chat transcripts and came to know that you have already tried the fix related to the newly updated Stripe API but still you were having problems after that. However, I have tried to access the website using the web test user and found that I get to the protected content page.

    I also confirmed on the admin side that the user has an overdue invoice as from 29 March and their subscription status is set to Expired. So, the web user has an overdue payment, their subscription is expired and hence they have no access to the content in the "/find-a-sitter" page. This is the expected behaviour of Membership 2, this makes me wonder if I have missed something here or the issue has been resolved regarding cancelled memberships having access to the content. Please let me know if I have missed anything here.

    I also noticed multiple instances of absint(...) being used in that same class-ms-gateway-stripeplan.php(Line 274 and 316) that end up calculating an incorrect amount.

    With regards to the use of absint() function in the code, it is used when calculating the amount to be charged. Stripe requires the amount to be whole number like 999 instead of 9.99 so this means if you have a price of 4.99 on your website, the plugin will convert that to 499 before sending it to Stripe. Applying ceil in the number 9.99 will make it a 10 which is mostly undesirable, let me try to explain:

    Consider you have a subscription whose regular price is $4.99 then you offer a 12% coupon then:

    Discount is: 0.5988 (0.60)
    Customer Pays: 4.3912 (4.39)

    The numbers in brackets are what the customer is expecting to pay, that is rounded to two digits after the decimal point.

    But since Stripe expects the number to be whole multiples of 100 then we simply multiply them by 100 and they become:

    Discount is: 59.88 (59)
    Customer Pays: 439.12 (439)

    The numbers in brackets are what is expected by stripe, especially the 439 which will be sent to Stripe for initial payment. So the issue is that after multiplying by 100 we get some cents after the decimal point and if we use ceil() on those cents they become a full currency unit, so with the use of ceil(), the number will be like so:

    Final Discounted Price = ceil( $4.99 -12% ) = ceil ( absint( 4.3912 x 100 ) ) = ceil ( absint( 439.12 ) ) = 440 = $4.40

    Coupon Off = ceil ( absint( 0.5988 x 100 ) ) = ceil ( absint( 59.88 ) ) = 59.88

    Compared to the current:
    Final Discounted Price = $4.99 -12% = 4.3912 x 100 = 439.12 = 439 = $4.39

    The main difference is that 'absint()' returns a non-negative integer of an expression which means it simply drops everything that comes after the decimal point while ceil() rounds up the number to the nearest integer.

    This means the subscriber/customer pays more than the discounted price when we use ceil() function. This may seem small but consider a discount that ends up being $5.1, with 'ceil' that becomes $6 and the plugin will send 600 to Stripe while with absint it is still 5.1 and the plugin will send it to Stripe as 510 which is more desirable than 600 which will be considered too much by the subscribers. Rounding up after discounting defeats the purpose of a discount if you will end up rounding the numbers up.

    Using ceil(abs(...)) might be a better solution.

    Maybe this is right but the issue is that abs() is already used inside absint() and with the use of only abs() then the number will be sent to stripe as 59.88 which is in the wrong format aa Stripe does not expect the decimal points. This is one reason the number is converted to an integer.

    Also in a case where from $6 the amount off is $0.1, ceil makes it become $1 which is more than the actual discount.

    I hope this explanation makes sense as to why the absint is used instead of ceil. With regard to the cancelled subscriptions still having access, please let us know if we have missed something and we will be happy to help in any way possible.

    Have a nice day.
    Lindeni

  • David @ BBS

    HI Lindeni!

    Thanks for the detailed reply and explanation. Definitely appreciate that. Yes from a math perspective all of that makes sense. However when I was testing different recurring payments, there was some instance where the amount charged/displayed wasn't correct. I do remember that the whole idea was that the math just wasn't calculating things correctly and rather than being charged say $9.99, clients were being charged $9.98. (or something like that). I found this ticket and implemented the suggestion within (ceil(abs(...))) which seemed to fix it. After upgrading to Membership 1.1.3 my modifications are of course gone and we're back at using "absint(...)" everywhere. I did a bunch of tests with different fees for the memberships but can't seem to replicate the exact issue as I can't remember the exact amount that was causing this behavior in the first place. Did I mention it in my chat? Is it in the chat log somewhere?

    As for retaining access to protected content, one of your colleagues has already been looking into that and we're testing it as we speak:
    https://premium.wpmudev.org/forums/topic/stripe-api-upgrade-issues#post-1311223
    So please put on hold looking into that for the time being. Will update you once we have a result.

    Thanks!
    David

  • Dimitris

    Hey there David @ BBS,

    hope you're doing good today! :slight_smile:

    I did a bunch of tests with different fees for the memberships but can't seem to replicate the exact issue as I can't remember the exact amount that was causing this behavior in the first place. Did I mention it in my chat? Is it in the chat log somewhere?

    I'm forwarding you the complete chat transcript into your WPMUDEV email address, to be sure about it.

    Please keep us posted here, once you complete your tests!

    Warm regards,
    Dimitris

  • David @ BBS

    Checked the transcript. Doesn't look like I specified what the exact amount was. So don't know now how I got to that error. Will be on the lookout should I find any discrepancies between the expected and charged amount. Will let you know if it pops up again...

    As for the protected access issue on cancellations, just posted an update to the tests I just ran. Feel free to chime in there:
    https://premium.wpmudev.org/forums/topic/stripe-api-upgrade-issues?replies=11#post-1312780

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.