Key takeaways
- Every item is its own product, so row counts are 10 to 50 times higher than a normal shop of the same value.
- Grade and condition are properties of a unique item, not variants. Modelling them as options breaks the catalogue.
- Catalogue references (KM, Pick, Friedberg) live in custom fields that default exports silently drop.
- Migrate sold items as out-of-stock rather than deleting them. The archive is an asset.
Most migration advice assumes a shop that sells the same t-shirt a thousand times. Collectibles work the opposite way: a thousand items, each sold once, each slightly different, each with a photograph that cannot be swapped for a stock image.
That difference breaks a surprising amount of standard tooling. Here is what actually goes wrong and how to get a numismatic or collectibles catalogue across intact.
Why your catalogue is bigger than the tools expect
A clothing retailer with 300 products and 8 sizes each has 300 products and 2,400 variants. Platforms are built and tested for that shape.
A dealer with 12,000 individual coins has 12,000 products and no variants at all. Same inventory value, forty times the product rows. Every product-level operation, indexing, exporting, importing, sitemap generation, runs forty times as often.
This is why the built-in exporters that work fine for an ordinary shop fall over here. WooCommerce's exporter drives the job from the browser in AJAX batches; on a catalogue this size it reliably hits a PHP timeout partway through and hands you a truncated file that looks complete.
Always check the row count. A partial export is indistinguishable from a full one until you compare against the product count in your admin. On a 12,000 item catalogue, losing the last 3,000 rows is easy to miss and expensive to discover after you have decommissioned the old store.
Three routes that hold up at this size:
- Export by category. Slow and manual, but the built-in exporter can usually manage 500 to 2,000 rows at a time. Concatenate afterwards.
- WP-CLI. Runs outside the web server, so request timeouts do not apply. The right answer if you have SSH.
- Server-side extraction. Reads the storefront rather than driving your admin, so there is no browser session to time out. This is what Scrapify does, and it is the only one of the three that works when you do not have admin access to the source.
The full comparison is in how to export all WooCommerce products to CSV.
Grade is not a variant
This is the modelling mistake that causes the most damage, and it is easy to make because platforms nudge you toward it.
A 1928 $5 note in VF and the same note in AU are two different physical objects, each with one in stock, each with its own photograph and its own price. They are not two variants of one product.
Model them as variants and you get:
- One product page showing one photograph, when the whole purchase decision rests on seeing that specific note.
- Stock that reads as "3 in stock" when you have three different items at three different grades and prices.
- A single URL competing for searches that should have landed on three distinct pages.
Model them correctly and each item is its own simple product with a quantity of one, and grade lives in an attribute or metafield.
In WooCommerce
Use a product attribute with visible set to 1 and in variations set to 0. That puts grade in the Additional Information table and makes it available to filtered navigation without turning the product into a variable one.
Type,SKU,Name,Regular price,Stock,Attribute 1 name,Attribute 1 value(s),Attribute 1 visible,Attribute 1 global
simple,FR-1950-D-VF,1928 $5 Federal Reserve Note Cleveland,340.00,1,"Grade","VF-25",1,1
simple,FR-1950-D-AU,1928 $5 Federal Reserve Note Cleveland,890.00,1,"Grade","AU-50",1,1
Set the attribute global flag to 1 so grades become a shared taxonomy. That is what lets a customer filter the whole shop by grade, which is the single most useful piece of navigation a collectibles site can offer.
In Shopify
Use a metafield. Be aware of the tradeoff: Shopify metafields are not searchable by the storefront search by default, so a customer typing "MS-65" will not find your MS-65 coins unless you also put it in the title or tags.
For that reason many dealers fold grade into the title on Shopify (1881-S Morgan Dollar MS-65) and keep the metafield as the structured copy for filtering apps. It is duplication, and it is the pragmatic choice.
Export a six-figure catalogue without the timeouts
Scrapify reads the storefront server-side, so catalogue size does not depend on your browser staying awake. WooCommerce CSV, Shopify CSV or Excel.
The fields that silently disappear
Catalogue references are what make a collectibles listing findable and credible, and they are exactly what a default export drops, because they are almost never core platform fields.
| Field | Typically stored as | Survives a default export? |
|---|---|---|
| KM / Krause number | Custom field | No |
| Pick number (banknotes) | Custom field | No |
| Friedberg number | Custom field | No |
| Grading service and cert number | Custom field | No |
| Year / date | Attribute or custom field | Sometimes |
| Mint mark | Attribute | Usually |
| Metal, weight, diameter | Attribute | Usually |
| Provenance / pedigree | Custom field or description | No |
In WooCommerce, tick "Yes, export all custom meta" on the export screen. It makes the file much larger and much more useful. On import, each one maps to a meta: column, covered in the WooCommerce CSV schema explained.
Get the exact key names from your own data. Export a single item that already has every field populated, look at the column headers the exporter emits, and use those verbatim. A typo in a meta: key does not error, it silently writes meta that nothing reads.
SKU strategy for one-of-one items
With unique items your SKU is doing more work than in normal retail: it is the only stable identifier tying an item to its photographs, its history and any future re-import.
What works:
- Make it meaningful and unique.
FR-1950-D-VF-0031beatsPROD-8842when you are reconciling a spreadsheet against physical stock. - Never reuse one. When an item sells, that SKU is spent. Reusing it attaches the sold item's history to a different object.
- Include the certification number for slabbed material. It is globally unique, which makes deduplication trivial.
- Assign one to everything before migrating. Items with a blank SKU cannot be matched on re-import, so any correction pass creates duplicates instead of updating. On a 12,000 item catalogue that is not recoverable by hand.
Images are the product
In ordinary retail a missing photograph is untidy. Here the photograph is the item: nobody buys a graded coin from a stock image, because the whole point is the condition of that specific piece.
Two things to get right:
Obverse and reverse both matter. Most collectibles items carry at least two images and often four. On a 12,000 item catalogue that is 30,000 or more image fetches during import. WooCommerce downloads them synchronously inside the import request, which is why image-heavy imports need batches of 200 products rather than 2,000.
Confirm every image landed before decommissioning the old host. Exports carry image URLs, not files, and those URLs point at the old domain. Filter for products with no image and expect zero results. Once the old host is gone, so are the photographs, and re-shooting 12,000 items is not a recovery plan.
Do not delete sold items
The instinct is to migrate only current stock. For collectibles that throws away one of your most valuable assets.
Sold archive pages:
- Accumulate long-tail search traffic. Someone searching a specific Pick number lands on your sold example, then browses what you do have.
- Demonstrate depth. A dealer with 400 live items and 6,000 sold reads as established. One with 400 items and nothing else reads as new.
- Become a price reference collectors return to, which is repeat traffic you do not pay for.
Migrate them as out of stock rather than deleting them, so the URLs survive with whatever ranking they earned. In WooCommerce set In stock? to 0 and leave the product published. In Shopify set inventory to 0 with the policy set to deny.
Before you switch over
- Product count matches the source exactly, including sold and archived items.
- Zero products without a featured image, and the media library count is roughly your expected total.
- Spot check 20 items across different categories for grade, catalogue reference, cert number and price.
- Grade filtering works on the front end, meaning the attribute imported as a global taxonomy rather than a per-product string.
- No product has a blank SKU.
- Sold items are reachable at their URLs and show as unavailable rather than 404.
- Redirects in place and returning 301, verified with a header checker rather than by clicking.
If the catalogue is large enough that this reads like a fortnight of work, our migration team handles the extraction, the field mapping and the verification, and hands back a store that has already passed this list.