WooCommerce: автоматическое изменение цен и скидок при обновлении атрибутов товара

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

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

Без автоматизации это требует постоянного ручного обновления, что неудобно и ошибочно. Поэтому задача — реализовать автоматическую корректировку цены и скидки товара в зависимости от выбранных или обновлённых атрибутов.

Как определить, что цена не обновляется корректно

  • Вы изменяете атрибуты товара в админке или через импорт, но цена вариации остаётся прежней.
  • При смене атрибута на фронтенде цена не меняется динамически (если это требуется).
  • В панели заказов и на сайте отображаются старые цены, не учитывающие новые атрибуты.

Пошаговое решение: автоматическое изменение цены и скидок через хук сохранения вариации

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

1. Подключаем функцию к хуку

add_action('woocommerce_save_product_variation', 'wpset_update_variation_price_on_attribute_change', 10, 2);

2. Реализуем функцию изменения цены

function wpset_update_variation_price_on_attribute_change($variation_id, $i) {
    $variation = wc_get_product($variation_id);
    if (!$variation) {
        return;
    }

    // Получаем атрибуты вариации
    $attributes = $variation->get_attributes();

    // Пример логики: если атрибут 'pa_material' равен 'premium', увеличиваем цену на 20%
    if (isset($attributes['pa_material']) && $attributes['pa_material'] === 'premium') {
        $regular_price = $variation->get_regular_price();
        if ($regular_price) {
            $new_price = $regular_price * 1.2; // +20%
            $variation->set_price($new_price);
            $variation->set_regular_price($new_price);

            // Можно задать скидку, например, 10% от новой цены
            $sale_price = $new_price * 0.9;
            $variation->set_sale_price($sale_price);
        }
    } else {
        // Если материал не premium, сбрасываем скидку и возвращаем базовую цену
        // Предположим, базовая цена хранится в метаполе '_base_price'
        $base_price = get_post_meta($variation_id, '_base_price', true);
        if ($base_price) {
            $variation->set_price($base_price);
            $variation->set_regular_price($base_price);
            $variation->set_sale_price('');
        }
    }

    $variation->save();
}

3. Сохраняем базовую цену при создании вариации

Чтобы иметь эталон цены, можно сохранить базовую цену при создании вариации или вручную добавить метаполе _base_price для уже созданных вариаций.

add_action('woocommerce_save_product_variation', 'wpset_save_base_price_variation', 20, 2);
function wpset_save_base_price_variation($variation_id, $i) {
    $variation = wc_get_product($variation_id);
    if ($variation && !get_post_meta($variation_id, '_base_price', true)) {
        update_post_meta($variation_id, '_base_price', $variation->get_regular_price());
    }
}

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

  • Создайте или отредактируйте вариацию, установив атрибут pa_material в premium.
  • Сохраните вариацию и проверьте, что цена увеличилась на 20%, а скидка применена.
  • Измените атрибут на другой и убедитесь, что цена вернулась к базовой и скидка снялась.
  • Проверьте на фронтенде (если вариации доступны для выбора) — цена должна соответствовать логике.

Частые ошибки и причины с их устранением

  • Ничего не меняется после сохранения вариации: проверьте, что вы используете правильный атрибут (с префиксом pa_) и значение соответствует реально существующему в WooCommerce.
  • Цена не обновляется на фронтенде: убедитесь, что кэш очищен, а тема корректно выводит обновлённую цену вариации.
  • Ошибка при сохранении вариации: проверьте права пользователя, а также правильность вызова $variation->save() и отсутствие конфликтов с другими плагинами.
  • Скидка не применяется: убедитесь, что для вариации выставлена sale_price, и она ниже regular_price.

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

  • Всегда проверяйте существование объекта продукта перед изменениями.
  • Минимизируйте общее количество операций сохранения вариаций за одну сессию, чтобы не перегружать базу.
  • Кэшируйте результаты, если применяете сложную логику вычисления цены.
  • Используйте wp_cache_delete() для очистки кэша WooCommerce при необходимости.
  • Тестируйте изменения на staging-среде, чтобы избежать сбоев в рабочем магазине.

Сравнение вариантов реализации автоматического изменения цены

МетодПреимуществаНедостаткиКогда использовать
Использование хуков (как в статье) Гибко, не требует плагинов, легко кастомизировать Требует навыков программирования, можно допустить ошибки Для индивидуальных проектов с уникальной логикой
Плагины для управления вариациями и ценами Простота настройки, поддержка, готовые функции Может замедлять сайт, ограничены возможностями Для быстрых решений без кода
Импорт и обновление через CSV с ценами Удобно для массовых изменений Менее динамично, требует повторного импорта При массовом обновлении большого каталога
Как создать уникальный вид записи в WordPress с помощью кода
30.01.2026
Как установить и настроить Redis кэш в WordPress
23.11.2025
Реактивный фильтрованный вывод постов в WordPress с AJAX
20.03.2026
Как установить и настроить WPRemark для расширенного комментирования в WordPress
19.02.2026
Как удалить ревизии записей в WordPress без плагинов
14.12.2025