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

Проблема: необходимость динамического изменения цены при оформлении заказа

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

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

Если попытаться изменить цену товара напрямую в объекте WC_Cart после добавления в корзину, то изменения могут не сохраниться или не отобразиться на странице оформления заказа. Это связано с тем, что WooCommerce кеширует цены и рассчитывает итоговую сумму один раз, а потом не обновляет их при повторных изменениях.

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

Пошаговое решение: динамическое изменение стоимости товара на этапе оформления

Ниже приведён пример кода, который изменяет цену товара в корзине на 10% ниже при оформлении заказа, если выбран определённый способ оплаты (например, «Оплата при получении»).

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

    // Проверяем, что корзина не пуста
    if ( did_action('woocommerce_before_calculate_totals') >= 2 ) return;

    // Получаем выбранный метод оплаты из сессии
    $chosen_payment_method = WC()->session->get('chosen_payment_method');

    // Условие для изменения цены
    if ( $chosen_payment_method === 'cod' ) { // cod - код способа оплаты «Оплата при получении»
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            $original_price = $cart_item['data']->get_regular_price();
            $discounted_price = $original_price * 0.9; // скидка 10%
            $cart_item['data']->set_price( $discounted_price );
        }
    } else {
        // Восстанавливаем оригинальные цены, если условие не выполняется
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            $cart_item['data']->set_price( $cart_item['data']->get_regular_price() );
        }
    }
}

Код нужно добавить в файл functions.php вашей темы или в отдельный плагин.

Объяснение кода:

  • Хук woocommerce_before_calculate_totals срабатывает перед пересчётом итоговой стоимости корзины.
  • Проверяется выбранный метод оплаты, который сохраняется в сессии WooCommerce.
  • Для каждого товара в корзине цена изменяется через метод set_price().
  • Если условие не выполняется, цены восстанавливаются до обычных.

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

  1. Добавьте товары в корзину.
  2. Перейдите на страницу оформления заказа (/checkout/).
  3. Выберите способ оплаты «Оплата при получении» (или тот, который вы указали в коде).
  4. Обратите внимание, что цены на товары изменятся — станут на 10% ниже.
  5. При выборе других способов оплаты цены вернутся к обычным.

Для проверки можно включить режим отладки WooCommerce или добавить в код error_log для вывода текущей цены.

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

  • Изменения не применяются: Возможно, хук вызывается некорректно или WC()->session->get('chosen_payment_method') возвращает пустое значение. Проверьте, выбран ли способ оплаты и доступна ли сессия на данном этапе.
  • Цены меняются в админке или в ненужных местах: Добавьте проверку is_admin() и !defined('DOING_AJAX'), чтобы ограничить выполнение только фронтендом.
  • Цены сбрасываются после обновления страницы: Убедитесь, что код вызывается на каждом пересчёте корзины, а не только один раз.
  • Конфликты с другими плагинами, изменяющими цены: Проверяйте приоритеты хуков и порядок загрузки плагинов.

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

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

Сравнение вариантов реализации изменения цены в WooCommerce

ВариантОписаниеПлюсыМинусы
Изменение цены через woocommerce_before_calculate_totalsДинамическое изменение цены в корзине через хукГибко, без изменения базы, работает для любых условийНужно правильно настроить условия, возможны конфликты с другими плагинами
Создание отдельного плагина для скидокИспользование плагина с настройками скидок и наценокПростой интерфейс, готовые решенияМожет быть избыточным, влияет на производительность, не всегда подходит для кастомных условий
Манипуляция ценами в базеПрямое изменение цен в базе данных продукта или заказаПостоянный эффектРиск потери данных, ошибки в отчетах, не рекомендуется
Как избежать конфликтов между плагинами в WordPress: практические советы и примеры
22.01.2026
Автоматическое удаление незавершённых заказов в WooCommerce
29.04.2026
WooCommerce: как собрать и очистить базу данных от зависших вариантов и вариантов с нулевым запасом
04.06.2026
WooCommerce: как автоматически очищать зависшие варианты товаров без плагинов
01.06.2026
Как сделать автоматическое сохранение записи в WordPress через плагин
01.02.2026