Promotions and sale prices
A discount touches the two most fragile things in a feed at once: the price and its agreement with the landing page. Most sale-season disapproval spikes are one badly expressed promotion, repeated across a catalogue.
The two fields
Keep price as the regular price and put the discounted figure in sale_price. Do not overwrite price with the discount: doing so loses the strike-through display, and it resets the reference price Google uses to judge whether a later "sale" is real.
sale_price_effective_date carries the window as a start and end timestamp. Setting it means the promotion begins and ends on its own, which is the difference between a campaign that ends at midnight and one that ends when somebody remembers.
Where it goes wrong
- The landing page shows the sale price and the feed still shows the regular one, or the reverse. Both are mismatches.
- The promotion starts on the site at 00:00 and in the feed at the next scheduled fetch, leaving a window where they disagree.
- sale_price is higher than price, which is rejected.
- A permanent "sale" price that never returns to the regular one, which Google treats as the regular price and may flag.
The safest sequence is feed first, site second, by a margin larger than your feed fetch interval. A site that discounts before the feed does produces a mismatch in the direction that disapproves items.
Merchant promotions are a separate thing
The promotions feed, which carries offers such as "20% off" or "free gift with purchase", attaches a special offer annotation to your listings and is submitted separately from the product feed. It is worth doing. The annotation is one of the few visual differentiators available in a Shopping row, and it costs nothing.
Peak season discipline
- Increase feed fetch frequency before the promotional period, not during it.
- Stage the promotion in the feed with a future effective date rather than pushing it live at the moment it starts.
- Watch the disapproval count hourly on the first day, not daily.
- Have the rollback ready: an end date already set beats a manual revert at 2am.