Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible solution for duplicate transaction tracking #118

Closed
duracelltomi opened this issue Apr 10, 2019 · 25 comments
Closed

Possible solution for duplicate transaction tracking #118

duracelltomi opened this issue Apr 10, 2019 · 25 comments
Assignees
Labels
Milestone

Comments

@duracelltomi
Copy link
Owner

According to the test of a plugin user on some mobile devices, JS codes re-execute on revisiting an already opened tab causing some transactions to be tracked multiple times:

https://wordpress.org/support/topic/duplicate-transactions-from-mobile-devices/

The proposed code change should be tested and added to the core

@duracelltomi duracelltomi self-assigned this Apr 10, 2019
@duracelltomi duracelltomi added this to the v1.10 milestone Apr 10, 2019
@koconder
Copy link
Contributor

koconder commented Jun 6, 2019

@duracelltomi seems like a clean fix but needs testing. Could be expanded to use HTML5 storage as cookies sometimes an issue with some devices but not a major issue as its the same methodology as before.

@duracelltomi
Copy link
Owner Author

I will check this and commit the code this week

@duracelltomi
Copy link
Owner Author

This case needed a bit more complex coding as order ID checking had to be done in the frontend since on mobile devices where the order received page is reopened from local cache, no backend execution is done

@luukfiets
Copy link

Hi,

I would like to get back on this one. I'm setting up a webshop in the Netherlands and we're using iDeal. I've enabled the option to not flag orders as being tracked, since it doesn't track orders payed by iDeal with this option disabled. I've found this new solution you mentioned above to be very useful in order to prevent duplicate transactions. However, I think you might be able to improve it even further.

I can see that the new cookie gtm4wp_orderid_tracked doesn't have an expiration date which makes it a session cookie instead of persistent cookie. First question: would it be possible to set an expiration date so that even when the browser is closed and the order confirmation page is opened a week later, the cookie still is in place (unless the user deleted his cookies of course) and prevents the transaction from being sent again?

Second question: would it be possible to store multiple order IDs in the cookie? After the first order my cookie was set to the right order ID (6 in this case). When making a new purchase in the same browser session the cookie is set to the latest order ID (7). In theory, I would be able to get duplicate transactions from the order with ID 6 because it isn't stored in the cookie anymore.

Sorry for the detailed answer, but hopefully it makes sense.

@koconder
Copy link
Contributor

koconder commented Oct 5, 2019 via email

@duracelltomi
Copy link
Owner Author

I can see that the new cookie gtm4wp_orderid_tracked doesn't have an expiration date

Could you point me to where you have this seen?
This is the code that places the cookie:

var gtm4wp_orderid_cookie_expire = new Date();
gtm4wp_orderid_cookie_expire.setTime( gtm4wp_orderid_cookie_expire.getTime() + **(365*24*60*60*1000)** );
var gtm4wp_orderid_cookie_expires = "expires="+ gtm4wp_orderid_cookie_expire.toUTCString();
document.cookie = "gtm4wp_orderid_tracked=" + gtm4wp_orderid_tracked + ";" + gtm4wp_orderid_cookie_expire + ";path=/";

But I had some more reports about this issue and for some reason this does not seem to work 100% accurate.

One case I was able to identify is the Safari browser which cuts of the expiration date of this cookie to 1 day. But this is a "by design" issue, to make it work the cookie should be created in the HTTP response header but this is not possible since this would remove tracking of the first page load as well.

Local storage could be one possible way to go as @koconder mentioned, but I have no doubt this will be on the desk very soon as Safari and Firefox is releasing an updated and even more restrictive "protection" many times in a year.

The real and most clear solution would be if vendors would have an option in their products to drop incoming data if the order ID was already tracked previously.

@luukfiets
Copy link

Here are two images which show that the cookie is only for this session. I'm using chrome by the way. The first one is in Dutch, but the selected text says it's only for this session.
Image 1
Image 2

If local storage is an option, would it be worth it to look further into the iDeal issue? The only way I'm able to get ecommerce data to Analytics is by disabling the option of flagging orders. That makes it easy to get duplicate transactions, so this new solution with the cookie would be great workaround. However, if it's not possible to add the suggested enhancements, it might be easier to find a solution for the iDeal issue. That wouldn't solve this exact issue, but it would help a lot of iDeal users, which are forced to drop flagging for tracked orders.

@duracelltomi
Copy link
Owner Author

Yeah, finally I found the problem: there was a typo in the code that created the cookie which made it a session cookie.

Now the first approach will be to use localStorage, if this is not available, the plugin will create a cookie but now with a 1 year long expiration date

@luukfiets
Copy link

"Should be work with Safari at least for now." made me laugh. Thanks for adding this fix!

Do you have any plans on adding multiple order IDs in the localStorage/Cookie in order to prevent duplicate transactions when there's more then one order done and someone visits the thank you page of the previous order? I'm just curious :)

@duracelltomi
Copy link
Owner Author

Sure, I just want to have a working solution with one order ID :-)
Currently I have a report where it seems that the fixed and enhanced version is not working for a website owner :-(

@luukfiets
Copy link

Ah perfect, I didn't want to rush you :)

Should I open another issue so that we can continue there or is this one still one still on the radar eventhough it's marked as closed?

@duracelltomi
Copy link
Owner Author

I have some open threads regarding this, believe me, it is on my radar :-)

@gbvaz
Copy link

gbvaz commented Sep 24, 2020

Hey, sorry I know this is already closed, but I've been reading all the threads about this problem here and in WP forum, and I know it's been a long time since all this happened.

The thing is, I've been having this problem with desktop users with cookies disabled. I was thinking if this has been implemented with the local storage solution mentioned, and if browsers now a days are also not storing this info anymore due to GDPR.

You probably already thought about this, and have the possible arguments against this, but bear with me, what if we could just store this in the database making an AJAX call or something like that to the backend, and move this control over to the server side of things, and when page reloads it pulls this info form the backend and prevents this from happening again once and for all?

@duracelltomi
Copy link
Owner Author

It is interesting that you see this on desktop since the cookie based prevention is not the only solution for multiple tracked transactions. Actually the cookie based protection was added much later and there is a server side solution active by default that flags all orders as being tracked. So on desktop, if the user reloads the page, there should not be any extra ecommerce tracking because of the server side tracking.

The cookie based prevention was introduced because especially on mobile devices users left the browser tab open with the order received page. Some days later, when this tab was reopened, the content was re-rendered and javascript codes were re-executed without the browser touching the backend.

I like the idea of having a backend AJAX call instead of or next to the cookie protection as this would be re-executed as well. I just do not know whether in that case the AJAX call would be returned from browser cache or from the backend. But perhaps a cache buster parameter could help.

Could you help me implementing this within GTM4WP?

@duracelltomi duracelltomi reopened this Sep 30, 2020
@erikmolenaarnl
Copy link

erikmolenaarnl commented Mar 16, 2021

I might have a good idea to prevent duplicate transaction data:

Only fire the ecommerce data when the order-received page is viewed within XX (e.g. 5) minutes after payment. Combined with the existing protection by the cookie (which prevents page reloads within this time limit), it could be a 100% watertight fix?

I believe this is it:

$order->get_date_paid()

As shown in Woocommerce order backend:

image

Looking forward to your thoughts.

P.s. I also posted this suggestion on the WP.org support forum, sry for the double post.

@duracelltomi
Copy link
Owner Author

Hi,

This could be one more level of protection, yes.
What I have experienced is that mostly in mobile browsers, JS codes on the order received page can rerun without real page reload when the mobile browser app is awakened from sleep. Perhaps checking the time stamp will see the actual time in those cases and prevent double tracking.

@erikmolenaarnl
Copy link

erikmolenaarnl commented Mar 17, 2021

Do you accept donations/paid work to include this feature asap in the next stable release?
I have multiple e-commerce stores for which this is a real problem in their sales reporting.

Looking forward to your reply. Thanks :-)

@duracelltomi
Copy link
Owner Author

It is not a question of money :-)

What you can do to include this in the next release is to clone this repo, add the necessary code (you or your programmer) and then send a PR . I will then review and include it asap.

@erikmolenaarnl
Copy link

Sure no problem, I'll get someone started on it asap! I am glad to be of any help to help you out :-)

I have thought about it some more and I think it's better to use $order->get_date_created() for this, don't you agree? In case orders will be paid later. GTM4WP also transmits ecommerce data when the order-received page is hit, which is when the order is created.

@koconder
Copy link
Contributor

koconder commented Mar 17, 2021 via email

@erikmolenaarnl
Copy link

erikmolenaarnl commented Mar 19, 2021

Hi @duracelltomi,

I would like to hear your thoughts on what I had in mind how to further prevent duplicate transaction tracking in my fork.

What we have:

  • GTM4WP transaction tracking happens only at is_order_received_page()
  • Cheque or BACS go straight to the order-received page.
  • Most users using a 3rd party payment method hit this page within a few minutes after submitting the checkout form when the order was created.
  • Some users get delayed but 99% get there within 25 minutes. Possible causes: having trouble with authenticating their payment, can't find credit card, having trouble logging into Paypal, unexpected toilet break etc.

So primary check will be:

✅ At is_order_received_page(): is $order->get_date_created() <= 25 minutes? If yes, fire transaction tracking. If not, do nothing.

However, some orders possibly get paid many days later after being created while being stuck on "Pending payment" before finally hitting the order received page.

So secondary check will be:

✅ At is_order_received_page(): is $order->get_date_paid() available? If yes, is it <= 25 minutes? If yes, fire transaction tracking. Else, do nothing.

What do you think? Does this make sense?
Please hit me back so I can get my fork started :-)

@koconder
Copy link
Contributor

koconder commented Mar 19, 2021 via email

@duracelltomi
Copy link
Owner Author

I like this approach, one addition that I am sure will be requested if not included in the first iteration: there should be an option under the "Advanced" tab where users can change the 30 min value. I am pretty sure some users will prefer 60 minutes, others 20 min, with that, we can keep this set to 30 by default for most users but more advanced users can adjust based on their figures.

@duracelltomi
Copy link
Owner Author

added in v1.13

@believethehyped
Copy link

believethehyped commented Jun 6, 2022

Hello,

I use this settings because on my ecommerce site we have BNPL payment gateways, which might return payment confirmation within 24 hours. Unfortunately, these orders are duplicated in GA.

image

image

image

Is there any solution that can fix this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants