Hi all,
I'm looking into a puzzling bug we've had on a number of client websites recently and was wondering if anyone had any insight.
It's a classic case of orders not being properly taken out of Missing Orders upon payment callback, and looks to be something to do with the user's session expiring while they are on the payment page.
It usually goes more or less along these lines:
1) OpenCart sets the order_id in $this->session->data before passing control over to the payment extension.
2) The user's OpenCart session somehow expires or otherwise "gets reset" while they're on the payment page.
3) Pretty much every payment extension uses $this->session->data['order_id'] with $this->model_checkout_order->addOrderHistory to confirm an order in the callback routine. If this isn't found, addOrderHistory is called with an empty order_id, resulting in a Missing Order.
4) Chaos ensues!
I've verified this with extensive logging code added to the payment ext.s to detail every step of the checkout process. If it finds no order_id in $this->session->data in the callback function it prints the entire session data array, which is empty except for "language" and "currency", suggesting a new blank session.
Also several instances of "undefined index: order_id" in the OC error.log, with the filename and line number corresponding with an addOrderHistory($this->session->data['order_id'], ...) line in the payment extension controller.
We've seen this problem on sites running OC versions 1.5 and 2.x which uses PHP's built-in session wrangler. Version 3 seems unaffected since it uses the database for session management (backporting this to OC1+2 might be a good idea). Each site we've encountered this issue on uses a different payment provider, so it's not limited to one extension.
Sometimes it's possible to edit the relevant bits of the extension so it doesn't rely on session->data to put through an order, but usually this is impossible without e.g. anybody being able to hit the relevant URL and put through an order without paying (not enough data sent from the payment gateway in the callback to verify it's a legit request!). I've also cranked up the session lifetime on servers of affected sites but I'm not confident this will clear up the issue for good.
I was wondering if anyone's seen anything similar, missing orders or other glitches caused by sessions prematurely expiring? We've suddenly seen this cropping up a lot in the last couple of months, so I'm wondering if it's a recent change in how web browsers handle cookies, or a recent new version of PHP/apache/whatever that has subtly altered how sessions are handled and gc'd on the server side.
Thanks for reading, any insight or comments appreciated.
It looks very much like the new cookie SameSite behaviour implemented in modern web browsers where Lax is the new default.
https://www.chromium.org/updates/same-site
With the new default of Lax, any payment gateway returning to your site whis a POST will not have the session cookie and therefore the session will be lost. The best way around this is to change how the payment module works (such as https://github.com/opencart/opencart/pull/8072), but as you have found this is not always possible.
Next option would be to set the session cookie to have the SameSite=None and Secure attributes. This would however lose the security advantages on the new behaviour.
For OpenCart 1.5.x, if you are using PHP 7.3+ then set the following in your php,ini or user.ini.
For OpenCart 2.x you would also need to make the following changes to setting of the session cookie.
viewtopic.php?f=190&t=216579&start=20#p782590
For OpenCart 3.x it would be as follows.
viewtopic.php?f=202&t=219633#p797082
For PHP 7.2 and below you would have to inject the SameSite attributes into one of the other attributes, as done in this example.
viewtopic.php?f=202&t=219633#p797043
Your 1.5.x sites would have to use HTTPS everywhere.
There are also more changes coming (Chrome 88?) which could affect site that aren't HTTPS everywhere or are badly configured.
https://www.chromestatus.com/feature/5096179480133632
https://www.chromium.org/updates/same-site
With the new default of Lax, any payment gateway returning to your site whis a POST will not have the session cookie and therefore the session will be lost. The best way around this is to change how the payment module works (such as https://github.com/opencart/opencart/pull/8072), but as you have found this is not always possible.
Next option would be to set the session cookie to have the SameSite=None and Secure attributes. This would however lose the security advantages on the new behaviour.
For OpenCart 1.5.x, if you are using PHP 7.3+ then set the following in your php,ini or user.ini.
Code: Select all
session.cookie_secure=On
session.cookie_samesite="None"
viewtopic.php?f=190&t=216579&start=20#p782590
For OpenCart 3.x it would be as follows.
viewtopic.php?f=202&t=219633#p797082
For PHP 7.2 and below you would have to inject the SameSite attributes into one of the other attributes, as done in this example.
viewtopic.php?f=202&t=219633#p797043
Your 1.5.x sites would have to use HTTPS everywhere.
There are also more changes coming (Chrome 88?) which could affect site that aren't HTTPS everywhere or are badly configured.
https://www.chromestatus.com/feature/5096179480133632
Thanks very much for the above, ADD Creative as we've seen this issue cropping up recently on a few sites.
UK OpenCart Hosting | OpenCart Audits | OpenCart Support - please email info@antropy.co.uk
Many thanks for your reply - we've applied those fixes to a couple of OpenCart 2.x websites and haven't seen any missing order issues since, so it looks like this was it! This has been a real head-scratcher recently, so thanks again!
We've packaged this fix as an extension for OpenCart 2.x in case anyone else is experiencing the same problem on their store:
https://www.opencart.com/index.php?rout ... n_id=40446
We've packaged this fix as an extension for OpenCart 2.x in case anyone else is experiencing the same problem on their store:
https://www.opencart.com/index.php?rout ... n_id=40446
THANKS! I've been scratching my head with this issue for months...
I'll see if I can figure out a way around this for our specific situation...
I'll see if I can figure out a way around this for our specific situation...
ADD Creative wrote: ↑Wed Sep 23, 2020 1:05 amIt looks very much like the new cookie SameSite behaviour implemented in modern web browsers where Lax is the new default.
https://www.chromium.org/updates/same-site
With the new default of Lax, any payment gateway returning to your site whis a POST will not have the session cookie and therefore the session will be lost. The best way around this is to change how the payment module works (such as https://github.com/opencart/opencart/pull/8072), but as you have found this is not always possible.
Next option would be to set the session cookie to have the SameSite=None and Secure attributes. This would however lose the security advantages on the new behaviour.
For OpenCart 1.5.x, if you are using PHP 7.3+ then set the following in your php,ini or user.ini.For OpenCart 2.x you would also need to make the following changes to setting of the session cookie.Code: Select all
session.cookie_secure=On session.cookie_samesite="None"
viewtopic.php?f=190&t=216579&start=20#p782590
For OpenCart 3.x it would be as follows.
viewtopic.php?f=202&t=219633#p797082
For PHP 7.2 and below you would have to inject the SameSite attributes into one of the other attributes, as done in this example.
viewtopic.php?f=202&t=219633#p797043
Your 1.5.x sites would have to use HTTPS everywhere.
There are also more changes coming (Chrome 88?) which could affect site that aren't HTTPS everywhere or are badly configured.
https://www.chromestatus.com/feature/5096179480133632
Who is online
Users browsing this forum: No registered users and 54 guests