To disable tracking for failed orders on the thank you page, check the order’s status before any conversion-tracking code runs, and remove everything hooked to woocommerce_thankyou when the order has failed — since that hook fires on the thank you page regardless of whether payment actually succeeded.
Why Failed Orders Still Trigger Tracking Code
- The
woocommerce_thankyouhook fires whenever the order-received page loads, not only on successful payments - Analytics, affiliate commission plugins, and ad conversion pixels often hook into it without checking order status themselves
- Left unchecked, this inflates your conversion numbers and can trigger affiliate payouts for orders that never actually completed
The Fix
/** Remove all woocommerce_thankyou callbacks if the order failed */
add_action( 'wp_head', 'exclude_failed_orders_from_thankyou_tracking' );
function exclude_failed_orders_from_thankyou_tracking() {
global $wp;
if ( ! is_wc_endpoint_url( 'order-received' ) ) {
return;
}
$order_id = isset( $wp->query_vars['order-received'] ) ? absint( $wp->query_vars['order-received'] ) : 0;
$order = $order_id ? wc_get_order( $order_id ) : false;
if ( $order && $order->has_status( 'failed' ) ) {
remove_all_actions( 'woocommerce_thankyou' );
}
}A Safer, More Targeted Alternative
Removing every callback on woocommerce_thankyou can be too broad if some of those callbacks genuinely need to run regardless of order status (like a “sorry your payment failed” message). A more targeted approach only removes specific tracking functions by name:
function exclude_failed_orders_from_specific_tracking_only() {
global $wp;
if ( ! is_wc_endpoint_url( 'order-received' ) ) {
return;
}
$order_id = isset( $wp->query_vars['order-received'] ) ? absint( $wp->query_vars['order-received'] ) : 0;
$order = $order_id ? wc_get_order( $order_id ) : false;
if ( $order && $order->has_status( 'failed' ) ) {
remove_action( 'woocommerce_thankyou', 'output_analytics_conversion_pixel', 10 );
remove_action( 'woocommerce_thankyou', 'notify_affiliate_plugin_of_conversion', 10 );
}
}
add_action( 'wp_head', 'exclude_failed_orders_from_specific_tracking_only' );Troubleshooting
Conversions Stop Tracking Entirely, Even for Successful Orders
This usually means the status check logic is inverted or firing too broadly — confirm $order->has_status( 'failed' ) only evaluates true for genuinely failed orders, and test with both a successful and a deliberately failed test order.
Affiliate Plugin Still Counts Failed Orders as Conversions
If the affiliate plugin’s own logic doesn’t respect remove_all_actions because it hooks somewhere else entirely (like woocommerce_order_status_changed), you’ll need to check its documentation for a status-based exclusion setting instead.
Frequently Asked Questions
Should I redirect customers elsewhere after a failed order instead?
It’s worth considering — redirecting to the My Account or Cart page after a failure lets customers retry payment, which can be a better experience than showing a generic thank you page.
Does this affect order-received emails too?
No — this only affects code hooked to the thank you page display; email notifications are controlled by separate order-status-change hooks.
Will this work for guest checkouts as well as logged-in customers?
Yes — the order status check works the same regardless of whether the customer has an account, since it’s based on the order object itself.
Conclusion
Disabling tracking for failed orders on the WooCommerce thank you page is a short status check that prevents inflated analytics and incorrect affiliate payouts — just be careful whether you remove all thank-you-page callbacks or only the specific tracking functions that shouldn’t fire on a failure.
See also How to Add a Tracking Script to the WooCommerce Thank You Page.
Prefer no code? All-in-One Utilities Woo Add-on handles this kind of change from a settings screen. Its Checkout and thank-you page content guide also shows how.