Google Shopping Sale Price Not Showing? Check the Offer Behind the Badge

A submitted sale price and a visible sale badge are not the same state. Audit the exact offer’s processed values, active dates, landing page, price history, market, and destination before treating an absent badge as a feed failure.

By
Hookin Team, Performance Editorial
Published
September 10, 2026
Reading time
15 min read
Views
33 views
On this page
  1. The badge is the last layer, not the first
  2. Know what each price field is doing
  3. Current market rules are not interchangeable
  4. Three fictional offer audits
  5. Audit the exact offer in this order
  6. Do not use a different pricing feature to force the visual
  7. Report the diagnosis, not just the screenshot
  8. Sources

A product can be correctly discounted on your site, carry a sale_price in Merchant Center, and still appear on Google without a crossed-out price or sale badge. That does not automatically mean the feed failed.

The useful question is not “Why is Google ignoring my sale?” It is: what state is the exact offer in? First confirm that the sale price was applied to the right item and is currently active. Then confirm that the landing page, checkout, structured data, destination, target country, discount, and price history make that offer eligible for an annotation. Only after those checks does badge rendering become the issue—and Google says eligible annotations are still not guaranteed to appear.

This distinction prevents two expensive mistakes: rebuilding clean product data because a badge was not rendered, or assuming a badge is merely optional when the offer actually has a price, date, variant, or landing-page defect.

The badge is the last layer, not the first

Treat sale-price troubleshooting as five separate layers.

Layer Question Evidence to inspect
Submitted Did the exact item receive price, sale_price, and any intended effective dates? Source row or API payload for the item ID
Applied What values did Merchant Center process after source rules and automations? Product details, contributing data sources, processed attributes
Validated Can the shopper buy the exact linked variant for that price? Landing page, checkout, structured data, currency, public access
Eligible Does this offer meet the annotation rule for its country and destination? Discount calculation and base-price history
Rendered Did Google choose to show the annotation on this impression and surface? “Has sale badge” status plus observed placement

A screenshot of a Shopping result tells you only about the final layer. It does not prove which value was submitted, whether an overlay matched the item ID, whether Google’s crawler saw a different variant, or whether the offer passed the market-specific history rule.

Google’s current documentation separates the current sale price from the annotation. The sale_price specification says the sale price is the amount charged during the sale; the original price and an annotation may also appear when further requirements are met. Google’s sale price annotation guide adds that annotations are not guaranteed even when those requirements are satisfied.

Know what each price field is doing

During a normal public sale, keep the regular amount in price and send the temporary payable amount in sale_price. Do not replace price with the old manufacturer’s suggested price, an invented anchor, or a price that this offer did not genuinely use as its base.

The optional sale_price_effective_date controls when the submitted sale price applies. Google expects an ISO 8601 date range with a start, an end, and preferably explicit times and time zones, such as:

2026-09-01T00:00-0400/2026-09-14T23:59-0400

Without an effective date, Google says the sale price is used immediately. Without a time, the start defaults to midnight and the end to 11:59 p.m.; without a time zone, Google defaults to UTC. That makes a missing offset capable of starting or ending a sale at an unintended local hour. See Google’s sale_price_effective_date format and timing guidance.

The landing page must make the two amounts understandable and the sale price must match the amount the user can actually pay. Google’s pages differ slightly on typography: the annotation guide recommends making the active sale price most prominent, while the sale_price attribute page says it does not have to be the largest price. Both agree on the substance: show the regular and sale prices clearly on the product page, submit matching values, and keep the payable sale price consistent through checkout. The safe implementation is not a font-size argument; it is an unmistakable current price.

This creates three distinct outcomes:

  1. Sale not applied: the processed offer still uses the regular price because sale_price is missing, invalid, mapped to another item, or outside its active window.
  2. Sale applied without annotation: the sale price can be the current offer price, but the original price and badge are not eligible or not selected for display.
  3. Annotation eligible: the exact offer passes the data, page, discount, history, country, and destination checks. Google may show the original price, sale price, and badge, but still does not promise the annotation on every impression.

Current market rules are not interchangeable

The eligibility rules below come from Google’s current sale price annotation requirements, checked on September 9, 2026. They apply to the annotation, not merely to your ability to submit a lower current price.

Destination and market Base-price history rule Other core conditions
Free listings in Australia, Canada, the United States, and Japan No base-price history test is listed on the current page Sale price lower than base; discount greater than 5% and less than 90%; both prices shown on landing page
Free listings in Brazil, France, Germany, India, Italy, Korea, the Netherlands, Spain, and the United Kingdom Base price valid for 30 days within the past 200 days; days need not be consecutive Same discount and landing-page conditions
Shopping ads in the United States Base price charged for 5 days within the past 30 days, or 15 days within the past 200 days; days need not be consecutive Same discount and landing-page conditions
Shopping ads in Australia, Brazil, Canada, France, Germany, India, Italy, Japan, Korea, the Netherlands, Spain, and the United Kingdom Base price valid for 30 days within the past 200 days; days need not be consecutive Same discount and landing-page conditions

For store-specific local inventory pricing, Google documents a separate 60-day history rule and additional setup conditions. Do not reuse the online Shopping-ad row for that case.

Two boundaries are easy to miss. “Greater than 5%” excludes a drop from 100 to 95 because that is exactly 5%. “Less than 90%” excludes a drop from 100 to 10 because that is exactly 90%. Calculate the discount as:

(price - sale_price) / price × 100

Do not engineer prices a few hundredths above a threshold merely to chase a badge. Rounding, currency presentation, page extraction, and ordinary merchandising changes can erase that margin. Set a defensible customer price first, then audit how it maps to the rule.

The country list matters as much as the percentage. If the target country is not listed for the relevant destination on Google’s current page, do not assume that a sale annotation is available just because another market shows one.

Three fictional offer audits

The following original examples are fictional teaching records, audited as of September 9, 2026. Their day counts are inclusive calendar-day calculations from the stated histories, not claims about data observed in a live Merchant Center account. Google ultimately evaluates its own record of each offer.

Three fictional Google Shopping sale-price offer audits showing one eligible offer, one insufficient price-history case, and one variant mismatch

The filled data is also available as HB68_sale_price_offer_audit_v1.csv, with a reusable blank audit template.

Offer A: the sale is eligible, but the badge is still not promised

Northwind Trail Shell, navy, medium targets United States Shopping ads.

  • price: 160.00 USD
  • sale_price: 120.00 USD
  • Effective window: September 1–14, 2026, Eastern time
  • Discount: (160 - 120) / 160 = 25%
  • Base-price history: 160.00 USD from February 22 through August 31
  • Base days inside the past 30-day teaching window: August 11–31, or 21 days
  • Landing page, checkout, and structured data: 160.00 USD regular; 120.00 USD current; navy medium preselected

This offer clears the United States Shopping-ad history route because 21 qualifying days in the past 30 exceed the five-day requirement. The discount also falls strictly between 5% and 90%, and the page evidence matches the submitted variant.

The correct verdict is eligible to be considered for a sale price annotation, not guaranteed to display one. If Merchant Center’s “Has sale badge” filter says Yes but an operator cannot reproduce a badge in a particular search, rebuilding the feed is not yet justified. The remaining difference may be Google’s rendering selection, placement, timing, or impression context.

Offer B: a real sale, but not enough base-price history for Germany

Kinetic Desk Lamp, graphite targets Germany Shopping ads.

  • price: 90.00 EUR
  • sale_price: 72.00 EUR
  • Effective window: September 5–20, 2026, Central European Summer Time
  • Discount: 20%
  • Product launched at 90.00 EUR on August 19
  • Base-price period before the sale: August 19–September 4, or 17 days
  • Landing page, checkout, and structured data: all match

Nothing is wrong with the arithmetic or page. The problem is the annotation history rule. Germany Shopping ads require the base price to have been valid for 30 days within the past 200 days. This offer has only 17 days in the fictional record.

The operational verdict is sale data can be valid, annotation not yet eligible on this evidence. Do not backfill a false start date or relabel a recommended retail price as the base. Keep accurate data, allow genuine price history to accumulate, and treat an unbadged current sale price as different from a feed rejection.

Offer C: the history qualifies, but the linked variant does not

Tide Runner Shoe, blue, size 9 targets Canada Shopping ads.

  • price: 100.00 CAD
  • sale_price: 75.00 CAD
  • Effective window: September 3–15, 2026, Eastern time
  • Discount: 25%
  • Base-price history in the teaching record: February 22–September 2, or 193 days
  • Submitted offer: blue, size 9
  • Landing URL result: product page opens with black, size 9 selected at 100.00 CAD

The percentage and 30-in-200 history test are satisfied. The offer still fails the more basic validation layer: the linked experience does not show the submitted variant at the submitted price. Google’s price-mismatch troubleshooting guide tells merchants to preselect the advertised variant and make its price match the feed.

The verdict is not a badge-selection case yet. Fix the offer URL or variant-state handling so blue size 9 loads by default, displays both 100.00 CAD and 75.00 CAD, exposes the correct current price in structured data, and keeps 75.00 CAD through checkout. Changing every color to the blue variant’s sale price would “fix” the screenshot by corrupting the catalog.

Audit the exact offer in this order

1. Freeze the offer identity

Record the item ID, item group ID, variant attributes, target country, destination, currency, source, and final landing URL. The word “product” is too broad for this diagnosis. A color-size combination in Canada Shopping ads and a sibling variant in United States free listings can have different prices, URLs, histories, and eligibility outcomes.

If a supplemental source is involved, verify that its item IDs actually exist in the primary source. Google’s product data-source documentation says a supplemental source cannot add products on its own and instructs merchants to match each supplemental product ID exactly to the primary source. Do not rely on a commerce app’s preview as proof that Merchant Center applied the overlay to every SKU.

2. Read the processed values

Open the affected item in Merchant Center and record the currently processed price, sale_price, and effective dates, plus the contributing source or automation. Compare that record with the source row you intended to send.

This separates “we generated the right feed” from “this offer received the right attributes.” Rules, stale uploads, source matching, and automatic updates can make those two statements different.

3. Check the active window and calculate the discount

Confirm the audit time falls inside the submitted range in the intended time zone. Then calculate the unrounded percentage from the actual submitted amounts. Check strict boundaries, not labels such as “5% off” or “up to 20%.”

If the date is omitted intentionally, document that the sale is meant to apply immediately. If the site has already ended the sale but the source still sends it, synchronize the website and product data rather than waiting for a crawler to reconcile the conflict.

4. Reproduce the payable price as a shopper

Open the final URL in a clean session appropriate to the target country. Confirm:

  • the exact advertised variant is selected;
  • the regular and sale prices are both clear on the landing page;
  • the sale is available to ordinary users, not only to a paid or restricted membership;
  • the currency matches the target-country offer;
  • the sale price survives cart and checkout;
  • no required option silently raises the price.

Google’s price requirements require the submitted amount and currency to match the landing page and checkout, and require variants and their prices to be displayed straightforwardly. A generic product URL that opens the cheapest, most popular, or first available variant is not good enough when the feed row advertises another offer.

5. Inspect structured data and automatic updates

If the page shows a live sale price, Google says that current amount should also be present in the page’s product Offer structured data. Use the Rich Results Test as a markup inspection aid, then compare the extracted price and currency with the visible page and feed. See Google’s Merchant Center structured-data setup.

Automatic updates can change price and sale-price information using structured data or Google’s extractors. They are a safety net, not a substitute for synchronized product data. Google also warns that multiple strikethrough prices can make it difficult to identify the correct reference price. Inspect the crawl timestamp and processed values before blaming the source or disabling automation. The relevant behavior is documented in Google’s automations guide and strikethrough-price mismatch guidance.

6. Apply the correct market and destination rule

Count the exact base price’s valid or charged days inside the relevant lookback window. Do not count days at another price, days from a sibling variant, or a manufacturer’s suggested price that shoppers were not actually charged. Keep the evidence as dated price records, not a note that the product has “usually” cost roughly the same amount.

Run this separately for free listings and Shopping ads. A United States free-listing offer and the same United States Shopping-ad offer do not have the same published history rule.

7. Check Merchant Center’s badge status, then stop guessing

Google’s annotation guide says you can filter Products → All products → Has sale badge → Yes to find eligible products. The wording or navigation can vary with interface changes and localization, but the key evidence is the item’s badge status—not whether one manual search happened to show the visual treatment.

Use this decision:

Result Conclusion Next action
Sale values are not processed or active Submission/application problem Fix source, matching, format, dates, or synchronization
Sale is active but page, checkout, schema, or variant fails Offer-validation problem Fix the linked buying experience and resubmit accurate data
Validation passes but market rule fails Annotation-ineligible offer Keep truthful pricing; wait for genuine history or revise a legitimate sale
Merchant Center reports a sale badge, but a search does not show it Eligible, display not guaranteed Monitor placements; do not claim a feed defect from one impression

Do not use a different pricing feature to force the visual

A public temporary price reduction belongs in sale_price. A promotion is a separate Merchant Center feature for special offers such as qualifying coupon mechanics, gifts, or other promotional structures. Google explicitly says sale prices should not be submitted as promotions merely to represent the same markdown.

In countries where Google supports loyalty programs, a member-only amount is not an ordinary sale_price. Google’s price specifications direct supported merchants to loyalty-program attributes for member pricing. Sending a restricted price as a public sale can produce a clean-looking feed and a broken customer promise.

Choose the data model that describes the offer the shopper can actually redeem. A badge is an output of that model, not the reason to distort it.

Report the diagnosis, not just the screenshot

A useful escalation contains one offer-level record:

Offer: Northwind Trail Shell / navy / medium / US Shopping ads
Processed data: 160.00 USD base; 120.00 USD sale; active September 1–14, 2026, ET
Discount: 25%
Base history: 21 days in past 30; 191 days in past 200 teaching record
Page and checkout: exact variant preselected; values and currency match
Structured data: current offer price 120.00 USD
Merchant Center badge status: record the observed Yes/No state
Conclusion: eligible-not-guaranteed, or name the first failed layer

That record gives a feed engineer, merchandiser, media buyer, or support agent something testable. “The sale badge is missing on some products” does not.

The final rule is simple: prove the current offer before troubleshooting the decoration. Once the exact item has an active sale price, a matching buying experience, and market-specific eligibility, an absent badge may be a rendering decision. Before that point, the missing badge is often only the visible symptom of a different offer underneath.

Sources

Back to blog

Keep reading

Turn the idea into a playable

Build and test an interactive ad in Hookin. No code required.

Start free