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

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

В стандартном WooCommerce цены товаров фиксированы и меняются вручную через админку или массовыми правками. Однако часто возникает задача динамически изменять цену товара при обновлении заказа — например, применять скидку, добавлять наценку или менять цену в зависимости от статуса заказа или других условий.

Типичные сценарии:

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

Без кастомного кода WooCommerce не поддерживает такие изменения автоматически, что приводит к необходимости ручной правки или использования сторонних плагинов.

Как отследить обновление заказа и изменить цены товаров

Для решения задачи нужно использовать хук woocommerce_before_calculate_totals, который вызывается при пересчёте корзины и заказа. Обновлять цену товара в заказе нужно именно через объекты WC_Order_Item_Product.

Пример кода, который применяет скидку 10% ко всем товарам, если заказ обновляется и статус — «обрабатывается»:

add_action('woocommerce_before_calculate_totals', 'custom_modify_order_item_prices', 10, 1);
function custom_modify_order_item_prices($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;

    // Проверяем, что объект корзины
    if (did_action('woocommerce_before_calculate_totals') >= 2) return;

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $original_price = $product->get_regular_price();

        // Пример логики: скидка 10% при обновлении заказа
        $new_price = $original_price * 0.9;
        $product->set_price($new_price);
    }
}

Для изменения цены товаров непосредственно в заказе (после оформления) нужно работать с объектом заказа, например, по событию woocommerce_order_edit_status или woocommerce_order_status_changed:

add_action('woocommerce_order_status_changed', 'custom_update_order_item_prices', 10, 4);
function custom_update_order_item_prices($order_id, $old_status, $new_status, $order) {
    if ($new_status !== 'processing') return; // ограничиваем по статусу

    foreach ($order->get_items() as $item_id => $item) {
        $product = $item->get_product();
        $original_price = $product->get_regular_price();

        $new_price = $original_price * 0.9; // скидка 10%
        $item->set_subtotal($new_price * $item->get_quantity());
        $item->set_total($new_price * $item->get_quantity());
        $item->save();
    }

    $order->calculate_totals();
    $order->save();
}

Пошаговое решение: как внедрить и проверить корректировку цены

  1. Добавьте один из приведённых выше фрагментов кода в файл темы functions.php или в собственный плагин.
  2. Обновите корзину или измените статус заказа (в зависимости от выбранного хука).
  3. Перейдите в админку WooCommerce → Заказы и откройте изменённый заказ.
  4. Проверьте цены товаров и итоговую сумму — они должны измениться согласно логике скрипта.
  5. Если работает с корзиной — проверьте цену товара непосредственно в клиентской части сайта, обновив корзину.

Как проверить, что цена изменилась

  • В админке откройте заказ и посмотрите цены в блоке товаров — они должны соответствовать новым значениям.
  • Проверьте итоговую сумму заказа — она должна пересчитаться автоматически.
  • В корзине при использовании woocommerce_before_calculate_totals — убедитесь, что цены отображаются с учётом скидки.
  • Для отладки можно добавить error_log внутри функций, чтобы убедиться, что они вызываются.

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

  • Изменение цены товара не влияет на итог заказа. Причина: не вызван $order->calculate_totals() и $order->save() после изменения цен в заказе. Решение: добавьте эти вызовы.
  • Цена меняется, но только в админке, а не на сайте. Причина: изменение происходит только в объекте WC_Order_Item_Product без обновления корзины. Решение: для фронтенда используйте woocommerce_before_calculate_totals.
  • Цены меняются несколько раз подряд. Причина: хук вызывается многократно без проверки. Решение: добавьте проверку с помощью did_action.
  • Изменения не сохраняются. Причина: не вызван метод save() у объекта заказа или элементов.

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

  • Не изменяйте цены в цикле без ограничений — используйте проверки статуса заказа или условия для минимизации нагрузки.
  • Для масштабируемости лучше инкапсулировать логику в отдельный класс.
  • Всегда тестируйте изменения на тестовой среде, чтобы избежать потери данных или ошибок при оплате.
  • Используйте transient или метаданные заказа для хранения информации о применённых скидках, чтобы избежать повторных изменений.

Сравнение способов реализации автоматической корректировки цены

МетодГде применяетсяПлюсыМинусы
Хук woocommerce_before_calculate_totalsКорзина, оформление заказаИзменяет цену до оформленияНе изменяет уже оформленные заказы
Хук woocommerce_order_status_changedРедактирование заказов после оформленияМеняет цену в заказе, учитывается в оплатеНе влияет на корзину, требует пересчёта заказа
Плагины динамического ценообразованияГотовые решенияМного функций, удобный интерфейсМогут быть тяжелыми и дорогими

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

⭐⭐⭐⭐⭐
Как создать пользовательские типы записей (Custom Post Types) в WordPress
08.11.2025
Как в WooCommerce автоматически исключить из каталога товары без остатка на складе
21.04.2026
Как использовать WP GPT для автоматизации создания контента в WordPress
06.02.2026
Автоматическое отключение плагинов в WordPress по расписанию: практическое руководство
26.12.2025
WooCommerce: автоматическое отключение неактивных способов оплаты
28.05.2026
×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее