Field guide
Thirty-five reasons a shopping channel rejects your product, and how to find each one yourself
The usual advice is to open Merchant Center once a week and work through the diagnostics tab. That tells you after the rejection, and a rejected product sells nothing while you wait. Everything below can be checked inside your own shop, before anything is sent.
This is the full list a feed gets judged on, written out so you can work through it by hand. No plugin is needed for any of it. Where a check is tedious to do one product at a time, there is a query you can paste into your database tool.
One distinction first, because most published advice runs the two together. An invalid identifier fails the check digit arithmetic, and arithmetic can find it. An incorrect identifier passes the arithmetic but belongs to some other product, and only the manufacturer's records can settle that. Nothing you run on your own shop can tell you the second.
Nine that stop the whole shop
These are not per product. If one of them is true, the channel has a reason to refuse everything you send, and fixing individual products will not help until it is cleared.
No privacy policy page
Channels require a reachable privacy policy before they will list a seller.
Settings, Privacy. If the page is set but in draft, it does not count. Open it logged out.
No terms page
Same requirement, separate page. A privacy policy does not satisfy it.
Look for a published page linked from your footer. Open it in a private window.
No returns page
The return policy has to exist as a page you can point at, not a line in your terms.
If your return terms live inside the terms page, split them out. The channel asks for a URL.
No return window in days
A number of days is required. Wording like 'reasonable period' is not accepted.
Read your own returns page and check a number appears. Most shops discover it does not.
Currency the channel does not take
Feeds are rejected wholesale on an unsupported currency.
WooCommerce, Settings, General. Supported list includes USD, EUR, GBP, CAD, AUD, JPY, CHF, SEK, NOK, DKK, PLN, CZK, MXN, BRL and others.
You do not ship to the United States
Some channels only accept sellers who ship to the US, whatever your own market is.
WooCommerce, Settings, Shipping. Check whether a zone actually contains US, not just 'everywhere else'.
Your shop sells a prohibited category
Alcohol, adult, weapons, tobacco and similar categories are refused at the shop level.
Read your own category list rather than assuming. A single category can disqualify the account.
Categories not mapped to the channel taxonomy
Your own category names mean nothing to the channel. They need mapping to its taxonomy.
List your product categories and match each to the channel's category list. Unmapped ones lose position rather than being refused.
The site tells search engines to stay out
A shop that blocks indexing is treated as not ready to be listed.
Settings, Reading. If 'Discourage search engines' is ticked, nothing else matters. This is the single most common one on a shop that was recently launched.
Four about identifiers
This group causes the rejections people find hardest to diagnose, because the product looks completely normal on your own screens.
No barcode at all
Costs position rather than blocking. A product with no identifier is harder to match.
If a product genuinely has no barcode, that is allowed. Say so with the channel's identifier flag rather than inventing a number. An invented number is worse than none.
The barcode fails its check digit
This is the one worth your attention. It is filled in, it is the right length, and it is wrong.
Do the arithmetic. It takes ten seconds by hand, and the method is in the next section.
The barcode is the wrong length
Valid lengths are 8, 12, 13 and 14 digits. Anything else is refused.
Count the digits. The usual cause is a 13 digit code that lost its leading zero to a spreadsheet.
No brand
Required by some channels for every item, including your own house products.
For your own goods, your shop name is the correct brand. Leaving it empty is not.
Six about words
Titles and descriptions are read by machines before any person sees them.
Title shorter than 20 characters
Too short to match against anything.
Sort your product list by title length. Short ones are usually variants named 'Blue' or 'Large'.
Title does not contain the brand
Costs matching accuracy.
Search each title for its own brand value. Easy to miss on products imported in bulk.
Description shorter than 200 characters
Thin descriptions rank badly.
Same sort, on the description field.
No description at all
Blocking on most channels.
Watch for products where the short description is filled and the main one is empty. They look complete in the editor.
Description carries HTML
Feeds want text. Markup arrives as literal tags.
Compare the raw field against its tag stripped version. Careful here: a lot of tools trim whitespace at the same time, which reports a clean description with a trailing space as containing markup. That mistake is easy to make and we made it ourselves.
Title begins with =, +, - or @
Costs position, and matters for a different reason.
Anyone who opens your feed as a spreadsheet has those cells evaluated as formulas. Do not let a tool silently rewrite the title to fix it, because the channels read the file programmatically and your data should stay yours.
Three about images
The image requirement is stricter than most shop themes need.
No main image
Blocking everywhere.
Filter your product list for a missing featured image.
Fewer than five images in total
Costs position on channels that favour richer galleries.
The main image plus at least four in the gallery. Count the gallery separately, because the featured image is not part of it and it is easy to count one photo twice.
Shortest edge under 800 pixels
Costs position, sometimes blocks.
Check the original upload, not the thumbnail your theme shows. A theme can display a 300 pixel file at full width and it will look fine to you.
Three about price
Two of these are arithmetic mistakes that no shop screen warns you about.
No price
Blocking.
Usually a variable product whose variations were never priced.
Sale price above the regular price
Blocking, and it looks deliberate to the channel.
Compare the two fields. This happens when a regular price is lowered later and the old sale price is left behind.
Price is zero or negative
Blocking.
A zero price is often intentional in a shop and never acceptable in a feed. Decide whether those products should be sent at all.
Two about stock
No stock status
Blocking.
Every item needs in stock or out of stock, explicitly.
Quantity not tracked
Costs position on channels that want the number.
Stock management off means you can say in stock but not how many. Some channels use the number.
Eight about the product itself
No category
Costs position.
Uncategorised products are usually imports.
Variable product without colour or size
Costs position.
Only applies to variable products. A size attribute named 'Groesse' or 'talla' will not be recognised, so map it.
Variation with no parent
Blocking.
Orphans are left behind by deleted parents and are invisible in the admin list.
Incomplete dimensions or weight
Costs position, skipped for downloads.
Needed for shipping estimates. Check all four values, not just weight.
Not published
Blocking.
Private and draft products get pulled into feeds more often than you would think.
Prohibited product
Blocking, and repeated attempts risk the account.
Match on whole words only. A naive text search flags a gunmetal grey lamp as a weapon, which is the kind of false alarm that makes people stop reading their own reports.
Intangible product
Blocking on channels that take physical goods only.
Downloadable and virtual products. Exclude them deliberately rather than letting them be rejected.
No condition
Costs position.
New, refurbished or used. If your whole shop is one of these, set a default instead of editing every product.
The arithmetic, so you can do it without any tool
Every barcode carries its last digit as a checksum of the ones before it. That is the whole point of the format, and it is why a single mistyped digit can be caught with nothing but addition.
Take the digits before the last one. Reading from the right, multiply alternately by 3 and 1, starting with 3. Add the results. Round that total up to the next multiple of ten, and the difference is the check digit.
Take 501234567890 and check its last digit, 0.
Body: 50123456789
From the right: 9x3 + 8x1 + 7x3 + 6x1 + 5x3 + 4x1 + 3x3 + 2x1 + 1x3 + 0x1 + 5x3
= 27 + 8 + 21 + 6 + 15 + 4 + 9 + 2 + 3 + 0 + 15 = 110
110 is already a multiple of ten, so the check digit is 0. It matches.
Change one digit anywhere in the body and the total stops landing on a multiple of ten.
-- Every product whose barcode fails the arithmetic.
-- WooCommerce 9.2 and later store the barcode in _global_unique_id.
-- Older shops and most third party plugins use their own key, so check
-- yours first with: SELECT DISTINCT meta_key FROM wp_postmeta
-- WHERE meta_key REGEXP 'gtin|ean|upc|barcode';
SELECT p.ID, p.post_title, m.meta_value AS gtin
FROM wp_posts p
JOIN wp_postmeta m ON m.post_id = p.ID AND m.meta_key = '_global_unique_id'
WHERE p.post_type IN ('product','product_variation')
AND m.meta_value <> ''
AND CHAR_LENGTH(m.meta_value) IN (8,12,13,14)
AND (
10 - (
(SELECT SUM(
CAST(SUBSTRING(REVERSE(LEFT(m.meta_value, CHAR_LENGTH(m.meta_value)-1)), n, 1) AS UNSIGNED)
* IF(n % 2 = 1, 3, 1))
FROM (SELECT 1 n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
UNION SELECT 11 UNION SELECT 12 UNION SELECT 13) d
WHERE n <= CHAR_LENGTH(m.meta_value) - 1
) % 10
) % 10 <> CAST(RIGHT(m.meta_value, 1) AS UNSIGNED)
);
It reads and changes nothing, so it is safe to run on a live shop. On the shop we tested it against it returned one product out of three: a 13 digit code that looked entirely normal, while correctly passing a 14 digit code with a leading zero and a 12 digit UPC.
One limit worth knowing. The query assumes the field holds digits only. If your shop stores barcodes with spaces or dashes, strip them before comparing, or the length test will reject codes that are actually fine. That is a real trap: a check that quietly skips half your catalogue is worse than no check, because it reports clean.
What to do with the list
Work the shop level nine first. While any of those is true the per product work is wasted, because the channel has a reason to refuse everything anyway.
Then the blocking ones, because those products are currently earning nothing. The rest cost position rather than presence, and position can wait until the shop is actually listed.
If you would rather not run any of this by hand, we build a plugin that does the same checks on a schedule. It is not needed for anything above. The arithmetic is the arithmetic.