Сценарий знакомый: на карточке товара цена вариации меняется в админке, но на фронтенде покупатель видит старое значение, либо цена обновляется только после очистки кэша. Чаще всего проблема не в самом WooCommerce, а в связке темы, кэширующего плагина, Object Cache или кастомного кода, который подменяет данные вариаций слишком агрессивно.
Ниже разберём, как локализовать источник рассинхрона и отключить кэширование именно там, где оно мешает, а не рубить кеширование целиком по сайту.
Как понять, что проблема именно в кэше цены вариаций
Сначала проверьте, где именно «застревает» значение. Если в админке у вариации цена уже новая, а на странице товара старая, это обычно один из трёх вариантов: HTML-кэш страницы, кэш ответа AJAX для вариаций или объектный кэш, который отдаёт устаревшие метаданные товара.
Быстрая диагностика
- Откройте товар в режиме инкогнито и сравните цену с админкой.
- Очистите только кэш страницы товара в плагине кеширования, не весь сайт.
- Проверьте, меняется ли цена после переключения вариации без перезагрузки страницы.
- Если используется Redis/Memcached, временно отключите Object Cache и повторите тест.
- Посмотрите, не подменяет ли цену тема через хук
woocommerce_available_variationили фильтрwoocommerce_get_price_html.
Если после очистки кэша страницы проблема исчезает, значит, у вас конфликт с full-page cache. Если цена не обновляется даже без HTML-кэша, копать нужно в данных вариаций и объектном кэше.
Что именно кэшировать не стоит
У вариативных товаров WooCommerce есть данные, которые должны оставаться динамическими: цена выбранной вариации, наличие, скидка, старая цена, HTML для конкретной комбинации атрибутов. Если эти данные попадают в кэш как статичный фрагмент, покупатель увидит не то, что хранится в базе.
На практике чаще всего мешают:
- кэширование HTML всей карточки товара для авторизованных и неавторизованных пользователей одинаково;
- кэширование ответа
?wc-ajax=get_variationили похожих AJAX-запросов; - объектный кэш, который не сбрасывается после сохранения вариации;
- кастомные оптимизации темы, которые сохраняют вывод цены в transient.
Пошаговое решение: отключаем кэш там, где он ломает цену
Лучше идти от менее рискованного к более точечному. Сначала исключите страницу товара из page cache, затем проверьте AJAX-запросы WooCommerce, и только после этого трогайте PHP-логику.
1. Исключите карточки товаров из full-page cache
Если у вас кэширующий плагин, добавьте в исключения шаблоны товаров и корзины. Для большинства решений это делается в настройках плагина, без кода. Важно не отключать кэш на всём сайте, а убрать только страницы, где цена зависит от выбора вариации.
Если нужен пример на уровне кода для своего слоя кэширования, можно не сохранять HTML страниц товара:
<?php
add_action('template_redirect', function () {
if (function_exists('is_product') && is_product()) {
if (!defined('DONOTCACHEPAGE')) {
define('DONOTCACHEPAGE', true);
}
}
});Этот вариант уместен только если вы контролируете собственный кэш или используете совместимый плагин. Не стоит вставлять его бездумно в тему, если у вас уже настроен нормальный page cache с исключениями.
2. Не кэшируйте AJAX WooCommerce для вариаций
WooCommerce подгружает данные вариаций через AJAX. Если прокси, CDN или плагин кэширует такие ответы, цена может зависать. Проверьте, не попадает ли в кэш запрос к ?wc-ajax=get_variation и похожие эндпоинты WooCommerce.
Для серверного кэша логика обычно такая: запросы с параметром wc-ajax не должны сохраняться как обычные страницы. Если вы пишете свой слой кеширования, исключите их явно:
<?php
add_action('init', function () {
if (isset($_GET['wc-ajax'])) {
if (!defined('DONOTCACHEPAGE')) {
define('DONOTCACHEPAGE', true);
}
nocache_headers();
}
});Это не замена настройкам CDN, но хороший страховочный слой для нестандартных конфигураций.
3. Сбрасывайте объектный кэш после сохранения вариации
Если у вас Redis или Memcached, устаревшие метаданные товара могут жить дольше, чем нужно. WooCommerce обычно чистит кэш при сохранении, но кастомные поля, связанные с ценой, иногда остаются в transient или в собственном кеше темы.
Если цена вариации зависит от дополнительного метаполя, сбрасывайте кэш после сохранения товара:
<?php
add_action('woocommerce_save_product_variation', function ($variation_id, $i) {
if (function_exists('wp_cache_delete')) {
wp_cache_delete($variation_id, 'post_meta');
}
if (function_exists('wc_delete_product_transients')) {
wc_delete_product_transients(get_post_parent_id($variation_id));
}
}, 10, 2);Здесь важно понимать, что wp_cache_delete() не является универсальной кнопкой «очистить всё». Она помогает только если вы точно знаете, какой кеш нужно сбросить. Для WooCommerce надёжнее дополнительно вызывать wc_delete_product_transients().
Сравнение подходов: плагин, код или настройка сервера
| Подход | Когда подходит | Минус |
|---|---|---|
| Исключение страниц товара в плагине кэша | Если проблема только на карточках товаров | Нужно вручную следить за правилами исключений |
Код с DONOTCACHEPAGE | Если нужен точечный запрет кэша для товара или AJAX | Легко переборщить и отключить кэш шире, чем нужно |
| Настройка Redis/CDN | Если рассинхрон идёт из объектного кэша или edge cache | Требует доступа к серверу и понимания архитектуры |
Проверка результата после внедрения
После изменений не ограничивайтесь ручным обновлением страницы. Проверьте сценарий как покупатель, а не как администратор.
- Откройте товар в инкогнито и выберите несколько вариаций.
- Сравните цену в карточке с ценой в админке у конкретной вариации.
- Обновите цену вариации в админке и проверьте, что она изменилась без полной очистки сайта.
- Если есть CDN, проверьте ответ заголовков и убедитесь, что карточка товара не отдаётся из устаревшего edge cache.
- Посмотрите логи кэширующего плагина, если он умеет показывать причину пропуска или сохранения страницы.
Хороший признак — цена меняется сразу после сохранения вариации или после очистки только конкретного товара, а не всего кэша сайта.
Частые ошибки и как их исправить
Отключили кэш на всём сайте вместо карточек товаров
Так делают часто, когда не находят источник проблемы. В итоге сайт теряет смысл кэширования, а проблема остаётся в AJAX или объектном кеше. Исправление простое: верните глобальный кэш и исключите только /product/, корзину, оформление заказа и проблемные AJAX-запросы.
Очистили page cache, но забыли про Object Cache
Если Redis хранит старые метаданные, HTML-кэш тут ни при чём. После изменения настроек проверьте оба слоя: page cache и object cache. Иногда помогает именно перезапуск Redis или сброс кэша плагина Object Cache.
Кастомная тема переопределяет цену через фильтр
Если в теме есть код на woocommerce_get_price_html или woocommerce_available_variation, он может возвращать закэшированное значение из своей переменной или transient. В этом случае нужно искать не в WooCommerce, а в теме или в мини-плагине с кастомизацией.
CDN кэширует AJAX-ответы
Это особенно заметно, когда цена меняется только у части пользователей. Проверьте правила кэширования на CDN и исключите запросы с wc-ajax. Если CDN не умеет тонко исключать такие запросы, лучше не пытаться кэшировать их вообще.
Практические советы по безопасности и производительности
Не храните логику отключения кэша в functions.php, если проект живёт долго и в нём несколько тем. Для таких правок лучше использовать небольшой mu-plugin или отдельный мини-плагин, чтобы не потерять настройку при смене темы.
Если вы используете сторонний плагин оптимизации, проверьте, не включена ли в нём агрессивная минификация и объединение скриптов на странице товара. Иногда цена вариации «не меняется» не из-за кэша, а из-за сломанного JS после оптимизации. Это уже другая проблема, но внешне она выглядит похоже.
Если нужен дополнительный контроль над дублями, кешем и технической чисткой сайта, полезно посмотреть Clearfy Pro: https://wpshop.ru/plugins/clearfy?utm_source=wp-box.ru&utm_medium=article&utm_campaign=woocommerce-otklyuchenie-keshiruyushchego-cena-dlya-variaciy
В итоге задача сводится не к полному отказу от кэширования, а к точной настройке: карточка товара и AJAX вариаций должны отдавать актуальную цену, а всё остальное на сайте может и дальше работать с кэшем без лишней нагрузки.