A wholesaler XML import works when, before you load the first product, you settle three things: what the permanent product key is, where prices come from, and what wins on every later update. The import itself is the easy part - click, wait, and you have a few thousand products. Trouble starts in week two, when the supplier changes the file structure and your hand-edited descriptions get overwritten by the supplier’s version.
Below is how I set these integrations up. The examples are WooCommerce and Baselinker (Baselinker is the order-management hub most Polish stores run on), but the logic is the same on any platform.
What a wholesaler XML feed actually is
A wholesaler XML feed is a text listing of their catalogue at a fixed web address - name, supplier index, purchase price, stock level, category, images and attributes. The supplier refreshes it periodically, and your store or Baselinker polls that address on a schedule and pulls the contents in. The formats you will meet in practice:
| Format | Note |
|---|---|
| XML | most common and most capacious - handles variants and multiple images |
| CSV / XLSX | simple, but poor with variants and image galleries |
| API | best for live stock and prices, needs an integration |
| Platform-specific feed | convenient, but simplified next to a full XML |
There is no single standard - two suppliers in the same industry will name the same field differently. That is why the work is all in the mapping, not in fetching the file.
The product key - the decision everything else hangs on
The product key is the one field the system uses to recognise that a product in the feed and a product in your store are the same item. Without a stable key, every update creates duplicates instead of replacing data - which is how you end up with a store holding three times more products than the supplier. Candidates, best first:
- Supplier index (supplier SKU) - stable for years, unique within one supplier. In Baselinker this is the “index” everything else attaches to
- EAN / barcode - good for branded goods and when you plan to add a second supplier for the same product
- Your own SKU built from a supplier prefix plus their index, for example
AB-10233- best with two or more suppliers, because you see the source at a glance - Product name - never. Names change every quarter, and every change produces a duplicate
Once chosen, you do not change the key. Changing it in a live store means importing from scratch and merging order history by hand.
Mapping categories and attributes
Mapping is a translation table: the supplier’s category on the left, yours on the right. You do it once, before the first full import, and you cannot skip this stage without paying for it later. What you decide:
- Categories - suppliers build their tree around a warehouse, not around a customer. Three levels like “Electronics > Cables > HDMI cables” may be a single category on your side. Merge, do not copy one to one
- Attributes - colour, size, power rating. These drive your filters, so normalise the values immediately: “black”, “Black” and “BLACK” all have to land in one value
- Manufacturer - a separate field, not a fragment of the name. People search by brand
- Products to skip - oversized items, hazardous goods, prices below your profitability threshold. Filter on the way in, do not delete by hand after the import
Keep the mapping outside your head - in a spreadsheet or in the integration config; six months later, when you add a second supplier, it saves you a day. The underlying mechanics of loading data into a store are a topic of their own on the blog.
Prices - markups, tiers and rounding
The price in your store is never the supplier price copied straight across - it is the output of a rule you set once and that recalculates on every update. The minimum set that works in most stores:
- Tiered markup instead of a single percentage - a cheap accessory needs a higher percentage than expensive equipment, otherwise you either earn pennies or price yourself out
- Minimum margin as an amount - a floor in złoty below which the percentage markup cannot go
- Handling cost added in - packing, gateway fee, returns. That is a real per-unit cost
- Rounding the ending - to .99 or to whole złoty; a detail, but it tidies up the catalogue
- Per-item exceptions - a list of indexes with a manually set price that the automation never touches
The last point matters more than it looks: without an exception mechanism, every manual price correction lives until the next update and then vanishes. I set it up as a “price locked” field on the product - the automation sees it and skips it. And if you also sell wholesale, contractor pricing is a separate layer and should not be mixed with the retail markup - that is B2B ordering portal logic.
Images, descriptions and what gets overwritten
Images and descriptions are the heaviest part of an import - literally, because they eat time and server space. The rule I apply: take images from the supplier, write descriptions yourself.
- Images - fetch once, on the first import, and do not refresh them on every sync. Resizing and converting to WebP on upload is mandatory - otherwise a year later you have tens of gigabytes and a store that crawls
- Descriptions - the supplier gives everyone the same text. Your key products need their own copy, so the description is a field the automation never touches after the first import
- Names - worth cleaning up once, stripping warehouse codes like “(2 pcs/pack) NEW”
The practical model: on every update the automation refreshes stock level, purchase price and availability status only. Every other field is flagged as “mine” and stays untouched.
Variants (size, colour) need checking before the first import: each variation must have its own index, otherwise you cannot sync stock per size, and the file must carry a grouping field that glues the variations into one product. Without such a field you are left selling variations separately or gluing them by a fragment of the name - and that is development work.
Update schedule - what, and how often
Not everything refreshes at the same rhythm. Splitting it into separate jobs is cheaper for the server and safer for the data.
| What | How often | Why |
|---|---|---|
| Stock levels | every 15-60 minutes | cancelled orders come from selling goods that are already gone |
| Purchase prices | 1-2 times a day | they change less often, and recalculation loads the store |
| New products | once a day, overnight | a new arrival can wait until morning |
| Images and descriptions | first import only | refreshing overwrites your work and fills the disk |
| Discontinued products | once a day | do not delete - set them unavailable so you keep the URL |
That last row matters: deleting products that vanished from the supplier feed is a fast route to hundreds of URLs that stop existing. It is safer to hide the product and leave a page explaining it is unavailable - I go into that at more length in the piece on inventory sync.
Baselinker or importing straight into the store
Baselinker makes sense when you sell in several places at once - your own store plus Allegro (Poland’s dominant marketplace) and other channels. Then one stock pool feeds every channel, and that is where you connect the marketplace to the supplier too. Importing straight into WooCommerce makes sense when the store is your only channel - fewer layers, fewer subscriptions, fewer places for things to drift.
| Criterion | Baselinker as the hub | Import straight into WooCommerce |
|---|---|---|
| Several sales channels | natural, that is what it was built for | has to be added on |
| Ready-made supplier integrations | long list in the panel | depends on the plugin or a custom integration |
| Fixed cost | subscription that grows with order volume | plugin cost or a one-off build |
| Unusual pricing and mapping logic | limited to what the panel offers | anything, because it is your code |
| Dependence on a single service provider | high | low |
Tool pricing changes regularly, so check the current tiers at the source before you decide. The tool comparison I laid out in Baselinker alternatives, and automation at the API level in Baselinker API and automation.
Five mistakes I see most often
- Importing without a sample run - I load 20-50 products first, look at them in the store, and only then release the full catalogue
- No backup before the import - rolling back a badly mapped import without one costs days
- Updating every 5 minutes on shared hosting - the store slows down and can stop responding at peak
- No monitoring of the feed - the supplier changes the XML structure without warning and the integration quietly stops working
- Publishing immediately - let new products arrive as drafts, for review
How this usually goes with me
I start with a free diagnosis: I look at your supplier’s feed, at the store and at where else you sell. After that conversation it is clear whether a good plugin and solid mapping are enough, or whether you need an integration written around your pricing logic - and which one is cheaper to run over the next two years.
For larger work you get a fixed bid in writing before we start: what gets mapped, what gets updated, how often, and what happens when the supplier changes format. Projects like this usually land in the range of 5,000-10,000 PLN net, and if the integration is meant to live and be watched afterwards, ongoing support starts at 1,000 PLN net per month. I quote after looking, never blind.
FAQ
How many products can WooCommerce handle? Tens of thousands, provided the store sits on hosting prepared for a catalogue that size and has its filters and search set up sensibly. The limit is not the product count but the number of variants and attributes - those hit the database hardest. Above a few thousand items it is worth planning store optimization alongside the import, not afterwards.
Will importing from a supplier hurt my SEO? The import itself does not, but copied manufacturer descriptions can - dozens of stores end up with identical text. So for the products you care about you write your own copy and leave the rest of the catalogue as it is. Nobody can guarantee specific rankings, because they depend on the competition in your niche.
What do I do when the supplier changes the XML structure? You fix the mapping on your side - and ideally you learn about the change from an alert, not from a customer who ordered something out of stock. That is why every integration I build gets a notification when the feed stops responding or the item count jumps.
Can I import from two suppliers at once? Yes, and it is a common scenario, but then the product key needs a supplier prefix and the system needs a rule deciding which supplier to source from when both have the item - usually purchase price or delivery time. Without that rule the catalogue starts drifting in the first month.
Running a store where something does not work the way it should? I build and rebuild WooCommerce stores - from a single fix to reworking the whole sales flow. Tell me what you are dealing with and I will send back a scope and a price.