Skip to content
MousaBatarseh
Back to all notes

· By Mousa Batarseh

How to Bulk Update Prices in WooCommerce Without Breaking the Store

A vendor sends a new price list on a Thursday afternoon and wants it live by Monday. Four hundred rows, maybe more. If you need to bulk update prices in WooCommerce, the import itself is the easy part. The hard part is making sure the four hundred numbers you push are the four hundred numbers you meant to push.

I ran pricing on the Universal Wholesale store for years, and later handled catalog and pricing on a wholesale B2B site at Wild Bill’s Tobacco. The tools changed a little between jobs. The failure modes never did. A price lands on the wrong SKU, a sale price sticks around after the promo ends, or a column of decimals turns into whole numbers because Excel decided it knew better. Here is the process I use so none of that reaches a customer.

Start with an export, not the vendor’s file

The vendor’s price list is not your catalog. Their SKUs might have extra zeros, different prefixes, or a pack size baked into the code that your store keeps in an attribute. So I never start by importing their sheet. I start by exporting the current products from WooCommerce with at least these columns: ID, SKU, name, type, parent, regular price, sale price.

That export is the truth about what the store looks like right now. I save it untouched as a backup, then make a working copy. If anything goes wrong later, I can re-import the backup and be back where I started in minutes.

How do I bulk update prices in WooCommerce with a CSV?

This is the question most people are searching for, and the short answer is the built-in product importer under Products, Import. Upload a CSV, check the box to update existing products, and map the columns. WooCommerce matches rows by ID or SKU. Plugins like the WebToffee importer or the Price and Stock import extension do the same job with more options, but the core flow is identical.

What the tutorials skip is that the importer will happily update any field you map. If your file has a stray name column and you map it, you just renamed products. So my rule is simple: the import file contains only the matching key and the fields I’m changing. For a price update that means SKU or ID, regular price, and sale price if I’m touching it. Nothing else goes in the file.

Match the new prices in Excel first

In my working copy I pull the vendor’s new price next to each row with XLOOKUP on SKU. Anything that comes back as not found goes on a separate tab. Those are usually one of three things: a SKU the vendor renamed, a product we don’t carry, or a typo on one side. I resolve every one of them by hand before moving on. I don’t let the importer guess.

Variable products need extra care. The parent row has no price of its own. Prices live on the variation rows, so if your vendor quotes a price per item and you sell by the case, the math has to happen before the import, on the variation row.

Build a check column and sort by it

This is the step that has saved me the most grief. Next to the new price I add two columns: the difference in dollars and the difference as a percent of the old price. Then I sort by the percent column, largest to smallest.

A real price list moves in a fairly tight band. When one row jumps far beyond the rest, or drops toward zero, it is almost always a mistake. A case price got matched to a single unit, a decimal slipped, or two SKUs got crossed. Sorting puts those rows at the top where I can’t miss them. I fix them or confirm them with the vendor, and only then does the file move forward.

I also filter for blanks and zeros in the new price column. A blank regular price on import can leave a product with no price, which on most themes means no add to cart button.

Watch the sale price column

Sale prices cause more trouble than regular prices. If a product has an active sale price and you raise the regular price, the customer still sees the old sale price. Sometimes that’s what you want. Often it’s a leftover from a promo that should have ended.

Before a big update I filter the export for any row with a sale price and decide row by row: keep it, clear it, or recalculate it. If I’m scheduling a promo, I use the sale start and end date fields so the price reverts on its own instead of relying on me to remember.

Test on five rows before the full file

I copy five rows into a separate CSV: a simple product, a variation, one with a sale price, one with a big change, and one with a small change. I import those five and check them on the live product pages, logged out, in a private window. Cart and checkout too, because some pricing plugins apply rules after the product page.

If those five look right, the mapping is right, and the full import is just more of the same.

Run the import, then spot check

  1. Put the store in a quiet window if you can. Early morning works for most retail sites.
  2. Import the full file with update existing products checked.
  3. Read the import summary. The count of updated rows should match your row count. Skipped rows mean something didn’t match.
  4. Export again and compare the new prices against your working file with a quick XLOOKUP. Every row should match exactly.
  5. Open ten random products on the front end, plus the outliers you confirmed earlier.
  6. Clear any page cache so customers aren’t served yesterday’s prices.

That re-export step feels like overkill until the day it catches something. It takes five minutes and turns hope into proof.

What I’d tell anyone doing this the first time

Don’t trust the file, trust the check column. The importer does exactly what you tell it, so the work is in making sure what you tell it is right. Keep the backup export, keep the import file down to the key and the price fields, sort by percent change, and test five rows before four hundred. Do those four things and a price update stops being something you worry about over the weekend.

Have a related task to discuss?

Email Mousa