WooCommerce: как автоматически изменять стоимость доставки при определённых условиях

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

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

Как проверить текущие настройки доставки

Для начала убедитесь, какие методы доставки активны в WooCommerce:

  • Перейдите в WooCommerce > Настройки > Доставка.
  • Посмотрите зоны доставки и методы, которые к ним привязаны.
  • Запишите ID используемого метода доставки (например, flat_rate, local_pickup).

Это поможет точно нацелить код на нужный способ доставки.

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

WooCommerce позволяет менять стоимость доставки через фильтр woocommerce_package_rates. Ниже пример, как увеличить стоимость доставки на 100 рублей, если сумма корзины меньше 3000 ₽, и снизить до 0 для регионов Москвы и Московской области.

add_filter('woocommerce_package_rates', 'custom_adjust_shipping_costs', 10, 2); 
function custom_adjust_shipping_costs($rates, $package) {
    $minimum_amount = 3000; // минимальная сумма заказа
    $free_shipping_regions = array('RU-MOW', 'RU-MOS'); // коды регионов по ISO или свои
    $user_country = WC()->customer->get_shipping_country();
    $user_state = WC()->customer->get_shipping_state();

    // Проверяем регион
    $is_free_region = in_array($user_state, $free_shipping_regions);

    // Сумма корзины
    $cart_total = WC()->cart->subtotal;

    foreach ($rates as $rate_key => $rate) {
        // Пример для метода flat_rate
        if ('flat_rate' === $rate->method_id) {
            if ($is_free_region) {
                // Бесплатная доставка для регионов
                $rates[$rate_key]->cost = 0;
            } elseif ($cart_total < $minimum_amount) {
                // Добавляем 100 рублей к стоимости доставки
                $rates[$rate_key]->cost += 100;
            }
            // Можно добавить дополнительные условия
        }
    }
    return $rates;
}

Как добавить условие по товарам в корзине

Например, если в корзине есть товар с ID 15, доставка бесплатна:

function has_product_in_cart($product_id) {
    foreach(WC()->cart->get_cart() as $cart_item) {
        if ($cart_item['product_id'] == $product_id) {
            return true;
        }
    }
    return false;
}

add_filter('woocommerce_package_rates', 'custom_shipping_based_on_product', 20, 2);
function custom_shipping_based_on_product($rates, $package) {
    if (has_product_in_cart(15)) { // товар с ID 15
        foreach ($rates as $rate_key => $rate) {
            if ('flat_rate' === $rate->method_id) {
                $rates[$rate_key]->cost = 0;
            }
        }
    }
    return $rates;
}

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

  1. Очистите кеш сайта и браузера.
  2. Откройте корзину и проверьте стоимость доставки при разных суммах заказа (меньше и больше 3000 ₽).
  3. Измените адрес доставки на Москву или Московскую область, проверьте, что доставка становится бесплатной.
  4. Добавьте в корзину товар с ID 15 и убедитесь, что доставка бесплатна.
  5. Для отладки можно добавить error_log() в функцию для вывода текущих значений в wp-content/debug.log.

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

  • Не работает фильтр: убедитесь, что код добавлен в functions.php вашей активной темы или в кастомный плагин, и что WooCommerce активен.
  • Неправильные коды регионов: для российских регионов используйте коды ISO 3166-2 (например, RU-MOW для Москвы), либо проверьте, что в профиле пользователя указаны корректные данные.
  • Кэширование: если используете плагины кэширования, очистите кэш после изменений.
  • Метод доставки не flat_rate: подберите правильный method_id, например, local_pickup, free_shipping и др.
  • Стоимость доставки не меняется: проверьте, что сумма корзины берётся именно из WC()->cart->subtotal, а не из total с налогами.

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

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

Сравнение вариантов реализации изменения стоимости доставки

ВариантПлюсыМинусы
Использование фильтра woocommerce_package_ratesГибкость, нет дополнительного плагина, контроль кодаТребует навыков кодирования, возможны конфликты с другими кастомизациями
Плагины для настройки доставки (Table Rate Shipping)Интуитивный интерфейс, множество условий без кодаПлатные решения, могут замедлять сайт, лишние зависимости
Использование условий в настройках WooCommerceПросто, без кодаОграниченный функционал, нет сложных правил
Как отключить типы постов в WordPress: проблемное место и решение
28.03.2026
Как автоматизировать работу с мета-данными в WordPress
20.11.2025
Как создать настройки плагина WordPress: подробное руководство для разработчиков
03.12.2025
Создание уникального отзывного блока в WordPress с AJAX
21.12.2025
Автоматический откат обновлений WordPress при ошибках: практическое решение
23.01.2026