Диагностика задачи: зачем нужна автоматическая смена цен по акциям
В крупных интернет-магазинах на WooCommerce часто требуется динамически менять цены товаров в зависимости от текущих акций, даты или определённых условий (например, наличие на складе, роль пользователя, категория товара). Ручное обновление цен неудобно и чревато ошибками, особенно при большом ассортименте.
Основная задача — реализовать автоматическое обновление стоимости товара без сторонних плагинов, с возможностью гибко задавать условия и сроки действия скидок.
Как проверить, что цена меняется автоматически и корректно
- Установите тестовый товар с базовой ценой и датой акции.
- Проверьте, что при заходе на страницу товара отображается цена с учётом скидки в рамках даты акции.
- Вне периода акции цена должна возвращаться к исходной.
- Проверьте работу для разных товаров и условий.
Пошаговое решение: изменение цены через хук WooCommerce
В WooCommerce для динамического изменения цены товара во фронтенде используется фильтр woocommerce_product_get_price и woocommerce_product_get_regular_price. Они позволяют переопределить цену для отображения и расчётов.
Пример кода, который меняет цену товара на 30% скидку в период акции:
<?php
// Добавляем в functions.php темы или в кастомный плагин
add_filter('woocommerce_product_get_price', 'custom_dynamic_sale_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_sale_price', 10, 2);
function custom_dynamic_sale_price($price, $product) {
// ID товара или категория для акции
$promo_product_ids = array(123, 456); // ID товаров
$promo_category_slug = 'sale'; // категория для акции
// Даты акции
$start_date = strtotime('2024-06-01');
$end_date = strtotime('2024-06-15');
$today = current_time('timestamp');
// Проверяем дату
if ($today < $start_date || $today > $end_date) {
return $price; // вне акции
}
// Проверяем товар по ID или категории
if (in_array($product->get_id(), $promo_product_ids) || has_term($promo_category_slug, 'product_cat', $product->get_id())) {
// Скидка 30%
$new_price = $price * 0.7;
return round($new_price, 2);
}
return $price;
}
Этот код подменит цену товара при выводе на сайте в указанный период и для заданных товаров или категории.
Расширение: учитываем роль пользователя для персональных скидок
add_filter('woocommerce_product_get_price', 'custom_dynamic_price_for_roles', 20, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price_for_roles', 20, 2);
function custom_dynamic_price_for_roles($price, $product) {
if (!is_user_logged_in()) {
return $price;
}
$user = wp_get_current_user();
if (in_array('wholesale_customer', $user->roles)) {
// Дополнительные 10% скидки для оптовиков
$price = $price * 0.9;
}
return round($price, 2);
}
Проверка результата после внедрения
- Очистите кэш сайта и браузера.
- Откройте страницу товара с ID из массива или в категории акции.
- Проверьте цену - она должна быть на 30% ниже базовой.
- Измените системную дату или подождите наступления периода акции, чтобы проверить отключение скидки.
- Залогиньтесь как пользователь с ролью «wholesale_customer» и проверьте дополнительную скидку.
Частые ошибки и как их исправить
- Цена не меняется на сайте: Проверьте, что фильтры подключены именно в
functions.phpили кастомном плагине, который активен. - Цена меняется, но не в корзине или на странице оплаты: WooCommerce кеширует цены, добавьте те же фильтры на хуки
woocommerce_cart_item_priceиwoocommerce_cart_item_subtotalпри необходимости. - Ошибка при проверке категории товара: Убедитесь, что слаг категории указан правильно и товары действительно в ней состоят.
- Скругление цен приводит к неправильным суммам: Используйте функцию
round()с нужным числом знаков после запятой (обычно 2).
Практические советы по производительности и безопасности
- Для большого каталога кешируйте результаты проверки условий акции, чтобы не вызывать
has_term()и другие тяжелые функции на каждом запросе. - Не используйте тяжелые SQL-запросы в фильтрах цены — это замедлит загрузку страниц.
- Обязательно тестируйте код в staging-среде перед внедрением на живом сайте.
- Для сложных акций и массовых изменений цен рассмотрите использование WP-Cron для периодического обновления метаданных товара с фиксированными скидками.
Сравнение подходов к автоматическому изменению цен
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
Фильтры woocommerce_product_get_price | Гибко, без плагинов, динамически | Нагрузка на запросы, сложнее отладка | Код выше |
| Периодическое обновление метаданных товара | Оптимально для большого каталога | Сложнее реализация, требуется WP-Cron | Обновлять _price и _sale_price |
| Плагины акций и скидок | Готовое решение, удобный UI | Зависимость от стороннего кода, нагрузка | WooCommerce Dynamic Pricing и др. |