CFCSV Forge

Wholesaler CSV to Shopify: converting a supplier price list

There is no standard for supplier spreadsheets. What there is instead is a recurring set of defects — semicolon delimiters, latin1 encoding, decimal commas, SKUs that Excel ate — and each one has a specific fix.

Open the tool with this presetField names are a best-effort starting point; adjust them to your sheet.

Start by assuming the file is not what it says it is

A file named .csv from a European supplier is usually semicolon-delimited, because that is what Excel writes in a locale where the comma is the decimal mark. It may be encoded windows-1252 rather than UTF-8, or UTF-16 if it was saved as “Unicode Text”. It may have a title banner and a blank row above the real header. All four are detected here and reported in the preview — check the delimiter and encoding line before you trust the mapping, because a wrong delimiter guess shows up as one giant column.

Pitfall 1: leading zeros are already gone

If your supplier sent an .xlsx and someone opened and re-saved it, SKUs like 0042 and EANs like 0400638133393 may have been stored as numbers and lost their leading zeros, or turned into 4.00638E+12. No converter can recover that — the information is gone from the file.

This tool reads every cell as text, so nothing is lost here. But if the damage happened before you received the file, ask for it again as CSV, and do not open it in Excel on the way. Spot-check the preview: a barcode column showing scientific notation means you need a fresh file.

Pitfall 2: cost, trade, net, RRP, MSRP

A trade price list typically gives you a cost column (Trade Price, Net, Wholesale, Cost) and a recommended retail column (RRP, MSRP). Shopify wants three distinct things:

  • Price — what you actually charge. This is a decision, not a column that exists in the file.
  • Compare-at price — the reference price shown struck through. RRP belongs here, if you intend to show it.
  • Cost per item — your cost, used for margin reporting and never shown to customers. The trade price belongs here.

Mapping trade price to Price is the error that publishes your wholesale cost as retail. The preset instead derives Price from cost with the cost × markup formula — 2.4× rounded to .99 by default — and puts RRP in Compare-at price. Change the multiplier per supplier; a blank Price cell is not a safe default because Shopify imports it as 0.00 rather than failing.

Pitfall 3: “€1.234,50” is not a number

Shopify’s money columns accept digits and a dot. Nothing else. European sheets break this three ways at once: a currency symbol, a dot as the thousand separator, and a comma as the decimal mark. €1.234,50 has to become 1234.50 — note that a naive “strip the dots” would give you 123450.

Price cells are normalised automatically by reading the rightmost separator as the decimal mark, so both 1.234,50 and 1,234.50 resolve to 1234.50. Anything genuinely unparseable (“POA”, “call us”, an empty cell) is reported as a warning rather than silently becoming zero.

Pitfall 4: no product/variant structure at all

Most price lists are one row per orderable item, with size and colour baked into a description string: “Camp Mug 350ml Blue”. There is no parent column and no option columns, so every row becomes its own Shopify product. That is a legitimate outcome — a simple product leaves all six option columns blank and Shopify creates the default variant itself.

If you want variants, the source needs a column that groups the rows (a parent article number, or a base SKU where MUG-350-BLU and MUG-350-RED share MUG-350) and columns holding the individual option values. If the sheet has neither, that is a spreadsheet editing job before conversion, not a mapping problem. Import as separate products first if you need the catalogue live; merging later is possible in the Shopify admin.

Pitfall 5: images that Shopify cannot fetch

Shopify downloads image URLs at import time over http(s), so they must be publicly reachable right then. Three common failures: bare filenames (mug-01.jpg) with the real host documented only in an email; URLs behind a login or a hotlink block; and protocol-relative URLs starting //, which Shopify does not resolve. All three are flagged as errors before export, because a failed image fetch during import is reported per-row and tedious to reconcile afterwards.

Suppliers also often pack a gallery into one cell with semicolons, commas, pipes or newlines. Use the split image list formula and the extra image rows are generated with incrementing positions.

Import as drafts

The preset sets Status: draft and Published on online store: FALSE deliberately. Supplier data needs human review — titles are warehouse shorthand, descriptions are specification dumps, and categories are the supplier’s internal taxonomy. Import as drafts, fix the first twenty products, then publish.

One more thing worth checking before a large import: whether the supplier expects you to re-import this file weekly for stock and price updates. If so, the column that will stay stable across those files — usually the supplier’s article number — is what your handle should be derived from, not the title. Titles get edited; article numbers do not, and a changed handle creates a duplicate product instead of updating the existing one.

What the preset maps

Product Name → Title, Item No → SKU, Brand → Vendor, Trade Price → Cost per item and → Price via 2.4× markup rounded to .99, RRP → Compare-at price, EAN → Variant Barcodes, Stock → Inventory quantity, Weight → Weight value (grams), Images → Product image URL with splitting, Category → Type.

These header names are a best-effort guess, not a verified schema — no wholesaler standard exists to verify against. Treat the preset as a shape to adjust: the auto-matcher will usually do better on your actual headers, and it recognises common aliases (article/ref/code for SKU; wholesale/trade/net for cost; qty/stock/on hand for inventory; ean/upc/gtin for barcodes) with a confidence badge on each guess.

Before you upload to Shopify

  • Import into a development store or a draft-status batch first. Set the default status to draft in the tool and nothing goes live by accident.
  • Shopify caps a product CSV at 15 MB. Bigger catalogues are split into numbered parts, and a product is never split across two files.
  • Overwriting existing products by handle is destructive: a blank cell can erase data that is currently there. Export your live products first if you are updating rather than creating.

Full column contract: the Shopify product CSV format, column by column. CSV Forge is not affiliated with Shopify Inc.