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

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

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

Диагностика проблемы: почему стандартная настройка не подходит

В WooCommerce есть возможность задать зоны доставки и методы для них, но:

  • Методы доставки обычно фиксируют цену или зависят от веса, но не учитывают регион и вес одновременно.
  • Плагины для расширенного расчета доставки часто платные, имеют избыточный функционал и нагрузку.
  • Настройка тарифов вручную в админке становится громоздкой при множестве регионов и весовых категорий.

Поэтому лучший путь — использовать хук woocommerce_package_rates для программного изменения стоимости доставки после расчета.

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

1. Получаем регион покупателя

Обычно регион определяется по адресу доставки в заказе. В коде это можно получить через объект $package в хуке woocommerce_package_rates:

add_filter('woocommerce_package_rates', 'custom_change_shipping_cost_by_region_and_weight', 10, 2);

В функции $package['destination']['state'] или $package['destination']['country'] — регион и страна доставки.

2. Получаем вес заказа

Вес заказа в килограммах можно получить через сумму веса товаров в корзине:

function get_cart_weight() {
    $weight = 0;
    foreach (WC()->cart->get_cart() as $cart_item) {
        $weight += floatval($cart_item['data']->get_weight()) * $cart_item['quantity'];
    }
    return $weight;
}

3. Меняем стоимость доставки

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

function custom_change_shipping_cost_by_region_and_weight($rates, $package) {
    $region = $package['destination']['state']; // Или 'country' если нужно
    $weight = 0;
    foreach (WC()->cart->get_cart() as $cart_item) {
        $weight += floatval($cart_item['data']->get_weight()) * $cart_item['quantity'];
    }

    foreach ($rates as $rate_id => $rate) {
        // Пример условий для региона и веса
        if ($region === 'RU-MOW') { // Москва
            if ($weight <= 5) {
                $rates[$rate_id]->cost = 300; // 300 руб до 5 кг
            } else {
                $rates[$rate_id]->cost = 500; // 500 руб свыше 5 кг
            }
        } elseif ($region === 'RU-SPE') { // Санкт-Петербург
            if ($weight <= 5) {
                $rates[$rate_id]->cost = 350;
            } else {
                $rates[$rate_id]->cost = 550;
            }
        } else {
            // Для других регионов оставить стандартную цену или задать свою
            $rates[$rate_id]->cost = 600;
        }
    }
    return $rates;
}
add_filter('woocommerce_package_rates', 'custom_change_shipping_cost_by_region_and_weight', 10, 2);

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

  1. Добавьте товары с разным весом в корзину.
  2. Укажите адрес доставки с разными регионами (Москва, Санкт-Петербург, другие).
  3. На странице оформления заказа проверьте стоимость доставки — она должна менять цену в соответствии с заданными условиями.
  4. Для отладки можно временно добавить error_log() внутри функции, чтобы выводить вычисленные значения региона и веса.

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

  • Регион не определяется корректно: Проверьте, что в $package['destination']['state'] приходит нужное значение. Иногда стоит использовать $package['destination']['city'] или country, в зависимости от настроек зоны доставки.
  • Вес товара не задан или не в килограммах: Убедитесь, что у товаров в WooCommerce заполнено поле «Вес» (в настройках магазина указан нужный единица измерения).
  • Стоимость доставки не меняется: Проверьте приоритет хука — 10 обычно подходит, но если есть другие плагины, конфликтующие с этим фильтром, может понадобиться повысить приоритет, например, 20.
  • Стоимость неправильная из-за кеширования: Очистите кеш WooCommerce и браузера, отключите кеширование страниц при тестировании.

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

  • Не используйте тяжелые вычисления внутри хука woocommerce_package_rates, чтобы не замедлять загрузку страницы оформления заказа.
  • Если код усложняется, рассмотрите кеширование вычисленных значений с помощью Transient API для уменьшения нагрузки.
  • Следите за обновлениями WooCommerce — иногда внутренние структуры $package могут меняться, проверяйте совместимость кода.

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

ВариантПреимуществаНедостатки
Код через хук woocommerce_package_ratesЛегкий, быстрый, гибкий, не требует доп. плагиновТребует навыков PHP, ручная поддержка при изменениях требований
Платные плагины для расчета доставкиГотовый функционал, поддержка, GUI для настройкиСтоимость, нагрузка, избыточность функций
Использование зон доставки WooCommerceПростота, встроенный функционалМалая гибкость при сложных условиях
WooCommerce: автоматическое изменение стоимости доставки по зонам
24.05.2026
WooCommerce: автоматическое изменение заказов при изменении стоимости доставки
30.04.2026
Как создать автоматический генератор ответов в комментариях WordPress с помощью WPGPT
13.03.2026
Как создать автоматический генератор изображений для постов WordPress с помощью GPT
17.04.2026
Как создать автоматический генератор SEO-заголовков в WordPress с помощью PHP и WPGPT
01.03.2026