Bulk Price Editor

Bulk Price Editor for WooCommerce updates the prices of many products in one action. You filter the products, choose how their prices should change, check the result in a preview and apply the update. The update runs in the background, keeps a snapshot of the previous prices and can be reverted in one click. Updates can also be scheduled, with an automatic revert at a later time.

Developers find the hooks, the command line interface and the extension points in the developer documentation.

Installation

↑ Back to top
  1. Download the plugin .zip file from your WooCommerce.com account under My Subscriptions, or use Add to store there.
  2. In WordPress go to Plugins → Add New → Upload Plugin, choose the file and click Install Now.
  3. Click Activate.

The editor is under WooCommerce → Bulk Price Editor. It has four tabs: Editor, Scheduled, History and Settings. No configuration is needed before the first update.

Requirements: WordPress 6.2 or newer, WooCommerce 7.1 or newer and PHP 7.4 or newer. The plugin is compatible with High-Performance Order Storage and the new product editor. The editor is available to administrators; the developer documentation shows how to open it to other roles.

Quick start

↑ Back to top
  1. In Filter Products, open a section and set a filter, for example the category Hoodies under Included Products. The preview table below lists every matching product.
  2. In Edit Prices, pick a method, for example Decrease by percent, and enter a value. The table now shows the current and the new price of every product.
  3. Click Apply changes, check the number of products in the dialog and confirm. The update runs in the background and a notification reports the result.
Category Hoodies, regular prices decreased by 20 percent, and the preview with the current and the new price of each product.

Every update is recorded in the History tab together with the previous prices, so a wrong update can be reverted.

Filters

↑ Back to top

Filters are collapsible sections in the first widget. A product must match every filter you set. Sections that contain a value stay open.

FilterWhat it does
Included ProductsProducts, categories, brands, tags and shipping classes to include. A category or a parent brand includes its children. A variable product includes all of its variations. Products and categories together select both.
Excluded ProductsThe same selections, removed from the result. Exclusions win over inclusions.
Product StatusStock status (in stock, out of stock, on backorder), sale status (on sale or not on sale) and featured products.
Price RangeA minimum and/or a maximum, applied to the regular price or to the sale price. In sale mode, products without a sale price never match.
Date RangeDate added or date modified, from and/or to.
Product TypeSimple, variable, variation and external products. By default simple products, variations and external products are selected, so every variation is listed with its own price.
SKU and NameA partial SKU (the full SKU matches one product) and a text contained in the product name.
Product AttributesOne field per global attribute, for example Color or Size. Values of one attribute are combined with OR, different attributes with AND. Variations match through their own attribute values.

Category, brand, tag and shipping class selections also match the variations of a matching variable product.

Price changes

↑ Back to top

The second widget offers one tab per method. Only the active tab is applied. Every method has separate fields for the regular price and the sale price; an empty field leaves that price unchanged. A value of 0 is a valid price.

MethodResult
Enter new pricesSets the same regular and/or sale price on every selected product.
Remove pricesClears both prices, the regular price only or the sale price only.
Increase by percent, Decrease by percentChanges existing prices by a percentage. Products without the price being changed are skipped. Decreases stop at zero.
Add flat amount, Subtract flat amountChanges existing prices by a fixed amount. Products without the price are skipped. Subtraction stops at zero.
Update by formulaCalculates the new price of each product from its own current values.
Tiered PricingAppears when the Tiered Pricing Table plugin is active, see below.

Formulas

↑ Back to top

Each formula field accepts a number or an expression with + - * /, parentheses and the functions min() and max(). Variables: {regular_price}, {sale_price}, {price} (the active price) and {cost} (the product cost from WooCommerce Cost of Goods or a supported cost plugin).

  • {regular_price} * 0.8 in the sale price field: a sale price 20 percent below the regular price, also on products that had no sale price.
  • {cost} * 1.4: a 40 percent markup on the cost.
  • max({regular_price} * 0.7, 9.99): 30 percent off, but never below 9.99.
  • min({regular_price} + 5, 199): 5 more, capped at 199.

A product that lacks a value used in the formula, for example {cost} on a product without cost data, is skipped for that field. An invalid formula is ignored.

Advanced Options

↑ Back to top

Every method has the same two options:

  • Rounding: 2 decimals, 1 decimal, whole number, or a price ending of .90, .95 or .99 (a calculated 63.74 becomes 63.99). To round existing prices without changing them otherwise, use Add flat amount with 0 and a price ending.
  • Sale dates: set a start and/or an end date of the WooCommerce sale schedule on every selected product, or clear existing schedules. Sale dates can be applied on their own and are restored by a revert.

Preview and apply

↑ Back to top

The preview table

↑ Back to top

The table lists every product matching the filters with image, name and SKU, categories, regular price, sale price, stock status, type and date. As soon as a price change is entered, the price columns show the current and the new price, with the new value highlighted. Products whose price would not change show the current price only. Name, prices, stock status and date are sortable; the table is paginated and refreshes without a page reload. The preview is calculated by the same code that performs the update.

Regular prices before and after a 20 percent decrease. The Price history link under a product opens its change log.

Export CSV downloads the whole preview: every matching product, variations included, with its current prices and the new ones.

Applying

↑ Back to top

Click Apply changes. The dialog states how many products are affected and offers:

  • Apply now: the update starts immediately.
  • Schedule for later: pick the date and time when the update should start.
  • Automatically revert at (optional, for both modes): the previous prices are restored at the given time. A weekend sale is one action: start on Friday evening, revert on Monday morning.

Times are in the site timezone, shown in the dialog. The update always targets the full filtered set, not only the current page of the table.

Schedule for later with an automatic revert.

Background processing

↑ Back to top

Products are processed in chunks of 100 through the WooCommerce Action Scheduler, so large catalogs are updated without timeouts. While an update runs, the editor shows the number of processed products and a progress bar with two buttons: View queue opens the Scheduled Actions screen filtered to the plugin’s jobs, and Stop updating cancels the remaining jobs. Products already processed keep their new prices; a stopped update appears in History and can be reverted. The page refreshes when the update completes.

A storewide update in progress.

Scheduled updates

↑ Back to top

A scheduled update is stored with its filters and price settings and listed in the Scheduled tab until it runs. The product count shown there is an estimate from the time of scheduling; the product list is resolved again when the update starts, so products added or changed in the meantime are included. Cancel removes the scheduled update and its automatic revert; the entry stays visible in History. Scheduled updates and automatic reverts run through the Action Scheduler and need the site cron, like other WooCommerce scheduled actions. Only one update processes at a time; a due update starts when the running one finishes.

A scheduled decrease on T-shirts with an automatic revert.

History and revert

↑ Back to top

Every update is recorded in the History tab with a snapshot of the prices of each affected product before the change. An entry shows when it ran and by whom, what it did, the filters with their values, the number of products and the status. Actions:

  • Revert restores the prices and sale dates of every product the update changed, using the snapshot. Only the fields the update touched are restored. A revert is recorded as its own entry and can be reverted again, which applies the update once more.
  • CSV downloads the snapshot with the prices before and after the update.
  • Delete removes the entry and its snapshot; the update can no longer be reverted.

Reverting runs in the background with the same progress screen. Stopped updates can be reverted; only the processed products are restored. The history keeps the 50 most recent updates.

One update is marked as reverted; the revert is listed as its own entry.

Templates

↑ Back to top

Save a set of filters, optionally together with the price change, as a template:

  • Save as template saves the current filters under a name. With Also save the selected price modification checked, the method and its values are stored too, which makes the template a complete job that can be re-run or scheduled.
  • Select template lists the saved templates; selecting one fills the filters and, for a job, the price change.
  • Update template saves changes back to the active template. Remove deletes it.

Templates are shared by all administrators. The active template is part of the page URL, so it can be bookmarked. Jobs can also be run from the command line, see Tools.

Saving the filters and the price change together as a reusable job.

Price change tracking

↑ Back to top

Independently of bulk updates, the plugin records every change of the regular or sale price of a product: manual edits on the product screen, imports, the REST API, other plugins and bulk updates, each with date, source and user.

  • On the product edit screen a Price history link with the number of recorded changes sits next to the Schedule link under the sale price, and inside the pricing row of every variation.
  • In the preview table the same link appears under each product.
  • The list shows each change with its old and new value and its source; bulk updates and reverts link to their History entry.

Tracking is on by default. The Settings tab turns it off and sets how many changes are kept per product (100 by default).

Manual edits, a REST API change and a bulk update in the price history of one product.

Variable products

↑ Back to top

With the default product types, each variation appears as its own row with its own prices, so every change is visible per variation. If the Variable product type is selected and a variable product matches the filters, the change is applied to all of its variations. A variable product row shows its price range; the new prices appear on the variation rows.

Tiered Pricing Table

↑ Back to top

When the Tiered Pricing Table plugin is active, a Tiered Pricing tab is added to the price methods and a Tiered Pricing column to the preview table.

  • Set new tiers defines a set of quantity tiers, fixed prices or percentage discounts, and applies it to all selected products. An empty builder removes the tiered pricing from the selected products.
  • Update existing by % scales existing tier prices by a percentage. Fixed prices are recalculated; percentage discounts are adjusted and capped at 100 percent. Products without tiers are left unchanged.

The preview column shows the current and the resulting tiers of each product. Regular and sale prices are not changed in this mode, and these updates have no price snapshot to revert.

Two percentage tiers applied to a category.

Tools

↑ Back to top

Command line

↑ Back to top

The wp bulk-price-editor command runs the same code as the editor. Its runs appear in History with snapshots and can be reverted from either place.

CommandPurpose
wp bulk-price-editor templatesLists the saved templates.
wp bulk-price-editor run --template="Weekend sale" --dry-runShows what a job would change without changing anything.
wp bulk-price-editor run --template="Weekend sale" --yesRuns a job; --yes skips the confirmation.
wp bulk-price-editor run --filters='{"bpe_included_category_ids":[15]}' --modifier=decrease_by_percent --args='{"bpe_regular_price_decrease_by_percent":10}'Runs an ad hoc update from filters and a method given as JSON.
wp bulk-price-editor history --limit=10Lists recent updates.
wp bulk-price-editor revert 42Reverts an update by its id.

Combined with a system cron, this runs recurring updates, for example a job every Monday night.

Settings

↑ Back to top

The Settings tab holds the price change tracking switch and the number of changes kept per product.

FAQ

↑ Back to top

An update went wrong. How do I undo it? Open the History tab and click Revert on the update. The previous prices and sale dates come back.

The update seems stuck. Background jobs run through the Action Scheduler, which depends on the site cron. Click View queue to see the pending jobs under WooCommerce → Status → Scheduled Actions. The same applies to scheduled updates and automatic reverts.

Some products did not change. Percentage and flat methods skip products that do not have the price being changed, usually products without a sale price. Use Enter new prices or Update by formula to set a price on products that have none.

Can the sale price end up above the regular price? The values you enter are applied as entered. WooCommerce does not display a sale price that is not lower than the regular price, so check the preview when changing both.

A scheduled update changed a different number of products than listed. The product list is resolved when the update starts; the number in the Scheduled tab is an estimate from the time of scheduling.

Does the plugin work with variations? Yes. Variations are listed and updated individually, or through their parent when the variable type is selected.

Is there a limit on the number of products? No. Updates run in chunks of 100 in the background.

Developers and support

↑ Back to top

Hooks, the command line, the data model and the extension points for custom filters, price methods and table columns are in the developer documentation.

For help with the plugin, open a ticket through WooCommerce.com support.

Related Products

WooCommerce Subscriptions is a WooCommerce extension that lets customers subscribe to your products or...

Offer add-ons like gift wrapping, special messages or other special options for your products.

Use of your personal data
We and our partners process your personal data (such as browsing data, IP Addresses, cookie information, and other unique identifiers) based on your consent and/or our legitimate interest to optimize our website, marketing activities, and your user experience.