Intermittently being returned to basket when pressing proceed to payment with error message
Garylanda opened this issue · 18 comments
Reason: When request contains same session or session ID, it process based on last action - as duplicate hostedCheckoutId
Steps to replicate:
Add product to basket and checkout
Place order
Click cancel button from Ingenico payment screen
User returns to basket
Quickly fill checkout details and try place order again
User won't redirected to Ingenico payment screen
User will redirected to basket page, with the same cancel action response
From the above scenario we can see that Ingenico is processing the second request based on response from the first one
See an example requests logs here:
First request:
[2020-02-13 08:47:29] report.INFO: Outgoing request to https://world.preprod.api-ingenico.com (requestId='6c9f1048-3c62-4693-bc1b-6ace630b1e10')
GET /v1/xxxx/hostedcheckouts/bf59a30d-bfc2-4c87-ae6c-c1ea99a15419 HTTP/1.1
Content-Type: application/json
Date: Thu, 13 Feb 2020 08:47:29 GMT
Response:
[2020-02-13 08:47:29] report.INFO: Incoming response from https://world.preprod.api-ingenico.com (requestId='6c9f1048-3c62-4693-bc1b-6ace630b1e10')
HTTP/1.1 200
Date: Thu, 13 Feb 2020 08:47:28 GMT
Second Request:
[2020-02-13 08:48:05] report.INFO: Outgoing request to https://world.preprod.api-ingenico.com (requestId='5ba5b646-0242-48e9-980a-16238a2afa7c')
GET /v1/xxxx/hostedcheckouts/bf59a30d-bfc2-4c87-ae6c-c1ea99a15419 HTTP/1.1
Content-Type: application/json
Date: Thu, 13 Feb 2020 08:48:05 GMT
Authorization: ******** [] []
Response:
[2020-02-13 08:48:05] report.INFO: Incoming response from https://world.preprod.api-ingenico.com (requestId='5ba5b646-0242-48e9-980a-16238a2afa7c')
HTTP/1.1 200
Date: Thu, 13 Feb 2020 08:48:05 GMT
Server: Apache
X-OneAgent-JS-Injection: true
Content-Type: application/json
Set-Cookie: dtCookie=1$3394998C076BB5A2E484F0EFA5FC54F4; Path=/; Domain=.api-ingenico.com
Transfer-Encoding: chunked
{
"status": "CANCELLED_BY_CONSUMER"
}
[] []
Third request:
[2020-02-13 09:02:47] report.INFO: Outgoing request to https://world.preprod.api-ingenico.com (requestId='17fce35e-7a7a-41e6-9d1f-0ab33da8d6cd')
GET /v1/xxxx/hostedcheckouts/bf59a30d-bfc2-4c87-ae6c-c1ea99a15419 HTTP/1.1
Content-Type: application/json
Date: Thu, 13 Feb 2020 09:02:47 GMT
Response:
[2020-02-13 09:02:48] report.INFO: Incoming response from https://world.preprod.api-ingenico.com (requestId='17fce35e-7a7a-41e6-9d1f-0ab33da8d6cd')
HTTP/1.1 200
Date: Thu, 13 Feb 2020 09:02:47 GMT
Server: Apache
X-OneAgent-JS-Injection: true
Content-Type: application/json
Set-Cookie: dtCookie=26$6A05B09FAEE5E7C7DC5B250BD51BB83B; Path=/; Domain=.api-ingenico.com
Transfer-Encoding: chunked
{
"status": "CANCELLED_BY_CONSUMER"
}
[] []
We have clicked cancel button only for first request, second and third processed without clicking the cancel button.
From the above case we can see that if request is same, then it will return the same response from server
GET /v1/xxxx/hostedcheckouts/bf59a30d-bfc2-4c87-ae6c-c1ea99a15419
If I wait for sometime to re-order then I can see request is changing and it is processing correctly.
[2020-02-13 09:36:41] report.INFO: Outgoing request to https://world.preprod.api-ingenico.com (requestId='a50d8d0a-3f35-426e-963d-5d8de6124639')
GET /v1/xxxx/hostedcheckouts/a555253a-7223-4d24-8b33-fcc10a180f8f HTTP/1.1
@rikvanthof / @kanduvisla Do you have an update on the above?
Hi @Garylanda , could you provide us with more information on how we can reproduce this issue?
- What was the used payment product?
- Country / Currency information?
- Was it a registered customer or a guest checkout?
- What's the Magento version?
- What's the module version?
We've created an internal ticket for this.
Hi @Garylanda , we've created an internal ticket for this. The first step for us is to reproduce the issue following the instructions you provided. To help us with this, could you please answer the questions in my previous comment? Thanks in advance.
Hi @Garylanda ,
I've tried to reproduce this issue in Magento CE 2.3.4 with the latest version of the module (2.1.2, will be released very soon), and I can't seem to reproduce the issue.
The scenario I tried:
- Checkout Type: Payment products and input fields on Hosted Checkout
- Place order with VISA > Cancel > Retry to place the order with VISA : I got redirected to the payment screen and was able to successfully pay my order.
- Second attempt I placed an order with Mastercard > Cancel > JCB > Cancel > VISA : payment successful.
Could you check if you've got the latest version of the module and / or Magento and see if that resolves your issue?
Hi @kanduvisla
We have tried this on both 2.0.0 and 2.1.1 versions and replicated issue with both cases.
Have you checked request/response in the task description? We can see duplicate {hostedCheckoutId} there and I think that's causing problem here
Hi, I have tried to reproduce the issues.
For every order attempt a new POST is send with a new Hostedcheckout ID in the response.
Your examples are all related to the GET and I see no new POST requests when moving from the shopping cart.
Are you using webhooks ?
Are you using guest or registered checkout ?
Which payment options do you cancel ?
From our log files, we can see that POST requests.
Are you using webhooks ? NO
Are you using guest or registered checkout ? Guest checkout
Which payment options do you cancel ? Its hosted checkout payment, and from payment screen we clicked on cancel button.
Hi @jitheesh-lumi , we're trying to reproduce the issue on the latest version of the module (2.1.2
, released earlier today), but with no success.
We're trying:
- Capture mode: Delayed settlement
- Guest customer
- Checkout type: Payment products and input fields on Hosted Checkout
However, just as @Ingenico-Shoppingcarts said: in our logs file we see that on the second attempt (the POST to /v1/xxxxx/hostedcheckouts
) returns a new hostedCheckoutId
which is then again used in all subsequent requests.
Could you please provide us with more information on how we could reproduce this? Things like:
- Currency / Country
- Server information (PHP version, what kind of caching is used, etc.)
- Browser / OS used
- Magento version
Also, @Ingenico-Shoppingcarts is also right that you should see two POST-requests to /v1/xxxxx/hostedcheckouts
in your logs (since POST is to create a new HC, and GET is to fetch the status of an existing checkout).
Currency / Country : GBP / UK
Server information (PHP version, what kind of caching is used, etc.) PHP 7.2, Varnish
Browser / OS used : Chrome/Safari, Linux & Mac
Magento version: Magento EE 2.3.3
Capture mode: Direct capture
See detailed logs for each transaction state, here https://docs.google.com/document/d/19q2GrIdKLKLqfWd8DcqkCbpvN3QL7CfXF5KJ-WIBqWE/edit?usp=sharing
Please let us know if you find anything wrong here
Hi @Jitheesh , I'm missing an essential part in your log file: as soon as you came back and try to place the order again there should be a new POST
to /v1/xxxx/hostedcheckouts HTTP/1.1
. But that's unclear from your log now, because it ends with "repeat above step 3 times".
Each POST
to /v1/xxxx/hostedcheckouts HTTP/1.1
should return in a new hostedCheckoutId
which can be seen in the return value.
Could you please answer me the following questions?
- If I understand your problem correctly, the current issue is that in your case there is no new POST-request, but instead it creates an additional GET-request? Is this correct?
- You mention that this only happens if you try to re-order quickly, but if you wait a while then it works. I'm trying to click through the checkout as quick as possible, but I can't reproduce the issue. Could you please explain what "quick" is and and how you long you (at least) have to wait for a successful order?
- Also: are you using any extensions / modifications to the checkout that might be causing this as well? Or are you using Magento 2's out-of-the-box checkout?
Hi @kanduvisla
I've added all log entries for the steps I described there. I can only see one POST request and there is no hostedCheckoutId in its return value.
PS: For above test we are not completing payment, we are cancelling order from payment screen
- If I understand your problem correctly, the current issue is that in your case there is no new POST-request, but instead it creates an additional GET-request? Is this correct?
Yes there is only one POST request, there is no POST request for getting hostcheckoutId
- You mention that this only happens if you try to re-order quickly, but if you wait a while then it works. I'm trying to click through the checkout as quick as possible, but I can't reproduce the issue. Could you please explain what "quick" is and and how you long you (at least) have to wait for a successful order?
I'm completing order within 30 sec, using extensions to fill checkout fields. As we said it is not happening for all cases.
- Also: are you using any extensions / modifications to the checkout that might be causing this as well? Or are you using Magento 2's out-of-the-box checkout?
Yes we are using Onestep checkout along with GFS shipping module
Hi @Jitheesh ,
I'm confused right now.
In the original issue you state:
Add product to basket and checkout
Place order
Click cancel button from Ingenico payment screen
User returns to basket
Quickly fill checkout details and try place order again
User won't redirected to Ingenico payment screen
User will redirected to basket page, with the same cancel action response
But now you're saying you're cancelling order from the payment screen. So you do manage to get to the payment screen for a second time?
Also, you say you don't see a hostedCheckoutId
. But if I look at your log: the POST
request is done in point 7: POST /v1/xxxx/hostedcheckouts HTTP/1.1
The return value of this request is:
{
"RETURNMAC": "2a77ac74-6e74-4c11-9d5f-e6d504abfeb3",
"hostedCheckoutId": "c3819d14-17fb-4a39-85c1-f87c9d480da1",
"merchantReference": "demo2000001199",
"partialRedirectUrl": "pay1.preprod.secured-by-ingenico.com/checkout/xxxx-ced7614efd594585861d04cc0600558f:c3819d14-17fb-4a39-85c1-f87c9d480da1:774dabe7c1944ad99e0812e4246fde48"
}
Which clearly has a hostedCheckoutId
and a partialRedirectUrl
.
Hi @Jitheesh ,
- Could you please provide exactly which OneStep checkout you are using? Since there are various one step checkout modules out there.
- Could you please check if this problem also exists if you're using the default Magento Checkout?
Hi @kanduvisla
I've shared a screen recording with you. Please check.
Sorry for the confusion, What I'm saying is this issue is happening when user clicks cancel button from Ingenico payment screen.
After clicking cancel button they redirected to basket page - That is correct.
Then user fills checkout again and click place order button from checkout page. After clicking place order button, user should redirected to Ingenico payment screen.
But they didn't.
User redirected back to basket page.
We are using Onestepcheckout_Iosc
Hi @Jitheesh @kanduvisla,
We intend to look for a solution to work correctly with Magento 2 and where possible support 3rd party modules.
Trying to reproduce the flow you shared on a regular Magento 2 install has not resulted in the same outcome. A reloading of a closed Hosted sessions.
When a consumer cancels an attempt on the Hosted Checkout, the session is closed and has the value:
{ "status": "CANCELLED_BY_CONSUMER" }
When reloading the request it is being redirected to the shopping cart.
To know if we need to make a change to our module we need to know how it interacts with the 3rd party module. Have you also raised a ticket with the provided of the onestepcheckout if they store the session on redirect URL.
Hi @Jitheesh ,
The issue you describe is being caused by a 3rd party module. Support for 3rd party modules is something on our roadmap, but it's not our priority at the moment. Given that the issue only happens in combination with the Onestepcheckout_Iosc
module I would suggest to raise a support question there.
For now I am closing this issue. Feel free to reopen the issue if it happens in the default Magento checkout as well.
Hi
I'm from Onestepcheckout_Iosc module support and current tests done by our customer show that if under load and moved fast enough the issue hits against redis session locking where it fails to update the session (cause its locked) and thus receive outdated state.
Issue is randomly replicable by stressing the magento2 installation and automating the payment gateway and order placement loop so that it acts fast enough for this issue to occur. Fast enough means hitting the session lock timeout timeframe with full to gateway back and to gateway redirection loop.
PS: This will probably happen default checkout flow or any other checkout customisation under higher load and concurrency that puts pressure to redis setup