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

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

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

Основные вопросы для диагностики:

  • Какой эффект требуется: изменить цену конкретного товара или итоговую сумму корзины?
  • Нужно ли сохранять корректную историю заказов?
  • Как не повредить совместимость с другими плагинами?

Как отследить выбор способа доставки в WooCommerce

Способ доставки в WooCommerce выбирается на странице оформления заказа (checkout). Для динамического изменения цены в корзине или на странице товара необходимо реагировать на изменение способа доставки в реальном времени.

Для этого можно использовать AJAX-хуки WooCommerce и PHP-фильтры, в частности:

  • woocommerce_package_rates — фильтр для изменения доступных способов доставки;
  • woocommerce_cart_calculate_fees — добавление дополнительных сборов;
  • JavaScript-события на странице оформления заказа для отслеживания выбора способа доставки.

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

1. Добавляем JavaScript для отслеживания выбора способа доставки

jQuery(function($){
    $('form.checkout').on('change', 'input[name^="shipping_method"]', function(){
        $('body').trigger('update_checkout');
    });
});

Этот код заставляет WooCommerce обновлять данные корзины при смене способа доставки.

2. Изменяем цену товара в корзине на сервере

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

    // Получаем выбранный способ доставки
    $chosen_methods = WC()->session->get('chosen_shipping_methods');
    if (empty($chosen_methods)) return;

    $shipping_method = $chosen_methods[0];

    // Пример: если выбран способ доставки 'flat_rate:10', увеличиваем цену товара на 15%
    if ($shipping_method === 'flat_rate:10') {
        foreach ($cart->get_cart() as $cart_item) {
            $original_price = $cart_item['data']->get_regular_price();
            $new_price = $original_price * 1.15; // +15%
            $cart_item['data']->set_price($new_price);
        }
    } else {
        // В остальных случаях восстанавливаем оригинальную цену
        foreach ($cart->get_cart() as $cart_item) {
            $original_price = $cart_item['data']->get_regular_price();
            $cart_item['data']->set_price($original_price);
        }
    }
}

3. Очистка цены при смене способа доставки

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

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

  1. Перейдите в корзину или оформление заказа.
  2. Выберите способ доставки flat_rate:10 (или указанный в вашем магазине).
  3. Убедитесь, что цена товара изменилась на 15% больше.
  4. Выберите другой способ доставки — цена должна вернуться к исходной.
  5. Проверьте, что на странице оплаты итоговая сумма корректна и соответствует ожиданиям.

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

  • Цена товара не меняется при выборе способа доставки
    Проверьте, вызывается ли update_checkout в JS. Без этого сервер не обновляет корзину при смене доставки.
  • Наценка накапливается при повторном выборе способов доставки
    Убедитесь, что в коде в блоке else правильно восстанавливается исходная цена (используйте get_regular_price(), а не текущее значение).
  • Изменение цены ломает совместимость с плагинами кеширования
    Отключите кеширование страниц корзины и оформления заказа или настройте исключения.
  • Цена меняется в админке
    Добавьте проверку if (is_admin() && !defined('DOING_AJAX')) return; для предотвращения изменений в бэкенде.

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

  • Не изменяйте цену товара в базе данных напрямую — меняйте только в объекте $cart_item['data'] для текущей сессии.
  • Избегайте слишком сложных вычислений в хукe woocommerce_before_calculate_totals, чтобы не ухудшать скорость работы корзины.
  • Тестируйте работу в разных браузерах и с разными плагинами кеширования.
  • Используйте child-тему или собственный плагин для добавления кода, чтобы не потерять изменения при обновлении WooCommerce.

Сравнение способов реализации

МетодПлюсыМинусы
Изменение цены товара в woocommerce_before_calculate_totalsГибкое, меняет цену именно товара, легко контролироватьНужно аккуратно сбрасывать цену, возможны конфликты с кешем
Добавление сборов woocommerce_cart_calculate_feesПросто добавить дополнительную плату без изменения цены товараНе меняет цену товара, сборы отображаются отдельно
JavaScript-манипуляции на фронтендеБыстро и просто для визуального измененияНе влияет на итоговые расчёты, ненадёжно
Как установить и настроить OmniVideo в WordPress
25.02.2026
Как запретить доступ к страницам в WordPress по IP адресу
12.03.2026
Как автоматизировать управление ролями в WordPress с помощью кода
22.12.2025
Как избежать повторов контента в WordPress: практические методы и примеры кода
22.02.2026
Как удалить автоматически неиспользуемые шорткоды в WordPress
01.04.2026