← All Guides

Meta Pixel Advanced Matching on WordPress and WooCommerce with Google Tag Manager: Higher Event Match Quality, Accurate Purchases

How to implement Meta Pixel through Google Tag Manager on a WordPress or WooCommerce site with Advanced Matching: ViewContent, AddToCart, InitiateCheckout and Purchase with values and content IDs, customer data for better Event Match Quality, and verification in Events Manager.

Atiqul Islam
Written by Atiqul Islam

Tracking & analytics specialist. 278+ GTM, GA4 and server-side tracking projects for clients in the US, UK and Australia.

Rather not do this yourself? I set this up for clients every week. Free 15-minute audit, no obligation.

Book a Free Audit

A WooCommerce store can have every Meta Pixel event firing and still get weak results from Meta ads, because the events arrive without enough information for Meta to know who performed them. Event Match Quality, the score Meta shows per event in Events Manager, measures exactly that. Low scores mean lost attribution, smaller custom audiences and worse optimisation.

This guide shows how I implement Meta Pixel through Google Tag Manager on WordPress and WooCommerce with manual Advanced Matching, so every event carries the customer data Meta can use.

What Advanced Matching Sends

With Advanced Matching, the pixel sends normalised and hashed values for fields such as:

Meta hashes them in the browser before sending. The more fields you provide, the higher the match rate.

Step 1: Clean Up Existing Pixels

Search the theme and plugins for existing pixel code. Common culprits: the Facebook for WooCommerce plugin, PixelYourSite, theme options with a pixel ID field, and code pasted into header scripts. Decide on GTM as the single source and disable the rest. Duplicate pixels inflate events and break deduplication.

Step 2: Build the User Data Layer

Push customer data to the data layer wherever you have it. A small plugin or child theme snippet handles the three cases:

add_action('wp_head', function () {
  $user = [];

  if (is_user_logged_in()) {
    $u = wp_get_current_user();
    $user = [
      'user_email'       => strtolower($u->user_email),
      'user_first_name'  => $u->first_name,
      'user_last_name'   => $u->last_name,
      'user_external_id' => (string) $u->ID,
    ];
  }

  if (function_exists('is_order_received_page') && is_order_received_page()) {
    $order = wc_get_order(absint(get_query_var('order-received')));
    if ($order) {
      $user = [
        'user_email'       => strtolower($order->get_billing_email()),
        'user_phone'       => preg_replace('/\D+/', '', $order->get_billing_phone()),
        'user_first_name'  => $order->get_billing_first_name(),
        'user_last_name'   => $order->get_billing_last_name(),
        'user_city'        => $order->get_billing_city(),
        'user_state'       => $order->get_billing_state(),
        'user_zip'         => $order->get_billing_postcode(),
        'user_country'     => $order->get_billing_country(),
        'user_external_id' => (string) ($order->get_customer_id() ?: ''),
      ];
    }
  }

  if ($user) {
    echo '<script>window.dataLayer=window.dataLayer||[];window.dataLayer.push(' . wp_json_encode(array_filter($user)) . ');</script>';
  }
}, 1);

On the checkout page, add a small script that reads the billing fields as the customer types and pushes them to the data layer, so InitiateCheckout and any later events on that page can use them.

Step 3: Ecommerce Data Layer

Use the WooCommerce GA4 guide on this site for view_item, add_to_cart, begin_checkout and purchase. The Meta tags read from the same ecommerce object.

Step 4: GTM Variables

Create Data Layer Variables for each user field: user_email, user_phone, user_first_name, user_last_name, user_city, user_state, user_zip, user_country, user_external_id. Create the ecommerce variables for transaction ID, value, currency and items, plus a Custom JavaScript variable that maps ecommerce.items to an array of item_id values for content_ids.

Step 5: Meta Pixel Tags

Use the official Meta Pixel template from the Community Template Gallery.

Base pixel on All Pages with Advanced Matching enabled and every user field mapped to the corresponding parameter. The template normalises and hashes them. Add an ad_storage consent requirement if you run a consent banner.

ViewContent on view_item with content_ids, content_name, content_type of product, value and currency.

AddToCart on add_to_cart with the same parameters.

InitiateCheckout on begin_checkout with content_ids, num_items, value and currency.

Purchase on purchase with content_ids, content_type, num_items, value, currency and eventID set to the order number for deduplication with the Conversions API.

Each event tag inherits the user data from the base pixel's init call, and the template also lets you pass user data per event. Map it on Purchase as well, because the order received page is where you have the most complete details.

Step 6: Conversions API

Send the same events from a server-side GTM container with the same event IDs. On WooCommerce you can trigger the server purchase from the browser event routed through the server container, or from a woocommerce_payment_complete hook that posts to the server container directly, which catches orders where the customer never saw the thank-you page. Include the hashed user fields and the fbp and fbc cookies.

Step 7: Verify

  1. GTM Preview. Browse as a guest, add to cart, check out with a test gateway. Confirm each Meta tag fires once with the expected parameters, and that the user fields are populated on checkout and the order received page.
  2. Meta Pixel Helper should show the Advanced Matching parameters on each event, hashed.
  3. Events Manager, Test Events: confirm the events arrive with matched parameters listed, and that Purchase shows as deduplicated when the server event arrives.
  4. Events Manager, Overview: within a few days, Event Match Quality for Purchase should rise into the good range. Scores in the high range typically need email, phone, name, address and the fbp and fbc cookies all present.

Common Problems

Outcome

Meta receives complete ecommerce events with the customer data it needs to match them to people. Attribution improves, custom audiences grow, and the Purchase event becomes a reliable optimisation signal. For most WooCommerce stores the Event Match Quality score moves from poor to good within a week of this setup.

Frequently Asked Questions

What is Advanced Matching and is it allowed?

Advanced Matching sends hashed customer details such as email and phone with pixel events so Meta can match them to accounts. The hashing happens in the browser. It is a standard Meta feature, but it is personal data, so it must respect your consent setup and privacy policy.

Automatic or manual Advanced Matching?

Automatic Advanced Matching lets the pixel scrape form fields on its own. Manual Advanced Matching passes the fields you choose, from the data layer. Manual is more predictable, works on checkout where you have billing data, and is what this guide uses.

Where does the customer data come from on WooCommerce?

On the order received page from the order's billing details, on checkout from the form fields as the customer types, and for logged-in customers from the user profile on every page.

Why is my Event Match Quality still low after adding email?

Email alone gives a moderate score. Add phone, first name, last name, city, postcode and country, and make sure the fbp and fbc cookies are present. Also check that the values are normalised: lowercase email, phone with country code and no spaces.

Do I still need the Conversions API?

Yes, for the events the browser cannot send. Advanced Matching improves the quality of browser events; the Conversions API recovers the missing ones. They work together, deduplicated by event ID.

Want This Done Right the First Time?

Book a free 15-minute audit call. I'll review your setup, show you what is broken, and tell you exactly what it takes to fix it.

Chat Now