Skip to content
Back to blog

WooCommerce to Google Merchant Center: Product Feed Setup

Connect WooCommerce to Google Merchant Center without broken feeds. Plugin tradeoffs, ACF/meta-key mappings, GTIN handling, and real-time sync covered.

Alex DiazFounder, SnowPipeMay 8, 202611 min read
woocommercegoogle-shoppinggoogle-merchant-centerproduct-feedsguide

WooCommerce gives you a flexible store. It does not give you a Google Shopping feed. The store data is spread across wp_posts, wp_postmeta, term taxonomies, and whatever Advanced Custom Fields setup the previous developer left behind. Google Merchant Center, meanwhile, expects a clean, fully-attributed feed with valid GTINs (Global Trade Item Numbers), the right Google Product Category, and prices that match the live site to the cent.

The gap between those two ends is where most WooCommerce stores stall. You install a plugin, products start syncing, and a week later half your catalog is "Disapproved" with errors you've never seen before. This guide is for the person fixing that — what's actually required, where WooCommerce data lives, and how to keep the feed honest without rebuilding it every Monday.

How WooCommerce stores product data (and why it matters)

Before touching Google, it helps to know where WooCommerce keeps the fields you'll need to map. Unlike Shopify's relatively flat product+variant model, WooCommerce spreads product data across several WordPress tables:

  • wp_posts — the product itself (title, description, slug, status). Variations are also stored here as product_variation post types, parented to the main product post.
  • wp_postmeta — almost everything else: regular price (_regular_price), sale price (_sale_price), SKU (_sku), stock (_stock, _stock_status), weight, dimensions, GTIN if you stored one, and any Advanced Custom Fields values.
  • wp_terms + wp_term_taxonomy + wp_term_relationships — categories (product_cat), tags (product_tag), brand taxonomies if you use a plugin like Perfect Brands for WooCommerce, and global product attributes (pa_color, pa_size, pa_material).
  • Variation attributes — stored as postmeta keys like attribute_pa_color, attribute_pa_size on the variation post.

That sprawl is why a generic "WooCommerce to Google" plugin often does 70% of the job and then fails on the 30% that's specific to your store — your brand might be a custom taxonomy, your GTIN might be in a third-party plugin's meta key, your product images might come from a CDN that strips alt-text. Google rejects what doesn't match its spec, and your job is to make the data Google sees match the data on your store.

Step 1: What Google Merchant Center actually requires

Google publishes the full product data specification, but only a subset is enforced strictly enough to disapprove your products. Here is the minimum that matters for a WooCommerce store.

Required fields

FieldNotes
idA stable unique ID. Use the WooCommerce variation ID for variable products, post ID for simple products. Do not use the SKU — SKUs change.
titleUp to 150 characters. Plain text. Append the variant axes when relevant ("Acme Hoodie — Black, Large").
descriptionUp to 5,000 characters. Strip the WordPress shortcodes and inline HTML; leave plain prose.
linkPublic product URL. Must return HTTP 200 to Google's crawler with no login wall.
image_linkPublic image URL. Minimum 100×100 pixels (250×250 for apparel). Must be HTTPS.
availabilityin_stock, out_of_stock, preorder, or backorder. Derive from _stock_status when stock management is on, fall back to "in_stock" only if you genuinely never run out.
priceFormat as 19.99 USD — number, space, ISO 4217 code. Comma decimals fail.
brandUp to 70 characters. Where this lives in WooCommerce varies by store.
gtin (or mpn + identifier_exists: no)See GTIN section below.

Required for apparel and shoes

FieldSource in WooCommerce
colorVariation attribute attribute_pa_color or a global attribute pa_color.
sizeVariation attribute attribute_pa_size.
genderOften missing entirely — usually has to be derived from category.
age_groupSame — adult, kids, toddler, infant, newborn. Almost always derived.
item_group_idUse the parent product's post ID so all variations of one product share the same value.

Strongly recommended

FieldWhy
google_product_categorySets your product against Google's product taxonomy. Auto-detection is unreliable for niche categories.
product_typeYour own breadcrumb. Helps with reporting and ad-set building.
sale_price + sale_price_effective_dateRequired to show strikethrough pricing.
additional_image_linkUp to 10 alternate images. WooCommerce stores them in the gallery meta key _product_image_gallery.
shippingAccount-level shipping settings usually suffice; product-level overrides are needed for oversize items.

Step 2: Map WooCommerce fields to Google's format

This is where most setups go wrong. The mapping looks straightforward until you hit a custom plugin or an ACF field. Here's a reference table.

Google fieldWooCommerce sourceGotcha
idpost_id (simple) or post_id of variation (variable)Never use _sku — SKUs change when stores merge inventory systems.
titlepost_titleAppend variation attributes for variable products.
descriptionpost_contentStrip shortcodes via wp_strip_all_tags() before sending. WordPress shortcode markers like [vc_row] will be sent literally otherwise.
linkget_permalink($post_id)Must be the canonical URL. If you run a multi-currency setup, the URL must match the currency you're sending in price.
image_linkFeatured image (_thumbnail_id → attachment URL)Featured image is required; gallery images go to additional_image_link.
price_regular_priceAppend currency. WooCommerce stores raw decimals; format yourself.
sale_price_sale_price if present and within _sale_price_dates_from/_to windowA future-dated sale price is not yet active — don't send it as price.
availability_stock_status (instock/outofstock/onbackorder)Map onbackorderbackorder, not in_stock. Google penalizes mismatches.
brandCustom taxonomy product_brand (Perfect Brands), ACF field brand, or _yoast_wpseo_brandHighly site-specific. Audit yours before assuming.
gtinCustom meta key — _gtin, _global_unique_id, ACF gtin, or a dedicated plugin metaIf empty, set identifier_exists: no and provide mpn.
mpn_sku is a reasonable fallbackUse _sku only when there's no real MPN — Google distinguishes them.
google_product_categoryCustom field or AI-derivedWorth investing in. The taxonomy IDs are at the Google Product Taxonomy page.
product_typeConcatenate product_cat taxonomy chain (parent → child)Clothing > Hoodies > Pullover is the right shape.
color, size, material, patternVariation attribute meta (attribute_pa_color, etc.)Map your slug-formatted values back to display labels — attribute_pa_color: cobalt-blue should send as Cobalt Blue.
item_group_idpost_parent of the variationAll variations of one product share the same value. Use this consistently or ad sets miss new variants.

The brand, GTIN, and Google Product Category fields are where almost every WooCommerce store struggles, because they're rarely stored in the obvious place. Spend an hour auditing your store before assuming a plugin will figure it out.

Step 3: Pick a sync method

There are four real options. Each has a different failure mode.

Option A: Manual CSV export

Use a plugin like Product CSV Import Suite to dump products, reformat to Google's spec, upload to Merchant Center.

  • Pros: Free, works with any WooCommerce setup.
  • Cons: Goes stale the moment you click export. Inventory and price changes don't propagate. Disapprovals from price mismatch are common because Google crawls your live site and sees a different number than your CSV.

Use this only for a one-time test or a fully static catalog (rare).

Option B: Google Listings & Ads (official WooCommerce plugin)

The Google Listings & Ads extension is free, maintained by Automattic with Google.

  • Pros: Free, OAuth setup is painless, handles standard fields.
  • Cons: Limited mapping flexibility. Custom fields, ACF, third-party brand taxonomies, and GTIN plugins often need a developer to wire in. Sync cadence is daily, not webhook-driven, so flash sales lag.

For straightforward stores with no customization, this is a perfectly fine starting point. For anything with ACF, custom taxonomies, or sub-hour sync needs, you'll outgrow it.

Option C: Third-party feed plugin (XML/CSV generator)

Plugins like Product Feed PRO, Pinnacle Cart Feed, or WooCommerce Product Feed generate a hosted XML or CSV file that Google fetches on a schedule.

  • Pros: Decent field-mapping UI, handles custom meta keys and ACF, supports multi-channel.
  • Cons: Generates the feed inside your WordPress install — large catalogs (10,000+ SKUs) can lock up the WP cron and time out. Schedule is hourly at best. No real-time delete signal.

This is the default for most agencies running 1,000–10,000 SKU WooCommerce stores. It works until you outgrow the WP-cron approach.

Option D: External feed automation (SnowPipe and similar)

A platform pulls from your WooCommerce REST API or webhooks, transforms into Google's spec, and pushes via the Merchant API or hosted file.

  • Pros: Doesn't run inside WordPress (no cron timeouts), supports webhook-driven real-time sync, full mapping control including custom meta and ACF, multi-channel from one source.
  • Cons: Monthly cost, requires API credentials.

For stores running serious Shopping ad spend or with frequent inventory turnover, this is where the math starts to favor automation.

Common WooCommerce → GMC errors

"Mismatched price" / "Mismatched availability"

Google crawls your product page and compares to the feed. If your feed says 19.99 USD and the page says $19.99 (no currency symbol issues — Google handles those) but the page is rendering a different number due to a multi-currency plugin or a cache, the product gets disapproved.

Fix: Confirm the price on the canonical product URL with the same currency you're sending. If you use WooCommerce Multi-currency, generate one feed per currency and target each to its market.

"Missing required attribute: gtin"

WooCommerce has no built-in GTIN field. Some stores stuff it into _sku, others use a plugin like WooCommerce GTIN, others add a custom field via ACF. Google warns when GTIN is missing because GTINs unlock better placements.

Fix: Find where (if anywhere) your store stores GTINs, map that meta key to gtin. For genuinely GTIN-less products (private label, custom-made), set identifier_exists: no and provide brand + mpn. See Google's GTIN policy.

"Missing google_product_category"

Auto-categorization works for "Shoes" and "Phones." It fails on "Pickleball Paddle" or "CBD Tincture." Google falls back to a generic category that ranks worse.

Fix: Either add a meta field per product with the Google Product Category ID, or use a tool that infers it from title + description with AI. Either way, ship the field — leaving it auto is leaving traffic on the table.

"Promotional content in image"

Your product image has a "20% OFF" badge baked in by your theme or a sale-banner plugin. Google rejects images with overlay text, watermarks, or borders. See image requirements.

Fix: Use clean product photos. If your theme injects badges, render them in CSS over the image, not into the image file itself.

"Variation not grouped"

Variable product variations don't share an item_group_id. Each variation is treated as an unrelated product. Ad sets that targeted a parent product miss new variations.

Fix: Set item_group_id to the parent product's post ID for every variation. Verify after each new variation is added — this is where bugs hide.

How SnowPipe handles WooCommerce → Google Merchant Center

SnowPipe connects to WooCommerce via the REST API, pulls products, variations, attributes, categories, and meta — including ACF fields and custom taxonomies — and pushes a Google-compliant feed via the Merchant API.

The pieces relevant here:

  • Custom meta and ACF mapping. The smart template handles standard fields out of the box. Anything custom — ACF GTIN field, Perfect Brands taxonomy, your own meta key for material — gets mapped through a visual mapper without code.
  • AI Google Product Category assignment. SnowPipe assigns the right Google Product Category from the title and description automatically, so you don't maintain a 6,000-row category map.
  • Real-time and scheduled together. WooCommerce webhooks trigger immediate updates for product changes; a scheduled full sync runs in the background to catch missed events. You don't pick one — both run.
  • Variation flattening with item_group_id. Variable product variations come out as separate Google items with shared item_group_id derived from the parent post. Each variant gets its own image when the variation has one, falling back to the parent featured image.
  • Multi-channel from one source. The same WooCommerce connection feeds Google, Facebook Catalog, and TikTok Shop without re-mapping. Smart templates per source×destination combo do the lift.

The platform runs outside your WordPress install, so large catalogs don't lock up WP-cron the way in-process plugins do. Catalogs in the 50,000+ SKU range stream through with constant memory.


Ready to fix this for good?

Try SnowPipe free — connect your WooCommerce store and get an accurate Google Merchant Center feed in minutes. Or, book a 15-min demo and I'll walk you through your specific setup.

Ready to automate your product feeds?

Connect your store and sync to Google, Facebook, and more — in minutes. No credit card required.