Build your WordPress website with Elementor.Discover Elementor Affiliate link
Français

Site appearance

WooCommerce store and checkout · Intermediate

Scheduled WooCommerce sale: correct the price and schedule

Does a WooCommerce sale fail to start at the right price? Check the product, variations, dates, and scheduled actions, then verify the display.

Source published: · Source updated: · Editorial policy

Read the French edition

Compare a precise amount and time

A sale was meant to start today, but the product page still shows the regular price, or the price changes at a different time than expected. Start by recording the product, any variation, expected amount, and agreed period. A variable parent’s price, a variation price, and a cart total do not necessarily represent the same data.

Note the observation time and context: logged-in or logged-out visitor, currency, quantity, and any location used for taxes. Compare the same case before concluding scheduling is broken. A change in displayed tax or a role-based rule can explain an amount difference without moving dates.

Open the editing screen and record the currently saved values. A sale entered but not saved is not a late scheduled action. A past date or invalid discount also requires correcting data before investigating background tasks.

This guide targets a native sale per product or variation. A coupon, dynamic-pricing rule, or plugin-provided campaign uses another mechanism. Identify the tool actually owning the price before changing the regular price.

  • Incorrect price or dates in the product: correct native data.
  • Only one variation affected: examine its own schedule.
  • Correct data, expected change not applied: view the action linked to the product.
  • Data and action consistent, old display: compare cache and pricing context.

Prepare a targeted rollback without touching orders

These procedures assume WooCommerce is installed and an account is authorized to edit products, on a self-hosted site or a WordPress.com store using WooCommerce. Action administration may require additional permissions. In multisite, check the open store before recording its time zone and prices; subsites do not necessarily share these settings.

Keep the product ID, regular and sale prices, dates, type, and values for affected variations. A targeted export and field screenshots complement the record. Also note synchronization processes that may restore prices or dates from an external source.

For testing, use an isolated copy and a demonstration product. Have outgoing emails, webhooks, real payments, and stock or catalog synchronization with production disabled. Verify this with the person preparing the copy. No real charge or order is needed: the product page and a test cart line allow amounts to be compared.

Define rollback before the fix: restore this product’s fields and only the compared settings. A full store restore could delete newer orders or content. It is not the first choice for an incorrectly scheduled price on one product.

The expected result is a readable initial state and a limited verification case. Do not modify already-recorded orders to automatically align them with the catalog’s new price. Their commercial handling and history are separate from scheduling future sales.

Approach 1: check prices on the correct object

A native sale requires a populated sale price lower than the regular price. An empty field or equal or higher value does not define the intended discount. For a variable product, each combination has its own prices and dates: the parent range does not demonstrate that every variation is on sale.

Do not change currency or global taxes to compensate for an incorrect value in this product. When conversion or role-based pricing applies, first record native data before looking for the rule transforming it.

The expected result is a pair of prices retained on the correct object after reloading. Rollback restores recorded fields while preserving other legitimate changes. Do not replace every variation with one amount to correct a single combination.

  1. In Products, All Products, edit the product identified by ID or SKU. Open Product data and check its type.
  2. For a simple product, open General and record Regular price and Sale price. For a variable product, open Variations, expand the target combination, and record its own fields, not those of another identically named product.
  3. Correct only the approved values for this product or variation. Open Schedule to reread associated dates before saving: a correct price may still belong to a past period.
  4. Save variation changes if necessary, then update the product. Reload administration and check prices and dates for the same combination.
  5. Compare the test product page with all attributes selected. If fields have changed again after saving, find the import or synchronization owning those data before repeating the edit.

Read dates as a sales schedule

Beside the sale price, open Schedule. In the native classic editor checked with WooCommerce 11.2.1, the start is stored at 00:00:00 and the end at 23:59:59 in the site’s time zone. The fields represent days, not a freely selectable time. An external integration supplying timestamps must be examined separately.

For example, a November 10–12 period includes the 12th: it does not end as that day begins. Record both dates and check that they are neither reversed nor already past. Define what the team expects at the start and end before correcting the schedule.

In WordPress Settings, General, record the site time zone and displayed local time. Do not compare only your computer’s clock or a UTC log. For a site using seasonal clock changes, a city time zone matching its operation may be more appropriate than a fixed offset.

Do not change the global time zone to fix one sale without examining the site’s other schedules. If the setting was wrong, prepare its correction with the administrator, record affected campaigns and publications, then check their deadlines after the change.

The expected result is a period understood in the correct time reference. Rollback restores backed-up dates or time zone but must account for events already executed during the test. Restoring an old time does not automatically remove prices already applied.

Preserve dates during imports and bulk edits

If the sale disappeared after a catalog update, find the action that changed prices. In Products, All Products, native bulk price editing concerns simple and external products; it does not set variation prices individually. It may erase existing sale dates when changing prices. Bulk commands in the Variations area are a different procedure: do not automatically apply the same diagnosis.

For a CSV import, start from an export of the target store and limit columns to the actual need. If dates must be retained or changed, check their mapping and format in the importer used. An empty column or supplier source ignoring sales may restore a configuration different from the manually created one.

On a copy, process one product, then reload its price and schedule fields. For a variable product, examine each affected variation; parent values do not establish that every date was retained. Keep the operation’s ID and report.

If synchronization rewrites data, correct its source or priority rule. Reapplying the sale manually after each run is not a lasting solution. Define which system owns the regular price, sale price, and dates.

The expected result is configuration remaining stable after the next planned process. Rollback uses previous values only for affected products and the retained source file. Do not replay the entire old catalog to restore a few dates, risking reapplication of outdated stock or descriptions as well.

Approach 2: examine the product’s start or end action

The per-product schedule is checked here in official WooCommerce 11.2.1 code. It uses wc_product_start_scheduled_sale and wc_product_end_scheduled_sale actions in the woocommerce-sales group. This mechanism has existed since 10.5; on an older version or third-party campaign, first identify the system actually used.

A deadline already past when saved does not create a new future action for that date. No pending row therefore does not suffice to diagnose a failure. Conversely, a pending action whose time is still ahead is normal. No schedule guarantees execution to the second if background tasks are delayed.

If a row failed, record its error and time. The technical administrator can correlate these clues with logs under WooCommerce, Status, Logs, then correct the cause on the copy. Do not publish a complete log. Resumption is decided only after verifying the correct product and intended commercial effect.

The following check remains read-only. Do not click Run to artificially advance a deadline or execute the whole queue. Correcting dates may replace scheduling: then check new rows. Rollback restores intended data without deleting history or assuming a completed action can be undone.

  1. Open WooCommerce, Status, Scheduled Actions. First display all statuses to avoid hiding a completed or failed action.
  2. Search for wc_product_start_scheduled_sale. In results, compare the group, arguments, and product_id value with the recorded identifier; for a combination, this is the variation ID, not the parent.
  3. Record the matching row’s date, status, and log. Read the time zone indicated in the interface before comparing the date with the product schedule.
  4. Repeat with wc_product_end_scheduled_sale to inspect the end. If no result matches, also search for the identifier in arguments and check the version, saved dates, and whether they are past or future.

Approach 3: compare stored and displayed prices

If fields and event are consistent, compare the direct product page, catalog card, and a test cart line in the authorized environment. Keep the same variation, quantity, and user context. A parent range may remain different from the selected combination’s price without being wrong.

Check displayed-tax settings and the session currency. The price entered in the product and amount presented to the visitor may follow different conventions. Record these conditions before interpreting a difference as a missing sale. Do not change tax rates to artificially match an example.

If a plugin applies role, quantity, bundle, or currency pricing, compare its rules on the copy. Disable or neutralize only the suspected rule for this case, then restore it to confirm its effect. The native price may be correct and subsequently replaced by another commercial rule.

Then clear the affected product page or collection cache through the existing tool. Check a clean session and the usual session. An old card and updated cart indicate a presentation or caching problem different from a price genuinely remaining at its regular amount.

The expected result is an explained amount on each surface. Rollback restores compared rules and preferences; it does not change historical orders. Distinguish native price, commercial transformation, and visual response so the correction can be prepared in the right source.

Check period boundaries on a copy

On the copy, prepare a demonstration product and a period suitable for checking. Note expected amounts and times before editing fields. Start and end tests must remain isolated from real customers and external services; no payment is needed to observe the catalog and a test cart.

A complete check observes the state before the period, during validity, and after its end, with the public price and relevant actions. With day-based dates, plan observations around local deadlines. Do not change the server clock or run a future action to accelerate the test. Saving an already-past period checks a state but does not prove that the automatic transition works.

For variable products, check one on-sale variation and one not on sale. Also check the parent range and sale badge. A campaign limited to one combination must not silently apply the same discount to others.

Check saved values after an import or synchronization run if that flow normally occurs. The schedule must remain as agreed. Also compare caches on the surfaces used so the end of a sale does not leave a card advertising an old price.

The expected result is a verified timeline in the test environment with explicit observations. If you have not performed this sequence, record it as outstanding verification. Reading code or seeing a future action does not justify claiming that the entire campaign was tested.

Finish with a lasting fix and clear rollback

Record the product or variation identifier, selected prices, dates, and time zone. Add the start or end actions examined and their observed results without copying unnecessary customer data. State the cause precisely: incorrect data, scheduling, synchronization, failed action, or stale display.

Keep previous values and the targeted correction procedure until the campaign is validated. If a global time-zone or pricing change was necessary, also check other affected schedules. Rollback must account for already-executed events and legitimate intervening updates.

If many background tasks are affected, continue with general WP-Cron and Action Scheduler diagnosis using the collected clues. Do not turn this pricing guide into a general queue-restart procedure without understanding pending operations.

Resolution is achieved when the correct object has the correct price for the agreed period and public surfaces reflect it in the intended context. Past orders remain a separate history. Keep a note of the source owning these data so the next import does not reintroduce the same defect.

Read a product’s prices and dates without resaving its sale

For a maintainer with WP-CLI already available, save this code in a private lire-promotion.php file outside the public directory. Replace 123 with the simple product or reference variation ID. Run wp --path="/chemin/copie" --url="https://copie.example.test" eval-file "/chemin/prive/lire-promotion.php" with the copy’s actual targets. WooCommerce must be active.

These reads in edit context avoid getter presentation filters; they are neither a cart total nor a tax simulation. Dates are Unix timestamps to correlate with the time zone displayed in administration; null means no date is defined. No save() is called and no scheduled action is launched by this snippet. However, WordPress startup loads its components: use the copy with external effects disabled. Keep the record private, then remove the diagnostic file after comparison.

<?php
if ( ! function_exists( 'wc_get_product' ) ) {
    throw new RuntimeException( 'WooCommerce doit être chargé.' );
}
$produit = wc_get_product( 123 );
if ( ! $produit ) {
    throw new RuntimeException( 'Produit introuvable.' );
}
$debut = $produit->get_date_on_sale_from( 'edit' );
$fin   = $produit->get_date_on_sale_to( 'edit' );
echo wp_json_encode( array(
    'id'          => $produit->get_id(),
    'normal'      => $produit->get_regular_price( 'edit' ),
    'promotion'   => $produit->get_sale_price( 'edit' ),
    'debut_epoch' => $debut ? $debut->getTimestamp() : null,
    'fin_epoch'   => $fin ? $fin->getTimestamp() : null,
), JSON_PRETTY_PRINT ), PHP_EOL;

Sources and references

Use these references to check the features, requirements and limitations described. Reading documentation is not a practical test.

View 10 references

English translation of the reviewed French edition. Code examples retain their original identifiers, comments and output strings for reproducibility. Linked exercise files and original screenshots may contain French. No new practical tests or price checks are implied by translation.

Continue reading in English