Skip to content
Back to blog

WooCommerce to Facebook Catalog: Automate Product Sync

Sync WooCommerce to Facebook Catalog without daily disapprovals. Plugin tradeoffs, variation handling, item_group_id, and webhook-driven real-time sync.

Alex DiazFounder, SnowPipeMay 8, 202611 min read
woocommercefacebookproduct-feedsguide

Most WooCommerce stores running Meta ads share the same story: you installed Facebook for WooCommerce or a similar plugin, products started flowing into Commerce Manager, and within a week you noticed something off — a sale price not showing, a sold-out variant still being advertised, or a "missing field" warning on half the catalog. You dig in, find that the plugin is shipping the regular price instead of the sale price, fix it manually, and then it breaks again two weeks later when you change something else.

WooCommerce to Facebook Catalog is one of those integrations that looks like a 15-minute setup and turns into a recurring chore. This guide covers what's actually moving between the two systems, where the data sprawls in WordPress, and what it takes to keep Meta ads showing the same product information your store does.

How WooCommerce data ends up in Meta

There are three architectures for getting WooCommerce products into a Facebook Catalog. They have different reliability and different failure modes.

1. Facebook for WooCommerce (the Meta plugin)

Facebook for WooCommerce is Meta's official extension. Install it, connect your Meta business account, pick which products to sync, and Meta pulls product data on a schedule.

What it does well: Free, official, OAuth setup is painless. Variations are mapped automatically. Inventory updates pass through.

Where it falls short:

  • Sync cadence is opaque. Price or inventory changes can lag for hours.
  • Field mapping is hardcoded. Custom brand taxonomies, ACF GTIN fields, non-standard title structures — none of those can be transformed on the way out.
  • The plugin runs on WP-cron. Large catalogs (10,000+ SKUs) often hit timeouts on shared hosting and miss sync cycles entirely.
  • Deleting a product in WooCommerce doesn't promptly push a delete to Meta — it's a cache eviction that happens whenever Meta gets around to it.

For a small WooCommerce store with no customization, the plugin is fine. Most stores running serious Meta ad spend outgrow it.

2. Hosted XML/CSV feed (third-party plugin)

A feed plugin (Product Feed PRO, WooCommerce Product Feed, etc.) generates an XML or CSV file at a public URL that Meta pulls on a schedule.

What it does well: Full mapping control. Transform fields, combine ACF values into a structured title, override Google Product Category. Multi-channel friendly.

Where it falls short:

  • Minimum cadence is hourly. Meta can advertise a product that just sold out.
  • The feed file is generated inside WordPress. Large catalogs slow the cron; the URL has to stay accessible 24/7.
  • File-based pulls reprocess the whole catalog each time.

3. API-driven push (Catalog API)

Meta's Catalog API lets you push products in real time — create, update, delete calls as products change.

What it does well: Updates land in seconds. Deleted products disappear immediately. Per-product partial updates mean you only push what changed.

Where it falls short:

  • You need to build (or buy) it. Authenticating to Meta, handling rate limits, mapping WooCommerce's product+variation model to Meta's flat item structure, and recovering from partial failures is real engineering work.
  • You need a WooCommerce webhook listener so changes trigger pushes. Otherwise you're polling.

API-driven is the most reliable in steady state and scales from one store to fifty.

Where WooCommerce stores the fields Meta needs

Before mapping, it helps to know where each piece of data lives in WooCommerce. Unlike Shopify's relatively flat model, WooCommerce spreads things across WordPress tables:

  • wp_posts — the product itself (post_title, post_content, post_status). Variations are also stored here as product_variation post types parented to the main product post.
  • wp_postmeta — most attributes: _regular_price, _sale_price, _sku, _stock_status, weight, dimensions, GTIN if your plugin or theme stores one, all Advanced Custom Fields values.
  • wp_terms + wp_term_taxonomy — categories (product_cat), tags (product_tag), brand taxonomies if you use a plugin like Perfect Brands.
  • Variation attribute meta — keys like attribute_pa_color, attribute_pa_size on the variation post.

Brand and GTIN are the two fields most likely to live in a non-obvious place. Audit your store before assuming a generic plugin will find them.

What Meta requires in a Facebook Catalog

Meta's product feed specification lists more than 30 fields. The enforced subset is what gets you disapproved.

Required fields

FieldNotes
idStable unique identifier. Use the WooCommerce variation post ID for variable products, the product post ID for simple products. Do not use SKU.
titleUp to 150 characters. Plain text. No HTML, no all-caps, no emojis.
descriptionUp to 5,000 characters. Strip WordPress shortcodes — Meta will send [vc_row] literally if you don't.
availabilityin stock, out of stock, available for order, discontinued, or preorder. Map from _stock_status.
conditionnew, refurbished, or used.
priceFormat as 19.99 USD — number, space, ISO 4217 code. Comma decimals fail.
linkPublic product URL via get_permalink(). Must be HTTPS and return HTTP 200.
image_linkPublic image URL. Minimum 500×500 pixels. Must be HTTPS.
brandUp to 70 characters. Source varies by store — see below.

Recommended fields

FieldWhy
gtinSignificantly improves ad relevance and unlocks shopping ad placements.
mpnUse when no GTIN is available. _sku is a reasonable fallback.
google_product_categoryUse Google's product taxonomy ID. Auto-detection is unreliable for niche categories.
product_typeYour own breadcrumb. Useful for ad-set building.
sale_price and sale_price_effective_dateRequired for strikethrough pricing.
additional_image_linkUp to 20 alternate images. Pull from _product_image_gallery.

Variation handling — the part most setups break on

WooCommerce's product+variation model has to flatten into Meta's per-item model:

  • Each WooCommerce variation becomes one Facebook item.
  • All variations of one parent product share the same item_group_id.
  • Each item needs its own id, its own image_link, its own price, and its own availability from per-variation stock.
  • Meta's variant axes — color, size, pattern, gender, age_group, material — should be filled from the matching attribute_pa_* meta when those attributes exist.

Getting variation flattening wrong is the #1 reason Meta ads underperform on WooCommerce stores. If two color variants share the parent's image, half your impressions show the wrong color.

Mapping WooCommerce fields to Meta fields

Meta fieldWooCommerce sourceGotcha
idVariation post ID (variable) or product post ID (simple)Stable IDs only. SKUs change.
titlepost_title + appended variation attributesStrip emojis. Meta rejects them.
descriptionpost_contentRun through wp_strip_all_tags() to remove shortcodes and inline HTML.
availability_stock_statusMap instockin stock, outofstockout of stock, onbackorderavailable for order. Note the spaces.
price_regular_price + currencyIf a sale is active, price stays at regular and sale_price carries the discount.
sale_price_sale_price if within _sale_price_dates_from/_toA future-dated sale price is not yet active — don't ship it as sale_price until the start date.
linkget_permalink($variation_id) for variable productsThe variation URL, not the parent — so the right variant pre-selects on click.
image_linkVariation _thumbnail_id if set, else parent _thumbnail_idIf you don't fall back to the parent image, variations without their own image fail with "missing image_link".
brandproduct_brand taxonomy, ACF brand field, or theme-specific metaHighly site-specific. Audit yours.
gtinCustom meta key — _gtin, _global_unique_id, or ACFIf empty, omit. Meta accepts missing GTIN; mismatched GTIN gets harsher penalties than missing.
conditionHardcode new for most stores; refurbished/used stores need a custom field
item_group_idpost_parent of the variationAll variations of one product share the same value.
color, size, material, patternVariation attribute metaMap slug values back to display labels — attribute_pa_color: cobalt-blue should ship as Cobalt Blue.
google_product_categoryCustom meta or AI-derivedAuto-detection fails on niche categories.

Common WooCommerce → Facebook Catalog errors

"Image is too small" / "Image not accessible"

Meta crawls image_link from outside your network. If your CDN blocks crawler IPs (rare on aggressive WAF setups) or your images live behind a login, the field fails. Less obvious: WooCommerce's default thumbnail sizes are often 300×300 or smaller. Meta requires at least 500×500.

Fix: Confirm the image URLs in your feed return 200 from a fresh curl with no cookies. In Settings → Media, set the WooCommerce single product image size to 1024×1024 or larger and regenerate thumbnails.

"Invalid price" or "Currency mismatch"

Meta wants 19.99 USD. WooCommerce stores raw decimals (19.99) — you have to append the currency. If you use WooCommerce Multi-currency or similar, the catalog needs one feed per currency.

Fix: Format prices server-side as ${amount} ${currencyCode}. For multi-currency stores, set up separate Meta catalogs per market.

"Mismatched availability"

Meta crawls your product page and compares its inventory hint to your availability field. If your feed says in stock but the page renders "Out of Stock" because of a shipping zone restriction or a backorder-only state your plugin handles oddly, the product gets flagged.

Fix: Source availability from _stock_status directly, not from the cart-add button state. The cart button can be disabled for reasons unrelated to inventory.

"Item group ID mismatch"

You added a new variation to a variable product. The new variation has a different item_group_id than its siblings. Ad sets that targeted "all variants of product X" miss the new one.

Fix: Always derive item_group_id from the parent product's post ID, never from the variation. Verify after every new variation is added.

Products linger after deletion

You delete a product in WooCommerce. It's still showing up in Meta ads two days later. Without a delete signal, Meta keeps serving impressions until its catalog refresh — which on a hosted-feed setup can be the next pull cycle.

Fix: Use a webhook-driven sync that pushes deletions in real time, or include availability: out of stock on removed products as a stopgap until the next full feed refresh.

Real-time vs scheduled — when does it cost you money?

Three failure modes map directly to revenue lost on stale data:

  • Stale price. A flash sale starts in WooCommerce. Meta reflects it after the next sync. During the lag, ads show yesterday's price; click-to-checkout expectation breaks; conversion rate drops.
  • Stale inventory. A product sells out. Meta keeps spending budget on it until the next sync.
  • Stale removal. A product is deleted (compliance issue, recall). For regulated categories — supplements, alcohol, restricted goods — this turns into a compliance issue, not just a marketing one.

If your catalog has flash sales, limited inventory, or compliance-sensitive products, real-time sync isn't a nice-to-have. For a stable catalog with daily-or-slower updates, scheduled feeds are fine.

How SnowPipe handles WooCommerce → Facebook Catalog

SnowPipe connects to WooCommerce via the REST API, pulls products, variations, attributes, categories, and meta — including ACF fields and custom taxonomies — and pushes to Meta via the Catalog API.

The relevant pieces here:

  • Real-time and scheduled in one pipeline. WooCommerce webhooks trigger immediate updates to Facebook Catalog for product changes; a scheduled full sync runs in the background to catch missed events. Both are wired by default.
  • Variation flattening built in. Variable products come out as Facebook items with item_group_id derived from the parent post. Each variation gets its own image_link from variation images when available, falling back to the parent featured image.
  • Custom meta and ACF mapping. The smart template handles standard fields. Anything custom — ACF GTIN, Perfect Brands taxonomy, your own meta key for material — gets mapped through a visual mapper without code.
  • Removed products are pushed as deletions. When a product is deleted or trashed in WooCommerce, SnowPipe issues a Catalog API delete to Meta, not just a stale out of stock flag. Orphans don't accumulate.
  • Runs outside WordPress. Large catalogs don't lock up WP-cron. Stores in the 50,000+ SKU range stream through with constant memory.

The same WooCommerce connection feeds Google Merchant Center and TikTok Shop from one source — so the mapping work you do for Meta extends across channels without redoing it.


Ready to fix this for good?

Try SnowPipe free — connect your WooCommerce store and get an accurate Facebook Catalog 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.