Loading twice WooCommerce thankyou page would duplicate Conversion tracking?
I implemented a custom script in tankyou page in my woocommerce store to track google ads conversions. This is my implementation:
add_action( "woocommerce_thankyou", "pixel_analytics_conversion_track_script", 20 ); if ( ! function_exists( 'pixel_analytics_conversion_track_script' ) ) { function pixel_analytics_conversion_track_script($order_id){ if ( $order_id > 0 ) { $order = wc_get_order( $order_id ); if ( $order instanceof WC_Order ) { $order_id = $order->get_id(); // order id $order_key = $order->get_order_key(); // order key $order_total = $order->get_total(); // order total $order_currency = $order->get_currency(); // order currency $order_payment_method = $order->get_payment_method(); // order payment method $order_shipping_country = $order->get_shipping_country(); // order shipping country $order_billing_country = $order->get_billing_country(); // order billing country $order_status = $order->get_status(); // order status ?> <script type="text/javascript"> jQuery(document).ready(function( $ ){ console.log('PURCHACE EVENT'); /* Track conversion on facebook Pixel */ fbq('track', 'Purchase', { value: <?php echo $order_total ?>, currency: "<?php echo $order_currency ?>" }); /* Track conversion on Google Ads */ gtag('event', 'conversion', { 'send_to': 'AW-693771414/0MhwCMa9rLYBEJa56MoC', 'value': <?php echo $order_total ?>, 'currency': "<?php echo $order_currency ?>", 'transaction_id': "<?php echo $order_id ?>" }); }); </script> <?php } } } }
The code works very well but some data is not precise and I think that probably the code above duplicates conversion if user goes to thank you page twice. We have an order confirmation email that has a link to the thankyou page of woocommerce.
As you can see Im sending the transaction_id
parameter, so my question:
If the user loads twice or N times the thank you page the conversion will appear dupplicated in Google ads even if you send the transaction_id
parameter?
Update: Added compatibility for HPOS
You can use order custom metadata to avoid duplicated Conversion tracking as follows:
add_action( "woocommerce_thankyou", "pixel_analytics_conversion_track_script", 20 ); if ( ! function_exists( 'pixel_analytics_conversion_track_script' ) ) { function pixel_analytics_conversion_track_script($order_id){ $order = wc_get_order( $order_id ); // Get order object // Avoid if pixel analytics conversion track script has been run before if ( is_a($order, 'WC_Order') && !$order->get_meta('_pixel_tracking') ) { $order_id = $order->get_id(); // order id $order_key = $order->get_order_key(); // order key $order_total = $order->get_total(); // order total $order_currency = $order->get_currency(); // order currency $order_payment_method = $order->get_payment_method(); // order payment method $order_shipping_country = $order->get_shipping_country(); // order shipping country $order_billing_country = $order->get_billing_country(); // order billing country $order_status = $order->get_status(); // order status ?> <script type="text/javascript"> jQuery(document).ready(function( $ ){ console.log('PURCHACE EVENT'); /* Track conversion on facebook Pixel */ fbq('track', 'Purchase', { value: <?php echo $order_total ?>, currency: "<?php echo $order_currency ?>" }); /* Track conversion on Google Ads */ gtag('event', 'conversion', { 'send_to': 'AW-693771414/0MhwCMa9rLYBEJa56MoC', 'value': <?php echo $order_total ?>, 'currency': "<?php echo $order_currency ?>", 'transaction_id': "<?php echo $order_id ?>" }); }); </script> <?php // Flag the order (with custom meta data) to avoid pixel analytics conversion track script run multiple times. $order->update_meta_data('_pixel_tracking', true); $order->save(); } } }Code goes in functions.php file of the active child theme (or active theme). It should works.
Im just curious about something, why is this necesary? if ( ! function_exists( 'pixel_analytics_conversion_track_script' ) ) {
@svelandiag Just taken from your code: It allows to be sure that the function name pixel_analytics_conversion_track_script is not defined yet by a plugin, your theme or another custom script, so not really necessary…
If you let the conditional 'done' === get_post_meta( $order_id, '_pixel_tracking', true ) it will never get in. I used your version and it never track conversions, I had to modify the if statement to get_post_meta( $order_id, '_pixel_tracking', true ) != 'done'
@svelandiag Thanks… I updated the code to be compatible with HPOS.
In your example, you're using a Google Ads conversion snippet which includes the transaction_id. When including the transaction_id Google Ads automatically deduplicates duplicate conversions. This happens over night. So you may see duplicate conversions during the day, but they will be removed by the next day.
For Google Ads this is a safe and the best way to ensure no duplicate conversions are measured.
Reference: Use a transaction ID to minimize duplicate conversions
In an earlier reply to your question a solution was outlined that would set a meta key on the order, once the woocommerce_thankyou hook has run. As pointed out in 1. using a server side flag for Google Ads isn't necessary. But other tracking pixels don't do automatic deduplication.
In our analysis that includes thousands of installs of our tracking code manager (Pixel Manager for WooCommerce), we found that using only this server-side code leads to underreported conversions down to 80% of what should be tracked.
The reasons are manifold.
The tracking pixels only fire if the buyer reaches the purchase confirmation page in his browser.
There are numerous reasons why that sometimes doesn't happen.
The payment gateway is not configured correctly and doesn't redirect to the purchase confirmation page. The buyer stops the browser redirect to the purchase confirmation page. The server loads the purchase confirmation page too slow and the buyer abandons it. Script errors on the purchase confirmation page. Cookie banners that block the tracking pixels as long and not cookie consent has been given. etc.The better way is to set a cookie after the tracking pixels have run in the browser.
And, only run the tracking codes if the cookie has not been set in that browser. This brings inflated conversions from an average of 115% down to approx. 103%.
The reason why this is not perfect is because buyers sometimes delete cookies and then, sometimes later, reopen the purchase confirmation page. Or they open the purchase confirmation page on a different device, etc.
The best solution is a combination of cookie and server-side flags.
After the tracking codes have run in the browser set the cookie and also use JavaScript to instruct the server to set a flag on the order to not active the tracking codes anymore.
That way, conversions don't get overreported. And if, for some reason the tracking codes don't run immediately after the purchase, they can run at least if the buyer re-loads or re-visits the purchase confirmation page.
This isn't easy to implement on your own. But it's the most accurate solution. You can take a look at the code of our Pixel Manager for WooCommerce to find out how we've done it. We also implemented more features that help you detect underreported conversions and help you fix misconfigurations that lead to underreported conversions.