WooCommerce: автоматическое изменение стоимости товаров при акциях без плагинов

Диагностика проблемы: почему нужно менять цены автоматически при акциях

В WooCommerce часто возникает задача автоматически изменять цены товаров при проведении акций, не прибегая к громоздким плагинам. Например, вы хотите временно снизить цену на 20% или установить фиксированную скидочную цену на определённый период. Без автоматизации это приходится делать вручную: менять каждую цену, а потом возвращать обратно. Это неудобно и чревато ошибками.

Автоматическое изменение цен позволяет:

  • Экономить время на массовых распродажах.
  • Обеспечивать корректное отображение скидок на сайте и в корзине.
  • Избежать ручных ошибок при выставлении цен.

Основные подходы к решению задачи в WooCommerce

В WooCommerce цены товаров хранятся в мета-полях _regular_price (обычная цена) и _sale_price (цена со скидкой). Чтобы автоматизировать изменение цен, можно программно устанавливать _sale_price для товаров в определённый период, а потом сбрасывать его.

Рассмотрим два варианта реализации:

1. Использование WP-Cron для автоматического запуска скрипта по расписанию

WP-Cron позволяет запускать PHP-функции по расписанию. Это удобно для установки и снятия акций в нужное время.

2. Изменение цен на лету при выводе товара без сохранения в базу

Этот метод подходит, если хотите показывать скидку, но не менять данные в БД (например, для временной акции или теста). Для этого используется фильтр 'woocommerce_get_price'.

Пошаговое решение с WP-Cron: установка и снятие акций по времени

Шаг 1. Добавляем функцию для запуска акции

function wpzoom_set_sale_price_for_products() {
    $args = [
        'post_type' => 'product',
        'posts_per_page' => -1,
        'post_status' => 'publish',
    ];
    $products = get_posts($args);
    foreach ( $products as $product_post ) {
        $product = wc_get_product($product_post->ID);
        $regular_price = (float) $product->get_regular_price();
        if ( $regular_price > 0 ) {
            $sale_price = $regular_price * 0.8; // скидка 20%
            update_post_meta($product->get_id(), '_sale_price', $sale_price);
            update_post_meta($product->get_id(), '_price', $sale_price);
        }
    }
}

Шаг 2. Добавляем функцию для снятия акции

function wpzoom_remove_sale_price_for_products() {
    $args = [
        'post_type' => 'product',
        'posts_per_page' => -1,
        'post_status' => 'publish',
    ];
    $products = get_posts($args);
    foreach ( $products as $product_post ) {
        $product = wc_get_product($product_post->ID);
        $regular_price = (float) $product->get_regular_price();
        update_post_meta($product->get_id(), '_sale_price', '');
        update_post_meta($product->get_id(), '_price', $regular_price);
    }
}

Шаг 3. Добавляем расписание WP-Cron

function wpzoom_schedule_sale_events() {
    if ( ! wp_next_scheduled( 'wpzoom_start_sale_event' ) ) {
        // Запуск акции 1 декабря в 00:00
        wp_schedule_event( strtotime('2024-12-01 00:00:00'), 'daily', 'wpzoom_start_sale_event' );
    }
    if ( ! wp_next_scheduled( 'wpzoom_end_sale_event' ) ) {
        // Окончание акции 10 декабря в 23:59
        wp_schedule_event( strtotime('2024-12-10 23:59:00'), 'daily', 'wpzoom_end_sale_event' );
    }
}
add_action( 'wp', 'wpzoom_schedule_sale_events' );

add_action( 'wpzoom_start_sale_event', 'wpzoom_set_sale_price_for_products' );
add_action( 'wpzoom_end_sale_event', 'wpzoom_remove_sale_price_for_products' );

Шаг 4. Очистка при деактивации темы или плагина

function wpzoom_clear_sale_schedule() {
    $timestamp_start = wp_next_scheduled('wpzoom_start_sale_event');
    if ($timestamp_start) wp_unschedule_event($timestamp_start, 'wpzoom_start_sale_event');

    $timestamp_end = wp_next_scheduled('wpzoom_end_sale_event');
    if ($timestamp_end) wp_unschedule_event($timestamp_end, 'wpzoom_end_sale_event');
}
register_deactivation_hook( __FILE__, 'wpzoom_clear_sale_schedule' );

Проверка результата после внедрения

Чтобы убедиться, что автоматическое изменение цен работает корректно:

  1. Проверьте в админке WooCommerce, что у товаров появляется sale price в указанный период.
  2. Перейдите на страницу товара на сайте — должна отображаться сниженная цена.
  3. В корзине и на странице оформления заказа скидка должна сохраняться.
  4. Проверьте логи WP-Cron, убедитесь, что события запускаются в нужное время.

Частые ошибки и как их исправить

  • WP-Cron не срабатывает: Проверьте, что на сайте есть трафик, либо настройте системный cron в сервере для запуска wp-cron.php.
  • Цена не обновляется после запуска функции: Проверьте, что у товаров есть заполнено поле _regular_price. Без него скидка не посчитается.
  • Скидка не отображается на фронтенде: Проверьте, не кешируется ли страница. Очистите кеш, отключите плагины кеширования для теста.
  • Расписание создаётся многократно: Используйте wp_next_scheduled для проверки перед созданием событий.

Практические советы по безопасности и производительности

  • При массовом обновлении цен используйте WP-CLI для ускорения и снижения нагрузки: wp post list --post_type=product --field=ID | xargs -n1 -P10 -I % wp post meta update % _sale_price 80 с нужным значением.
  • Для больших магазинов разбивайте обновление цен на части — например, обновляйте по 100 товаров за один запуск WP-Cron.
  • Не оставляйте в базе неиспользуемые мета-поля — удаляйте _sale_price после окончания акции.
  • Резервируйте базу перед массовыми изменениями цен.

Сравнение подходов: WP-Cron vs изменение цен на лету

КритерийWP-Cron (сохранение в БД)Изменение цен на лету (фильтр)
Влияние на базу данныхМеняет цены в базеНе меняет, только отображение
ПроизводительностьНагрузка при массовом обновленииНагрузка при каждом выводе цены
Сложность реализацииСредняяНизкая
Возможность массовых акцийОтлично подходитТолько для временных визуальных скидок
Совместимость с корзиной и оплатойПолнаяМожет требовать дополнительной настройки

Пример использования фильтра для временной скидки без записи в базу

add_filter('woocommerce_get_price', 'wpzoom_temporary_price_discount', 10, 2);
function wpzoom_temporary_price_discount($price, $product) {
    $current_time = current_time('timestamp');
    $start = strtotime('2024-12-01 00:00:00');
    $end = strtotime('2024-12-10 23:59:59');
    if ( $current_time >= $start && $current_time <= $end ) {
        return $price * 0.8; // скидка 20%
    }
    return $price;
}

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
WooCommerce: автоматическое отключение неактивных методов оплаты
25.09.2026
Как создать и использовать атрибуты шорткода в WordPress с примерами кода
18.09.2026
Как отключить системные письма WordPress без плагинов
20.09.2026
Как удалить лишние метаданные из изображений в WordPress для ускорения сайта
18.09.2026
WooCommerce: автоматическое обновление атрибутов товаров при массовом импорте
18.09.2026
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше