Key takeaways

  • Missing GTIN or MPN is the most common reason individual products get disapproved.
  • Google compares your feed against your landing page. A price mismatch can suspend the whole account.
  • Every variant needs its own id and a shared item_group_id.
  • A scheduled fetch URL beats a manual upload, because the failure mode of "I forgot" is account suspension.

Merchant Center rejections are rarely mysterious. Google publishes exactly what it wants, checks it mechanically, and disapproves anything that does not match. Almost every rejection falls into one of four buckets: a missing required attribute, a missing product identifier, a mismatch between the feed and the landing page, or a policy issue with the product itself.

Here is how to build a WooCommerce feed that clears all four.

The required attributes

For a standard retail product sold online:

AttributeRequirementNotes
idRequiredUnique and permanent. Use the SKU, never a database ID that changes on re-import.
titleRequired150 characters max. Brand plus product plus key attribute performs best.
descriptionRequired5,000 characters max. Strip HTML. No promotional text.
linkRequiredFull product URL including https. Variant-specific where applicable.
image_linkRequiredMinimum 100x100, no watermarks, no promotional overlays.
availabilityRequiredin_stock, out_of_stock, preorder, backorder
priceRequiredValue plus currency: 24.99 USD. Must match the landing page.
brandRequired for mostOmit only for genuinely unbranded goods.
gtin or mpnConditionally requiredSee below. This is the big one.
conditionIf not newnew, refurbished, used

Apparel and accessories add color, size, age_group, gender and size_type. If you sell clothing and skipped these, that is your disapproval.

Product identifiers, the number one rejection cause

Google wants to know which real-world product each listing refers to, so it can group offers and show comparison results. It infers this from unique product identifiers.

The rule:

  • If the product has a manufacturer-assigned GTIN (a UPC, EAN or ISBN), you must supply it. Omitting a GTIN that exists is a disapproval, not a warning.
  • If you manufacture the product yourself and there is genuinely no GTIN, supply brand plus mpn and set identifier_exists to no.
  • Do not invent GTINs. Google validates the check digit, and a wrong one is worse than an absent one.

In WooCommerce, GTIN lives in the barcode field on modern versions, or in a custom field on older ones. If your data came from a migration, check it survived: barcode is one of the fields most commonly dropped in a CSV round trip.

id must be permanent. Google builds performance history against it. If your feed regenerates ids on each import, every product looks brand new every time, and you lose all accumulated performance data. Use the SKU.

Variants

Anything a customer chooses between needs its own feed entry. A shirt in four sizes and three colours is twelve entries, not one.

Each entry needs:

  • Its own unique id, typically the variation SKU.
  • A shared item_group_id across the whole group, typically the parent SKU.
  • Its own link, ideally with the variation pre-selected: ?attribute_pa_size=large.
  • Its own price, availability and image_link where these differ.
  • The distinguishing attributes filled in: size, color, material, pattern.

Submitting only parent products is a common shortcut that costs you impressions, because Google cannot match a size-specific query to a listing that has no size.

Price and availability mismatch

Google crawls your landing pages and compares what it finds against what you submitted. A discrepancy triggers a warning, then a disapproval, and persistent mismatches can suspend the account.

The usual causes are all timing problems:

  • The feed refreshes daily, prices change hourly.
  • A sale started and the feed still carries the old price.
  • Stock ran out and the feed still says in_stock.
  • Currency or tax display differs between feed and page.

This is why refresh frequency is not a nice-to-have. If your prices or stock move, a daily feed is not enough, and a feed you upload by hand is a suspension waiting for a busy week.

Use XML, not a spreadsheet

Merchant Center accepts RSS 2.0 and Atom 1.0 XML from a URL it fetches on a schedule. This is better than uploading a file for reasons that have nothing to do with the format itself:

  • Google pulls on a schedule, so there is nothing to remember.
  • XML has unambiguous encoding and no delimiter problems, which removes an entire class of CSV failure.
  • Nested attributes such as shipping and tax are expressible without inventing column conventions.

A minimal item looks like this:

<item>
  <g:id>NB-TEE-M-BLK</g:id>
  <g:item_group_id>NB-TEE</g:item_group_id>
  <title>Northbound Premium Cotton Tee, Black, Medium</title>
  <description>Heavyweight 240gsm combed cotton tee...</description>
  <link>https://example.com/product/cotton-tee?attribute_pa_size=medium</link>
  <g:image_link>https://example.com/img/tee-black.jpg</g:image_link>
  <g:availability>in_stock</g:availability>
  <g:price>24.99 USD</g:price>
  <g:brand>Northbound</g:brand>
  <g:gtin>0123456789012</g:gtin>
  <g:condition>new</g:condition>
  <g:size>Medium</g:size>
  <g:color>Black</g:color>
</item>

Generating the feed

Which route you need comes down to a single question: where does the catalogue come from?

A Scrapify live feed

Scrape any WooCommerce or Shopify store, save the result as a live feed, and you get an XML URL that refreshes every hour. Point Merchant Center's scheduled fetch at it and the price and availability mismatch problem above stops being something you manage.

This is the option that works when the products are not natively yours: a supplier catalogue, a dropship range, a store you are mirroring. A feed plugin cannot help there, because it can only publish products that already exist in your WordPress database. Scrapify populates the catalogue and publishes the feed, and the same feed URL drives our WordPress import plugin, so one feed both stocks your store and advertises it.

Included on every account: free accounts get 1 feed up to 15 products, Premium raises that to 5 feeds of up to 100,000 products.

A feed plugin

If every product already lives in your WooCommerce database and you only need to reshape it into Google's attribute names, a feed plugin does that job. It reads your existing products and generates an endpoint.

The limits worth knowing before you buy one: it publishes only what is already in your store, it cannot fix missing GTINs or thin descriptions, and refresh frequency is bounded by WP-Cron, which on a low-traffic site fires late or not at all. That last one is how a "daily" feed quietly becomes a weekly one and your account picks up mismatch warnings.

Build it yourself

A WordPress endpoint that queries products and echoes XML. Total control, and you own the maintenance forever. Worth it only if your requirements are genuinely unusual.

A feed that refreshes itself

Turn any store into an hourly auto-refreshing XML feed and point Merchant Center at it. Included on every Scrapify account.

Create a free feed See the plugin guide

Getting approved faster

  1. Submit a 10 product test feed first. Fix what it flags before submitting 5,000 and receiving 5,000 errors.
  2. Complete the account setup. Verified and claimed website, shipping settings, returns policy, tax. Google will not approve products in an incomplete account regardless of feed quality.
  3. Match the landing page exactly. Same price, same currency, same availability, same product.
  4. Fix the Diagnostics tab weekly. Warnings become disapprovals if ignored.
  5. Write titles for search, not for shelves. "Northbound Premium Cotton Tee, Black, Medium" beats "Premium Tee" because it contains the words people type.

One feed, several uses

Once the feed exists it is worth more than Merchant Center alone. The same URL typically feeds Facebook and Instagram catalogues, Pinterest product pins, Bing Merchant Center, affiliate networks, and comparison shopping engines.

Each platform wants slightly different attribute names, but the underlying data is identical, and getting it right once pays out across every channel.

Frequently asked questions

Which attributes does Google Merchant Center require?
For most retail products: id, title, description, link, image_link, availability, price, and either brand plus gtin or brand plus mpn. Apparel adds colour, size, age group and gender. Missing identifiers are the most common reason a product is disapproved rather than the whole feed being rejected.
How often should a Shopping feed refresh?
At minimum daily, and hourly if prices or stock move. Google compares your feed against what it crawls on the landing page, and a mismatch in price or availability can suspend the account. A feed served from a live URL that Google fetches on a schedule is safer than a file you remember to upload.
Do I need a separate feed entry for each variant?
Yes for anything customers choose between, such as size or colour. Each variant needs its own unique id, its own link with the variant selected, and an item_group_id shared across the group so Google knows they belong to the same product.
Can I use an XML feed instead of a spreadsheet?
Yes, and you should. Merchant Center accepts RSS 2.0 and Atom 1.0 XML from a scheduled fetch URL. XML avoids the encoding and delimiter problems that plague CSV, and a fetch URL removes the manual upload step entirely.

Keep reading

WooCommerce How to Bulk Import Products into WooCommerce Without a Spreadsheet Guides How to Stock a New Store With Products in Under an Hour WooCommerce How to Export All WooCommerce Products to CSV: 5 Methods Compared