Practical WordPress guide

Show Sale Savings for WooCommerce: safe setup, failure cases, and rollback

A plain-language guide for nontechnical site owners. It separates what the parent plugin really knows from what a helper plugin should never guess.

Reviewed July 20, 2026Official-source links includedNo invented performance claims

Direct answer

When WooCommerce renders its native sale badge, compare only the current product's regular and sale prices. If the regular price is finite, positive, and greater than the sale price, replace only the badge text with a compact escaped saving. If the pair is missing, equal, reversed, malformed, ambiguous, or over budget, return the complete native badge unchanged.

Show Sale Savings for WooCommerce follows that rule. Free shows a whole-number percentage. Pro can use a locally formatted amount or both, with a short-output fallback for themes whose native badge was designed for Sale!.

Read prices; do not become a pricing engine

WooCommerce's product editor distinguishes a regular price from a sale price and supports sale date ranges. The official Product Editor settings documentation explains those fields and notes that variations have their own settings.

A sale-savings badge should not write any of them. Its ownership boundary is display only:

  • WooCommerce owns current regular and sale prices.
  • Pricing, coupon, and dynamic-discount extensions own their own rules.
  • The active theme owns badge shape, color, and position.
  • The savings plugin owns only a proven short text value.

That separation makes an immediate off switch meaningful: disable the plugin and WooCommerce's complete native badge returns.

Simple-product math

For a simple product:

saving amount = regular price - sale price
saving percent = round((saving amount / regular price) * 100)

Example: regular price $120, sale price $90.

amount = 120 - 90 = 30
percent = round(30 / 120 * 100) = 25

Free can display 25% off. Pro can display $30 off or a compact combination such as 25% off ($30.00) using WooCommerce's local currency formatter.

The calculation must stop when the regular price is zero, either value is non-finite, the sale price is negative, or the sale price is not lower. A visible 0% off is not a helpful fallback; the untouched native badge is safer.

Variable products need bounded, honest wording

A variable product may have different regular and sale prices for every variation. Applying the largest percentage to every variation would overstate the discount.

A bounded summary can:

  1. Read at most 100 current variation price rows.
  2. Keep only pairs that independently prove a sale.
  3. Calculate each valid pair.
  4. Select the largest proven percentage.
  5. Say Up to X% off.

The words Up to carry the important limitation: the badge describes the maximum among valid variations, not the selected variation and not every variation.

A merchant report describes a misleading 0% label on mixed variable-product ranges. Another reports that a largest discount was shown for variations that were not actually on sale. These reports establish concrete failure modes; they do not prove every percentage-badge plugin has the same implementation.

Keep the native wrapper

WooCommerce's current code reference lists the woocommerce_sale_flash filter used by native sale-flash templates. The WooCommerce hook index and template reference provide the stable integration surface.

The filter receives the complete badge HTML. A focused plugin can recognize the supported native wrapper, replace only escaped inner text, and return the original string for unfamiliar markup. It should not copy template files or add selectors, icons, animations, or CSS.

This fail-passive rule matters when a theme or another extension owns a different badge structure. Uncertain input should remain with its existing owner.

Compact text is a compatibility feature

Many themes style the native badge for a short word. A long combination such as a 20-character prefix, percentage, and formatted amount can overflow even when its math is correct.

Without taking over theme CSS, a text-only plugin can enforce a small final text budget:

  1. Try the selected Pro wording and prefix.
  2. If it is too long, remove the prefix.
  3. If the amount or combined wording is still too long, use the shorter proven Free percentage.
  4. Never cut a currency value or word in the middle.

StoreFixKit uses a 16-character final budget. This is a product-design boundary, not a WooCommerce platform rule. The desktop and 390-pixel mobile release checks also verify that the actual badge rectangle remains inside the viewport.

Diagnose an unchanged or surprising badge

Symptom Likely boundary Safe behavior
Badge still says Sale Invalid/uncertain pair, unsupported wrapper, or feature disabled Preserve complete native badge
Badge says Up to Variable product has several valid sale pairs State only the maximum proven saving
Prefix disappears Final Pro combination exceeded short-text budget Remove prefix before using a shorter value
Amount differs from coupon Plugin reads product prices, not cart discount rules Do not merge unrelated discount systems
Color or shape is unchanged Theme owns presentation Change text only
More than 100 variation rows Evaluation exceeds resource budget Preserve native badge

Do not call this price-history compliance

Current regular and sale prices do not establish how a product was priced over a legal reference period. The plugin should not claim Omnibus, advertising, consumer-protection, or price-history compliance.

It also does not calculate tax-inclusive savings, personalized prices, role prices, quantity discounts, cart rules, coupons, subscriptions, bundles, or dynamic-pricing outcomes. Those systems can change what a shopper ultimately pays without changing the product's stored regular/sale pair.

Test the promises and the non-promises

Use this release checklist:

  1. 100 regular and 75 sale produces 25% off.
  2. Zero, equal, reversed, negative, missing, and malformed pairs keep the original badge.
  3. A variable product ignores non-sale pairs and uses only the largest valid percentage.
  4. More than 100 rows keeps the original badge.
  5. The native wrapper and class appear exactly once.
  6. Pro percentage, amount, both, phrase, and prefix use the same Free proof.
  7. Overlong Pro text falls back without truncation.
  8. Desktop and mobile badge rectangles remain inside the viewport.
  9. Product name, regular price, sale price, schedule, stock, cart, checkout, and order remain unchanged.
  10. Disabling Free restores the complete native badge immediately.
  11. Removing Pro or the license API leaves Free working.
  12. Update, downgrade, rollback, and uninstall preserve all WooCommerce data.

Resource boundary

Simple products need two current price reads. Variable products use WooCommerce's bounded current variation-price structure and stop above 100 rows. There is no catalog query, write, custom table, cron, queue, background job, telemetry, frontend asset, or storefront remote request.

The WordPress Settings API provides a consistent administrator surface with capability and nonce handling. Pro license and update requests belong behind authenticated administrator actions only.

Common mistakes

Calculating from formatted price HTML

HTML can contain ranges, tax labels, markup, and localization. Use numeric product values, then format only the final proven amount.

Treating an empty sale price as zero

That can invent a 100% discount. Empty or malformed data must keep the native badge.

Showing the maximum percentage without Up to

That implies every variation receives the maximum. Use bounded wording that states the limitation.

Adding CSS to repair every theme

That turns a one-job text plugin into a badge-layout framework. Keep theme presentation with the theme and keep output compact.

Recalculating prices to match the label

Display must never become authority over price, cart, or order state.

Market boundary

Current WordPress.org products and a paid WooCommerce Marketplace sale-flash product demonstrate an existing category. Research captured a current $79/year offer and a deployed footprint for another product. That does not prove StoreFixKit buyers, future revenue, or that every active installation is paid.

The hypothesis to validate is specific: merchants who value trustworthy variable-product wording and compact theme-safe output will upgrade for amount and wording controls. Measure installations, enabled badges, trial starts, successful checkouts, support, refunds, and renewals before making a revenue claim.

FAQ

How do I show a discount percentage in a WooCommerce sale badge?

Calculate it from the current numeric regular and sale prices when the pair proves a positive saving, then replace only the native badge text.

How should variable-product discounts be shown?

Evaluate a bounded set of valid sale pairs and state the maximum as Up to X% off.

Does the plugin change sale prices?

No. It reads current product values and writes no product, cart, or order data at runtime.

Why did Pro remove my prefix?

The full wording exceeded the compact native-badge budget. The prefix is removed before falling back to the shorter proven percentage.

No. It does not retain price history or interpret laws and regulations.

Focused plugin

Use the one-job implementation.

Show a truthful percentage or compact amount inside WooCommerce's native sale badge only when current local product prices prove a positive saving.