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.

S01

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.

S02

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.

S03

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.

S04

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.

S05

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.

S06

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'.

S07

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.

S08

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.

S09

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.

P01

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.

P02

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.

P03

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.

P04

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.

P05

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'.

P06

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.

P07

Description shorter than 200 characters

Thin descriptions rank badly.

Same sort, on the description field.

P08

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.

P09

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.

P26

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.

P10

No main image

Blocking everywhere.

Filter your product list for a missing featured image.

P11

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.

P12

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.

P13

No price

Blocking.

Usually a variable product whose variations were never priced.

P14

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.

P25

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

P16

No stock status

Blocking.

Every item needs in stock or out of stock, explicitly.

P15

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

P17

No category

Costs position.

Uncategorised products are usually imports.

P18

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.

P19

Variation with no parent

Blocking.

Orphans are left behind by deleted parents and are invisible in the admin list.

P20

Incomplete dimensions or weight

Costs position, skipped for downloads.

Needed for shipping estimates. Check all four values, not just weight.

P21

Not published

Blocking.

Private and draft products get pulled into feeds more often than you would think.

P22

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.

P23

Intangible product

Blocking on channels that take physical goods only.

Downloadable and virtual products. Exclude them deliberately rather than letting them be rejected.

P24

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.