Skip to content

Purchase event sends parent product ID instead of variation ID for variable products (GlobalSiteTag.php line 402) #3290

@hardik18882

Description

@hardik18882

Plugin version: 3.5.3
WooCommerce version: 10.5.3
WordPress version: 6.9.1


Describe the bug

In GlobalSiteTag.php, the maybe_display_conversion_and_purchase_event_snippets() method builds the purchase event's item list using $item->get_product_id() (line 402). For variable products, this method always returns the parent product ID, never the variation ID.

Since the Google Merchant Center product feed indexes items by variation ID, 100% of purchased item IDs in the purchase event are unmatched in Merchant Center. This breaks basket data reporting in Google Ads entirely.


Evidence from Google Ads Diagnostics

Google Ads → Conversions → Goals → Purchase → Diagnostics reports the following:

⚠️ Needs attention
Basket data is being recorded but there are issues that require your attention.

Under the expanded warning:

Many recent conversions have sold item IDs that can't be matched to Merchant Center
Many recent conversions have sold item IDs that can't be matched to products in Merchant Center. This could be because the item IDs are incorrect or because these products haven't been added to Merchant Center.

Conversion action Action optimisation Conversion source Unmatched sold products Last updated
Google for WooCommerce purchase action Primary Website 100.00% 9 Mar 2026

Downloading the unmatched item IDs confirms they are all parent product IDs (e.g. gla_1234), while the Merchant Center feed correctly lists products by variation IDs (e.g. gla_9876).


Root cause — GlobalSiteTag.php lines 401–414

foreach ( $order->get_items() as $item_id => $item ) {
    $product_id   = $item->get_product_id(); // ← Always returns parent ID
    $product_name = $item->get_name();
    $quantity     = $item->get_quantity();
    $price        = $order->get_item_total( $item );
    $item_info [] = sprintf(
        '{
        id: "gla_%s",   // ← Sends parent ID e.g. "gla_1234" instead of variation ID "gla_9876"
        ...
        }',
        esc_js( $product_id ),

get_product_id() always returns the parent product ID. For variable products, it never returns the variation ID.


Proposed fix — one-liner change on line 402

// Before (buggy):
$product_id = $item->get_product_id();

// After (fixed):
$product_id = $item->get_variation_id() ?: $item->get_product_id();

WC_Order_Item_Product::get_variation_id() returns 0 for simple products, so the ?: $item->get_product_id() fallback ensures simple products continue to work correctly.


Secondary bug — same issue in display_page_view_event_snippet() line 508

The cart page tracking has the same problem:

// Buggy — cart page item tracking:
$id = $cart_item['product_id']; // ← Always parent ID

// Fixed:
$id = ! empty( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : $cart_item['product_id'];

Steps to reproduce

  1. Create a variable product in WooCommerce with at least one variation (e.g. Size: Single, Double, King)
  2. Add a specific variation to cart and complete a purchase
  3. Open browser DevTools on the thank-you / order confirmation page
  4. In the Console run: dataLayer.filter(e => e.event === 'purchase')
  5. Inspect items[].id in the purchase event

Expected: id: "gla_9876" ← variation ID, matches Merchant Center feed
Actual: id: "gla_1234" ← parent ID, does not exist in Merchant Center feed


Impact

  • Google Ads Diagnostics shows 100% unmatched sold products for all stores selling variable products
  • Basket data tracking is completely broken for the majority of WooCommerce stores, as variable products are the standard pattern
  • Google Ads Smart Bidding cannot optimise on product-level conversion value
  • ROAS and product performance reporting is inaccurate

Additional context

This is a one-line fix per affected method. The get_variation_id() method is already available on WC_Order_Item_Product and returns 0 safely for non-variable products, making the fix fully backward compatible.

Metadata

Metadata

Assignees

Labels

BEneeds feedbackThe issue/PR needs a response from any of the parties involved in the issue.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions