Kryptronic Software Support Forum

You are viewing this forum as a guest. Login to an existing account, or create a new account, to reply to topics and to create new topics.

#1 07-19-2022 02:16:36

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Order Number Regeneration for Sagepay Form

Hi Nick
Re "Added logic to the SagePay (Protx) – Payment Form processing gateway to trigger order number regeneration if the back button is used to return to checkout from SagePay. This combats a known issue with SagePay when the back button is used which is due to in their system’s session handling logic."

Can you confirm the intended way this should work.

If I proceed to Sagepay, click the back button and then change the total amount(change shipping method or add additional item), I still get a sagepay error.
The only way to force the function docheckoutron() to run is by refreshing any page on my site. Whilst this is a massive improvement as it is easy to talk customers through the issue, shouldn't function docheckoutron() run without the need for a physical refresh??

If I click Back on Sagepay, I do return to /CheckoutNew


Rob

Offline

 

#2 07-19-2022 08:07:25

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

If the payment method is configured so that order numbers should be regenerated upon back navigation (Sage is the only one like this), the following is added to Checkout, and executed when the payment form is submitted:

Code:

$js_docready  = 'jQuery(\'#PAYMENT\').submit(function(){';
$js_docready .= 'if (window.history && window.history.pushState) {window.history.pushState(\'forward\', null, \'' . $this->link_namespace('ecom','checkoutron') . '\');}';
$js_docready .= '});';

This uses JavaScript to alter the browser history and replace the entry for the current checkout page with a checkout page which regenerates the order number when loaded.  The only way I could see hitting that namespace wouldn't regenerate an order number is if you accessed it multiple times (checkout -> sage -> back to checkout -> sage -> back to checkout) and your browser somehow cached it (which it shouldn't).

shouldn't function docheckoutron() run without the need for a physical refresh

It should regenerate an order number every time.  If it isn't, please try this.  Edit {private}/apps/ecom/ECOM/includes/olpform.php and at the bottom of the file, where you see the code I referenced above, change the link_namespace() function call to:

Code:

$this->link_namespace('ecom','checkoutron',array('randomkey' => $this->random_key(10)))

That will append a random key to the URL, and should defeat any cache issues and force a browser reload.  Please try this and report back to let me know if that helps.  If it does, we'll add it to the next update.


Nick Hendler

Offline

 

#3 07-19-2022 09:58:51

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

Hi Nick

The randomkey didn't help.

I don't think it is a cache issue as I can delete cache, navigate around website before returning to checkout page, and still a new order number isn't generated.

The only way I can generate new order number is by manual refresh on checkout page.
If I refresh on shopping cart page and then return to checkout, order number isn't regenerated.

Can history.pushState actually refresh the page??

When I submit payment form, window.history.pushState(\'forward\', null, \'' . $this->link_namespace('ecom','checkoutron') . '\'); definitely runs.
Not sure if we need to delay the form submit so checkoutron can regenerate order number, update DB and update the $crypt which is passed to sagepay.
At the moment, I can't see how the $crypt is being updated before the form is submitted.

I will keep looking,


Rob

Offline

 

#4 07-19-2022 16:38:37

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

The marker is set for the regeneration of the order number when the docheckoutron URL/namespace is accessed.  So when checkout loads and the payment form is generated, a new order number is created and used.

The namespace ecom.checkoutron points to ECOM_Checkout::docheckoutron().  The docheckoutron() function in ECOM_Checkout sets the 'ecom.checkout_regenordnum' global, which forces regenerating an order number, then runs docheckoutfn() which restarts checkout.  If that global is set, the order number will be regenerated (see docheckout() and writeorder() in the same class to confirm).  If that namespace is being hit, that global is being set.

Perhaps you can test further by editing {private}/apps/ecom/ECOM_Checkout/ECOM_Checkout.php.  In the docheckoutron() print something to the screen, or send yourself a mail, to know that namespace is loading.  Then run your test and see if it is.  I'm thinking your back button click is returning the initial checkout page you were on, and not the entry from your history.  This may confirm that.


Nick Hendler

Offline

 

#5 07-20-2022 03:20:26

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

Clicking the back button to return just returns to the previous page. It doesn't force the page to refresh so docheckoutron() doesn't actually run.
This is confirmed as any printing I have added to the function isn't printed when returning via the back button.
The URL does change from /CheckoutIntro to /CheckoutNew but there is no reload or refresh.

I am away for a week or so from today. When I get back I will update to clean version of 9.2 and check again, just in case it is something I have done but don't think it can be as pushState doesn't reload the browser.
https://stackoverflow.com/questions/243 … he-browser

Last edited by zanart (07-20-2022 03:24:57)


Rob

Offline

 

#6 07-20-2022 08:54:28

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

Sounds good.  I'd like to see this completely solved, so please enjoy your holiday and pick this up when you return.  Our testing here worked perfectly, so this may be an issue with Sage manipulating the back functionality on their side, or browser version / maker related.  We'll track it down.  The changes we made likely made it better, but didn't appear to address all cases.


Nick Hendler

Offline

 

#7 07-20-2022 10:44:34

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

I appear to have resolved the problem by changing

$js_docready  = 'jQuery(\'#PAYMENT\').submit(function(){';
$js_docready .= 'if (window.history && window.history.pushState) {window.history.pushState(\'forward\', null, \'' . $this->link_namespace('ecom','checkoutron') . '\');}';
$js_docready .= '});';

to:

$js_docready  = 'jQuery(\'#PAYMENT\').submit(function(){';
$js_docready .= 'if (window.history && window.history.pushState) {ajaxExec({\'primary\': \'ContentWithTitle\', \'callback\': \'ajaxExecResult\',\'app\': \'ecom\',\'ns\': \'checkoutron\'});}';
$js_docready .= '});';

This forces checkoutron to run everytime the back button is clicked to return to checkout from Sagepay.
I have briefly tested and haven't found any issues with checkoutron running when it shouldn't.
New order numbers are generated only when back button is clicked, not when the correct Cancel link is clicked on sagepay(which is correct).

As always, I have no idea if this is the correct way to do things, but it works for me!


Rob

Offline

 

#8 07-20-2022 11:00:50

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

That should not be working.  What you're doing is running checkoutron() when your payment page loads.  This should have the effect of embedding the current order number in the payment form and regenerating a new order number when the submit button is pressed.  Every time.  I guess the processing works by tagging the old order number, and checkout reloads on return using the new order number so it works, but it's very bad form. I'd like to see a different solution implemented, but this may be a good stop-gap for your issues.


Nick Hendler

Offline

 

#9 07-20-2022 12:47:37

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

So, I get a new order number whenever someone clicks the Back Button on Sagepay or the cancel Button on Sagepay. This is due to the checkoutintro reloading when accessed via Back button.
Don't have any issues with this as I want a need order number when Back button is used.
Only downside is order number is regenerated unnecessarily when returned to site via cancel button,

checkoutron() only runs when CheckoutIntro is returned to via Back button or Cancel button. It doesn't run everything CheckoutIntro is hit or when the Payment form is submitted.

As the crypt is updated as soon as the back button is hit, the correct order id and value is passed to sagepay.

For 90%+ customers who visit checkoutintro and then proceed to payment, there isn't any difference and no extra order numbers are generated.


Rob

Offline

 

#10 07-21-2022 08:11:16

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

The way I'm reading it, every time you access checkout and submit the payment form, your current order is sent to Sage, and a new order is created just in case you return.  Is that how it's working?


Nick Hendler

Offline

 

#11 07-28-2022 14:37:40

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

HI Nick.
If I understand it correctly...
When /CheckoutIntro is hit and the payment form is submitted, the code adds

if (window.history && window.history.pushState) {ajaxExec({\'primary\': \'ContentWithTitle\', \'callback\': \'ajaxExecResult\',\'app\': \'ecom\',\'ns\': \'checkoutron\'});}';

to the docready and submits the form which directs to sagepay payment page. Checkoutron doesn't ever run or do anything when then payment form is submitted as window.history && window.history.pushState cannot be true at this point as /CheckoutIntro would already have reloaded. It just adds the code to the docready.

If user hits Back button or the cancel button on sagepay, they are returned to /CheckoutIntro.

As

if (window.history && window.history.pushState) {ajaxExec({\'primary\': \'ContentWithTitle\', \'callback\': \'ajaxExecResult\',\'app\': \'ecom\',\'ns\': \'checkoutron\'});}';

is in the docready and completely independent of the payment form being submitted it is actioned as window.history && window.history.pushState is true at this point.
Therefore as soon as /CheckoutIntro is accessed via the Back or cancel button, the checkoutron function runs, creates a new order number and reloads the payment form.

A new order is not created everytime the Payment form is submitted just in case the user return. It can't be.

Checkoutron doesn't run at any other time as it can only run after the code has been added to the docready AND window.history && window.history.pushState is true. And this can only happen when the back or cancel button is clicked on sagepay.

Does that make any sense at all??
It does seem to work as I expect/need it to.


Rob

Offline

 

#12 07-29-2022 08:38:07

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

I was incorrect.  I was reading:

Code:

if (window.history && window.history.pushState) {}

As true when the submit button was clicked.  That's not the case.  It only evaluates as true when the page is accessed using back navigation.  And it's only added to the DOM when the submit button is clicked.  I'm going to take this and test it in DEV and I assume you'll see it in the next update.

FYI:  I sent you a lengthy reply to your multipay ticket in our ticket system.  I got you what you needed, but had a few questions for you.  I just want to make sure you got the message and have just been too busy to reply.  Thanks.


Nick Hendler

Offline

 

#13 07-30-2022 01:58:04

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

Excellent.
Got back from holiday on Friday. I will get latest version installed this week along with additional xmod.
Once done I will respond to your email direct.


Rob

Offline

 

#14 08-01-2022 08:39:39

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

Perfect.  Thanks.


Nick Hendler

Offline

 

#15 08-19-2022 00:33:07

extinco
Member
From: Madrid
Registered: 08-19-2022
Posts: 1
Website

Re: Order Number Regeneration for Sagepay Form

Nice


Especialistas en sistemas de protección contra el fuego y equipos de extinción como el  o los equipos de detección automáticos o manuales.

Offline

 

#16 08-19-2022 05:32:06

zanart
Member
From: bedford
Registered: 04-02-2008
Posts: 1706

Re: Order Number Regeneration for Sagepay Form

FYI, i have added a setTimeout to the ajaxexec function so it doesn't run too quickly.
I had a broadband issue for a few days and was using 4G. I found the ajaxexec function would sometimes run before sagepay url loaded, causing extra order numbers and problems with the return from sagepay having an older order number.
Don't really understand why the function would run on slower connections without the back button being clicked but it does intermittently.

changing it to

$this->append_global_array('core.js_windowload',$this_windowload);

also seems to resolve issue.


Rob

Offline

 

#17 08-19-2022 08:20:10

webmaster
Administrator
From: York, PA
Registered: 04-20-2001
Posts: 19798
Website

Re: Order Number Regeneration for Sagepay Form

Thanks for the update.  I'll ensure this change is implemented in the next update.  I'm going to move the code from docready to windowload rather than using a timeout via docready.


Nick Hendler

Offline

 

Board footer