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

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

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

Диагностика задачи

Перед решением важно понять, какая именно логика изменения стоимости требуется:

  • Изменять цену товара на фиксированную сумму или процент;
  • Изменять общую стоимость заказа;
  • Добавлять скрытые сборы на уровне товара;
  • Применять изменение только к определённым товарам или категориям;
  • Реагировать на выбор конкретного способа доставки.

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

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

1. Отслеживаем выбор способа доставки через AJAX

WooCommerce при выборе способа доставки обновляет данные через AJAX. Можно подключиться к этому событию и сохранить выбранный метод в сессии:

add_action('woocommerce_checkout_update_order_review', 'save_chosen_shipping_method');
function save_chosen_shipping_method($posted_data) {
    parse_str($posted_data, $output);
    if (!empty($output['shipping_method'])) {
        WC()->session->set('chosen_shipping_method', $output['shipping_method'][0]);
    }
}

2. Изменяем цену товара в корзине перед расчётом итогов

Используем хук woocommerce_before_calculate_totals, чтобы динамически менять цену товара:

add_action('woocommerce_before_calculate_totals', 'change_product_price_based_on_shipping', 20, 1);
function change_product_price_based_on_shipping($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    $chosen_shipping = WC()->session->get('chosen_shipping_method');

    if (!$chosen_shipping) return;

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

        // Пример логики: если выбран способ доставки "flat_rate:5" — увеличиваем цену на 10%
        if ($chosen_shipping === 'flat_rate:5') {
            $new_price = $original_price * 1.10; // +10%
            $product->set_price($new_price);
        } else {
            // Сбрасываем цену, если другой способ доставки
            $product->set_price($original_price);
        }
    }
}

Проверка результата

  • Добавьте товар в корзину и перейдите к оформлению заказа.
  • Выберите способ доставки с ID flat_rate:5 (замените на актуальный ID вашего способа).
  • Проверьте, что цена товара изменилась на 10%.
  • Выберите другой способ доставки — цена должна вернуться к исходной.
  • Обновите страницу и убедитесь, что изменения сохраняются корректно.

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

  • Цена не меняется в корзине или на странице оформления заказа. Проверьте, что хук woocommerce_before_calculate_totals подключён с приоритетом выше 10 (чтобы перекрывать другие изменения). Также убедитесь, что сессия WooCommerce корректно сохраняет выбранный способ доставки.
  • Изменения не сохраняются при обновлении страницы. Возможно, сессия не была сохранена или выбран способ доставки сбрасывается. Проверьте работу функции сохранения в сессии и правильность ключа.
  • Ошибка на странице админки или при AJAX-запросах. Добавьте проверку if (is_admin() && !defined('DOING_AJAX')) return; в обработчик изменения цены, чтобы избежать ошибок в админке.

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

  • Изменяйте цену товара только в оперативной памяти объекта WC_Product в корзине, не сохраняйте изменения в базе данных.
  • Не используйте жёсткие ID способов доставки — получайте их динамически или документируйте, чтобы не забыть.
  • Минимизируйте количество вычислений в цикле корзины для оптимальной производительности.
  • Для более сложных сценариев рассмотрите использование пользовательских сборов (fees), если изменение цены товара не подходит.

Сравнение подходов

СпособПлюсыМинусы
Изменение цены товара через woocommerce_before_calculate_totalsГибко, напрямую меняет цену, отображается в корзинеМожно запутать пользователя, влияет на отчёты и аналитики
Добавление дополнительного сбора (fee) с учётом доставкиПрозрачно отделяет стоимость доставки от товара, проще для отчётовНе меняет цену товара, требует дополнительной настройки отображения
Использование плагинов для динамического ценообразованияРасширенный функционал, готовые решенияДополнительная нагрузка, возможны конфликты, платные решения
WooCommerce: автоматическое блокирование платёжных методов после неудачного платежа
21.07.2026
WooCommerce: автоматическое изменение стоимости товара при выборе способа доставки
15.05.2026
WooCommerce: автоматическое изменение стоимости товара при определённых условиях
03.05.2026
Автоматическое удаление старых постов в WordPress по дате публикации
18.01.2026
Как создать автоматический отчет о ошибках в WordPress
18.12.2025