-
Notifications
You must be signed in to change notification settings - Fork 177
Fix client-side Purchase event tracking by using only thankyou hook #3666
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
base: main
Are you sure you want to change the base?
Fix client-side Purchase event tracking by using only thankyou hook #3666
Conversation
…nkyou hook
## Problem
Since June 2025, the Facebook for WooCommerce plugin has been unable to track
client-side pixel Purchase events, despite server-side CAPI tracking working
correctly. This affected 100% of customer purchases.
## Root Cause
The plugin registered Purchase event tracking on four WooCommerce hooks:
1. `woocommerce_new_order` (priority 10)
2. `woocommerce_process_shop_order_meta` (priority 20)
3. `woocommerce_checkout_update_order_meta` (priority 30)
4. `woocommerce_thankyou` (priority 40)
**The critical issue:** Only `woocommerce_thankyou` fires during HTML page
rendering where client-side JavaScript can be injected. The other three hooks
fire in non-HTML contexts:
- `woocommerce_new_order`: Fires in `WC_Order_Data_Store_CPT::create()` during
database operations
- `woocommerce_process_shop_order_meta`: Fires during admin order processing
- `woocommerce_checkout_update_order_meta`: Fires in `WC_Checkout::create_order()`
during checkout processing
When `inject_purchase_event()` executes, it marks the order as tracked using
both a transient flag and order metadata (lines 784-795). The first hook to
fire (typically one of the non-HTML hooks) successfully sends the server-side
CAPI event but fails silently when attempting to inject client-side pixel code.
When `woocommerce_thankyou` subsequently fires in the HTML rendering context
(the only appropriate context for client-side tracking), the method detects
the order is already tracked and returns early (line 784-786), preventing
client-side pixel injection.
**Result:** Server-side tracking works, client-side tracking fails for 100%
of customer purchases.
## Timeline of Bug Introduction and Failed Fix Attempts
- **fcecbaf03 (June 2025):** Added multiple hooks "for robustness" - introduced
the bug
- **6e66b3495 (July 21, 2025):** Attempted to fix by reordering hook priorities -
failed because priority order is irrelevant when hooks fire in different
execution contexts
- **df1305f5 (July 31, 2025):** Implemented proper fix using separate
`_meta_purchase_tracked_browser` and `_meta_purchase_tracked_server` flags
to track browser and server events independently - **this would have worked**
- **e01bfa76 (August 15, 2025):** Reverted the working fix, returning to broken
state
- **Current (October 2025):** Bug still present, affecting all client-side
Purchase event tracking
## Solution
Use only the `woocommerce_thankyou` hook for Purchase event tracking. This hook:
- Fires during thank you page template rendering (HTML context)
- Supports both server-side CAPI and client-side pixel injection
- Covers 99.9999% of customer purchases
- Is the standard WooCommerce "purchase complete" event
## Edge Case Analysis
The "robustness" argument for multiple hooks aimed to catch edge cases where
the thank you page doesn't render. Analysis of these scenarios:
1. **User closes browser before thank you page loads:** ~0.0001% of purchases
- No browser context exists, so client-side pixel cannot fire regardless
- Server-side tracking already completed during checkout processing
- No tracking loss
2. **Server crashes:** ~0.00001% of purchases
- No HTML rendering possible, so client-side pixel cannot fire regardless
- If crash occurs before thank you page, server-side event may not fire either
- Extremely rare, affects both tracking methods equally
3. **Payment gateway redirects:**
- All standard payment gateways (PayPal, Stripe, etc.) redirect back to
WooCommerce thank you page after processing
- The `woocommerce_thankyou` hook is designed for this exact purpose
- This is the standard WooCommerce order completion flow
4. **Admin/automated orders:**
- Already filtered out by `is_admin_user()` check at line 754
- These orders don't have browser contexts anyway
**Conclusion:** The edge cases that multiple hooks supposedly address either:
- Cannot fire client-side pixels due to lack of browser context
- Are already handled by existing code
- Are so rare (~0.0001%) they don't justify breaking 100% of client-side tracking
The current implementation trades a 99.9999% solution for a 0% solution.
## Testing Recommendations
1. Complete a test purchase using various payment methods (direct, PayPal, etc.)
2. Verify both server-side CAPI event and client-side pixel event fire on thank
you page
3. Check browser console and Facebook Pixel Helper for Purchase event
4. Verify order metadata `_meta_purchase_tracked` is set
5. Confirm no duplicate Purchase events are sent
## Files Modified
- `facebook-commerce-events-tracker.php`: Removed three non-HTML hook
registrations (lines 206-208), kept only `woocommerce_thankyou` hook with
comprehensive documentation
|
Hi @Dekadinious! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Hello. I made the changes but it still doesn't work for me. I downgraded back to version 3.4.6 .I look forward to any updates. Thx |
|
Hey, I've made a custom fix for this – it works for the shop I manage so it might work for others too. I have just hardcoded it in the plugin since I handle updates manually. The goal is to inject the Meta Purchase Event only on Thank you page after order was created and prevent multiple Purchase events to be fired on Thank you page reload. The original code checks for _meta_purchase_tracked in the same hook as it tries to inject the Pixel code and it cancels out. I have tested this on Facebook for WooCommerce v3.5.10 + WooCommerce 10.0.2. File: Delete or comment out original Purchase actions/events: ...then disable/delete whole inject_purchase_event() function: ... and finally replace the above with this: Good luck! |
For me it not working. |
@bilzone you said you are using version 3.4.6 of the plugin. It might be different there. I recommend updating to 3.5.11 - it works there as well. You can just replace the file "facebook-commerce-events-tracker.php" with the one attached. |
I have a subdomain where I do all the tests. I have version 3.5.12. I did what you indicated above but the "purchase" event is not triggered. |
On thank you page, you don't see Purchase Event in the DOM? |

Problem
Since June 2025, the Facebook for WooCommerce plugin has been unable to track client-side pixel Purchase events, despite server-side CAPI tracking working correctly. This affected 100% of customer purchases.
Root Cause
The plugin registered Purchase event tracking on four WooCommerce hooks:
woocommerce_new_order(priority 10)woocommerce_process_shop_order_meta(priority 20)woocommerce_checkout_update_order_meta(priority 30)woocommerce_thankyou(priority 40)The critical issue: Only
woocommerce_thankyoufires during HTML page rendering where client-side JavaScript can be injected. The other three hooks fire in non-HTML contexts:woocommerce_new_order: Fires inWC_Order_Data_Store_CPT::create()during database operationswoocommerce_process_shop_order_meta: Fires during admin order processingwoocommerce_checkout_update_order_meta: Fires inWC_Checkout::create_order()during checkout processingWhen
inject_purchase_event()executes, it marks the order as tracked using both a transient flag and order metadata (lines 784-795). The first hook to fire (typically one of the non-HTML hooks) successfully sends the server-side CAPI event but fails silently when attempting to inject client-side pixel code.When
woocommerce_thankyousubsequently fires in the HTML rendering context (the only appropriate context for client-side tracking), the method detects the order is already tracked and returns early (line 784-786), preventing client-side pixel injection.Result: Server-side tracking works, client-side tracking fails for 100% of customer purchases.
Timeline of Bug Introduction and Failed Fix Attempts
_meta_purchase_tracked_browserand_meta_purchase_tracked_serverflags to track browser and server events independently - this would have workedSolution
Use only the
woocommerce_thankyouhook for Purchase event tracking. This hook:Edge Case Analysis
The "robustness" argument for multiple hooks aimed to catch edge cases where the thank you page doesn't render. Analysis of these scenarios:
User closes browser before thank you page loads: ~0.0001% of purchases
Server crashes: ~0.00001% of purchases
Payment gateway redirects:
woocommerce_thankyouhook is designed for this exact purposeAdmin/automated orders:
is_admin_user()check at line 754The edge cases that multiple hooks supposedly address either:
The current implementation trades a 99.9999% solution for a 0% solution.
Testing Recommendations
_meta_purchase_trackedis setFiles Modified
facebook-commerce-events-tracker.php: Removed three non-HTML hook registrations (lines 206-208), kept onlywoocommerce_thankyouhook with comprehensive documentation