Showing sale prices and strikethrough prices correctly in Google Shopping
Which value belongs in price during a sale, how to set sale_price and its period, and why Google's sale annotation is not a check against German price law.
During a sale, price is an advertising claim, not master data
As soon as you fill sale_price, Google shows the value from price as a struck-through original price next to the sale price (Google). In Germany that means you are announcing a price reduction, which falls under section 11 PAngV (the German Price Indication Ordinance). You must state the lowest total price you charged consumers in the 30 days before the reduction (§ 11 (1) PAngV, in German).
My reading of this: during a sale, price should not hold the regular price from your shop system but the 30-day low. Many feed exports simply write the stored regular price into price. That is fine as long as there was no promotion beforehand. It is not fine once you have already reduced the price in the weeks before, which happens often in the fourth quarter.
What the CJEU ruled on percentage discounts
In the Aldi Süd case, the CJEU clarified that a reduction announced as a percentage or as an advertising claim must be determined on the basis of the lowest price of at least the 30 days before (CJEU, C-330/23, in German). It follows that it is not enough to state the lowest price in addition and calculate the discount from the higher regular price.
For the feed this means that everything claiming a gap between two prices must start from the 30-day low. That covers the strikethrough price in Shopping, the "-20%" in ad copy, in a promotion and on the landing page. If you calculate the discount correctly in the shop but the feed delivers the old regular price, you have two different claims out in the market.
Worked example: Black Week after an interim promotion
Suppose a shop sells an item at its regular price of €100. Three weeks before Black Week, a ten-day promotion runs at €89, after which the item goes back to €100. In Black Week it is meant to cost €79.
| Field | What the shop plugin delivers | What fits section 11 PAngV |
|---|---|---|
price (struck through) |
€100 | €89 (30-day low) |
sale_price |
€79 | €79 |
| Discount in ad and promotion | -21% | -11% |
Google's own check would have no objection to €100. For the sale annotation in Germany, Google requires the discount to be greater than 5% and less than 90%, and the base price to have been valid on 30 days, not necessarily consecutive, within the last 200 days (Google). €100 meets that easily. A displayed strikethrough price is therefore no proof that it is legally clean. Google checks a different rule with a different time window.
In commercial terms, the correct version costs some impact, because -11% pulls less than -21%. I would not solve that in the feed but in promotion planning: if you want to show a strong Black Week reduction, drop the interim promotion or schedule it more than 30 days earlier, provided the regular price really applied afterwards. What a promotion leaves after ad spend is worked through in the article on discount promotions.
How to set sale_price and the period
price: Whensale_priceis filled,pricemust be submitted as well (Google). In a sale this is the comparison price, that is, the 30-day low.sale_price: The promotional price. It must match the price on the landing page and at checkout (Google).sale_price_effective_date: Start and end in ISO 8601 format with time zone, for example2026-11-27T00:00+01:00/2026-12-01T23:59+01:00. Without a time zone Google uses UTC, and without a time of day it runs from 00:00 to 23:59 (Google). Without the attribute the sale price applies immediately (Google).
The period is the most common cause of price mismatches during promotions. According to Google, a wrong start date or time zone leads to a wrong price being shown (Google). If the time zone is missing, the sale price in Shopping starts at 01:00 German winter time, while the shop starts at midnight. During that hour feed and landing page contradict each other. I would always set the period with +01:00 or +02:00.
The sale price applies only within the stated period; according to Google, price is the full price when the product is not on sale (Google). So the real shop price has to be there. A period uploaded in advance therefore only works if the 30-day low equals the regular price. If it is lower, you switch price and sale_price together at start and end through a feed update, from the same source that switches the shop price.
If you would rather deliver the sale price without sale_price, it belongs directly in price (Google). Google then shows no strikethrough price. That is the safe choice if you cannot control the 30-day low or the switchover cleanly.
When to leave sale_price out
Three cases in which I would not set the strikethrough price in the feed:
- No real gap to the 30-day low. If the sale price is barely or not at all below the lowest price of the last 30 days, there is no reduction you could announce. Put the sale price in
priceand leavesale_priceempty. - Permanent sale beyond 30 days. According to Händlerbund, the discounted price itself becomes the new reference price once a promotion runs longer than 30 days (Händlerbund, in German). A permanently struck-through price is then no longer a comparison price.
- RRP as the comparison. Whether the RRP may serve as a strikethrough price is not conclusively settled, according to Händlerbund (Händlerbund, in German). In
priceit appears as the shop's original price, not as a manufacturer recommendation. I would avoid that.
Merchant promotions are not the same as sale_price
Promotions in Merchant Center map discounts that only apply in the basket: voucher codes, a percentage off a category, free shipping above an order value. Google keeps the two strictly apart. Sale prices should not be submitted as promotions (Google), and discounts that are already included in the price on the landing page are not permitted as a promotion (Google).
If the reduced price is already on the product page, it belongs in sale_price. If the customer has to enter a code or the discount only applies at checkout, it is a promotion. Submitting both for the same discount shows the user a double reduction they will never get.
Two limits in the promotions policy: discounts of less than 5% of the current price, or less than the equivalent of $5 in local currency, whichever is lower, are not permitted, and in Germany the threshold is €4.50 (Google). And the CJEU's classification also applies to a percentage discount in a promotion: if it refers to a price that was already lower within the last 30 days, it is calculated from the wrong value.
Check before every promotion
Before the start, I would pull a list for the promotional items with item number, the minimum price of the last 30 days, the planned sale price and the value the feed will deliver in price. Every row where price is above the 30-day minimum needs a correction or an empty sale_price. This assumes your shop or feed tool stores the price history. If it does not, that is the real job before the next season, see Black Week preparation. And after the promotion, its price itself counts as the 30-day low, so a Black Week at €79 limits the strikethrough price of a December promotion.
If Google rejects products for a wrong price although no sale is running, that is a different problem, see Rejection because of a wrong price. How the price itself affects reach in Shopping is covered in Price position and Shopping reach, and the basics of the feed in The feed is Google's model of your range.
Further questions
Can the RRP be the struck-through price?
According to Händlerbund, this is not conclusively settled in law. I would not put the RRP in price in the feed while your own price is below it, because Google shows the value as the shop's original price. Take the question to your lawyer.
Does this also apply to Austria and Switzerland?
The article only covers the German PAngV. Austria and Switzerland have their own price law. If you deliver there, have the strikethrough logic checked for each country, including whether you need separate feeds.
Sources
- § 11 Preisangabenverordnung: Additional price disclosure for price reductions, Federal Ministry of Justice, gesetze-im-internet.de (in German)
- Judgment in Case C-330/23 (Aldi Süd), Court of Justice of the European Union (in German)
- Sale price [sale_price], Google Merchant Center Help
- Sale price effective date [sale_price_effective_date], Google Merchant Center Help
- About sale price annotations, Google Merchant Center Help
- How to fix: Mismatched product price, Google Merchant Center Help
- Promotions policies, Google Merchant Center Help
- Streichpreise: Was Händler beachten müssen, Händlerbund (in German)
Read next
- Shopping and Merchant CenterDisapproved for a price mismatch: find the cause and fix it for good
Why Merchant Center disapproves products for a price mismatch and how to check feed, server HTML, markup and variant in the right order.
8 min read · 1 November 2026 - Budget and seasonalityBlack Week with Google Ads: work out the discount first, then the campaign
Test the discount against your own Black Week without one, derive target ROAS from margin, plan the price window, promotions and month-end budget.
9 min read · 2 November 2026 - Profit and marginDiscount promotions: what is left after ad spend
A 20% discount moves break-even ROAS and the extra volume you need a long way. With a calculation table, a full P&L and a check for pull-forward.
7 min read · 1 November 2026
