Диагностика задачи: зачем менять стоимость доставки автоматически
В 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;
}
Проверка результата после внедрения
- Очистите кеш сайта и браузера.
- Откройте корзину и проверьте стоимость доставки при разных суммах заказа (меньше и больше 3000 ₽).
- Измените адрес доставки на Москву или Московскую область, проверьте, что доставка становится бесплатной.
- Добавьте в корзину товар с ID 15 и убедитесь, что доставка бесплатна.
- Для отладки можно добавить
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 | Просто, без кода | Ограниченный функционал, нет сложных правил |