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

Диагностика задачи: зачем менять стоимость товара в зависимости от доставки

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

Основная проблема — стандартное поведение WooCommerce не предусматривает изменение цены товара после выбора способа доставки, поэтому требуется кастомный код.

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

1. Использование хука woocommerce_before_calculate_totals

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

add_action('woocommerce_before_calculate_totals', 'custom_change_price_based_on_shipping', 20, 1);
function custom_change_price_based_on_shipping($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (did_action('woocommerce_before_calculate_totals') >= 2) return;

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

    $chosen_shipping = $chosen_methods[0];

    // Проходим по товарам в корзине
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $original_price = $cart_item['data']->get_regular_price();

        // Пример: если выбран способ доставки 'express_shipping', увеличиваем цену на 10%
        if ($chosen_shipping === 'express_shipping') {
            $new_price = $original_price * 1.10; // +10%
            $cart_item['data']->set_price($new_price);
        } elseif ($chosen_shipping === 'local_pickup') {
            // при самовывозе уменьшаем цену на 5%
            $new_price = $original_price * 0.95; // -5%
            $cart_item['data']->set_price($new_price);
        } else {
            // для всех остальных способов возвращаем оригинальную цену
            $cart_item['data']->set_price($original_price);
        }
    }
}

2. Определение ID или slug способа доставки

Для точной работы скрипта нужно узнать точный идентификатор способа доставки. Его можно найти в админке WooCommerce (Настройки > Доставка > Зоны доставки) или через вывод массива WC()->session->get('chosen_shipping_methods') с помощью error_log(print_r(...)).

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

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

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

  • Добавьте товар в корзину.
  • Перейдите на страницу корзины или оформления заказа.
  • Выберите способ доставки, например, «Экспресс-доставка».
  • Убедитесь, что цена товара изменилась в соответствии с заданным процентом.
  • Смените способ доставки на «Самовывоз» — цена должна уменьшиться.
  • Выберите другой способ — цена возвращается к оригиналу.

Частые ошибки и причины их возникновения

  • Изменения цены не применяются или сбрасываются: Возможно, в хуке происходит повторное срабатывание, из-за чего цены меняются несколько раз. Решение — использовать проверку did_action('woocommerce_before_calculate_totals') < 2.
  • Цена меняется, но итоговая сумма в корзине не обновляется: Отсутствует AJAX-обновление корзины при смене способа доставки. Требуется проверить тему на поддержку AJAX в корзине.
  • Неверный идентификатор способа доставки: Нужно убедиться, что slug способа доставки совпадает с тем, который используется в коде.
  • Изменение цены влияет на отображение в других местах (например, на странице товара): Изменяйте цену только для объектов в корзине, не меняйте глобальные цены товара.

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

  • Не сохраняйте изменённые цены в базу данных — меняйте цену только в объекте WC_Product в корзине.
  • Используйте минимально необходимый приоритет для хука (например, 20), чтобы избежать конфликтов с другими плагинами.
  • Проверяйте, что функция не вызывается в админке или при AJAX-запросах, не связанных с фронтендом.

Сравнение вариантов реализации

МетодПреимуществаНедостатки
Код на хуке woocommerce_before_calculate_totalsГибкость, не требует плагинов, прямое управление ценамиТребует навыков программирования, возможны конфликты с другими плагинами
Плагины для управления ценами в зависимости от доставкиПростота настройки, поддержка, готовые решенияМогут быть платными, нагружают сайт, ограничены функционалом
Изменение цен через JS на фронтендеМоментальное обновление UI, без вмешательства в серверный кодНе влияет на реальные данные заказа, легко обойти, небезопасно
Как сделать загрузку изображений по требованию в WordPress для ускорения сайта
15.12.2025
Как избежать проблем с перезапуском AJAX-запросов в WordPress
07.04.2026
WooCommerce: установка лимитов на количество товаров в корзине по ролям пользователей
19.06.2026
Как удалить пустые категории и метки в базе данных WordPress
07.01.2026
Автоматическое удаление неактивных пользователей WordPress
08.02.2026