В чем суть задачи и когда это нужно
Интернет-магазины на WooCommerce часто используют разные тарифы доставки в зависимости от веса заказа. Например, до 1 кг доставка стоит 200 рублей, от 1 до 5 кг — 400 рублей, свыше 5 кг — 700 рублей. Стандартные настройки WooCommerce позволяют задать фиксированные зоны доставки, но для гибкой тарификации по весу требуется кастомизация. В этой статье разберем, как автоматически изменить стоимость доставки в корзине в зависимости от суммарного веса товаров без сторонних плагинов.
Диагностика проблемы: почему стандартные методы не подходят
WooCommerce по умолчанию не умеет динамически менять стоимость доставки внутри одной зоны в зависимости от веса. Есть варианты с плагинами, например WooCommerce Table Rate Shipping, но они платные и иногда избыточны. При попытке использовать стандартные способы, например, несколько методов доставки с разными весовыми ограничениями, пользователь видит несколько вариантов, что может запутать. Поэтому лучше программно изменять стоимость единственного метода доставки в зависимости от веса корзины.
Пошаговое решение: код для автоматической смены стоимости доставки
1. Создаем метод доставки с минимальной стоимостью
В настройках WooCommerce > Доставка создайте зону и добавьте способ «Фиксированная ставка» с базовой стоимостью, например, 200 рублей. Этот способ мы будем менять программно.
2. Добавляем фильтр для изменения стоимости метода доставки
В файл functions.php вашей темы или в кастомный плагин добавьте следующий код:
add_action('woocommerce_package_rates', 'change_shipping_cost_by_weight', 10, 2);
function change_shipping_cost_by_weight( $rates, $package ) {
$total_weight = 0;
foreach ( WC()->cart->get_cart() as $cart_item ) {
$total_weight += $cart_item['data']->get_weight() * $cart_item['quantity'];
}
// Вес в килограммах
$total_weight = floatval( $total_weight );
foreach ( $rates as $rate_key => $rate ) {
if ( 'flat_rate' === $rate->method_id ) { // проверяем нужный метод
if ( $total_weight <= 1 ) {
$rates[ $rate_key ]->cost = 200;
} elseif ( $total_weight <= 5 ) {
$rates[ $rate_key ]->cost = 400;
} else {
$rates[ $rate_key ]->cost = 700;
}
// Обновляем налоги, если есть
if ( ! empty( $rates[ $rate_key ]->taxes ) ) {
$tax_rates = WC_Tax::get_rates( $rate->tax_status );
$taxes = WC_Tax::calc_tax( $rates[ $rate_key ]->cost, $tax_rates, false );
$rates[ $rate_key ]->taxes = $taxes;
}
}
}
return $rates;
}3. Убедитесь, что у товаров указан вес
Для корректной работы необходимо, чтобы у каждого товара в карточке был установлен вес (в килограммах). Без этого расчет будет некорректен.
Как проверить, что решение работает
- Добавьте в корзину товары с весом, чтобы суммарный вес был меньше 1 кг — стоимость доставки должна быть 200 рублей.
- Увеличьте вес до значения от 1 до 5 кг — стоимость доставки должна измениться на 400 рублей.
- Добавьте товаров, чтобы общая масса превысила 5 кг — цена доставки станет 700 рублей.
- Обновите корзину и убедитесь, что стоимость доставки меняется без ошибок.
Частые ошибки и как их исправить
- Вес товаров не задан: Проверьте, что в карточках товаров заполнено поле «Вес» в граммах или килограммах. Без этого расчет невозможен.
- Метод доставки не называется «flat_rate»: Если вы используете кастомные методы доставки, поменяйте условие
'flat_rate' === $rate->method_idна ваш ID метода. - Стоимость не обновляется в корзине: Проверьте, что код добавлен в активную тему или плагин, и что нет конфликтов с другими плагинами по доставке.
- Налоги считаются некорректно: Убедитесь, что в WooCommerce правильно настроены налоговые ставки и статус налогообложения доставки.
Практические советы по безопасности и производительности
- Не используйте тяжелые плагины для простого изменения стоимости доставки, если можно обойтись кодом.
- Добавляйте код в дочернюю тему или в отдельный плагин, чтобы не потерять изменения при обновлении.
- Кэширование страниц с корзиной отключайте или исключайте, чтобы динамическая стоимость доставки всегда была актуальной.
- Проверяйте валидность данных веса товаров — можно добавить валидацию при сохранении товара в админке.
Сравнение вариантов решения задачи
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Плагин Table Rate Shipping | Готовое решение с гибкими настройками | Простота настройки, много правил | Платный, влияние на производительность |
| Кастомный код (предложенный) | Изменение стоимости через хук woocommerce_package_rates | Бесплатно, быстро, гибко | Требует базовых навыков программирования |
| Несколько методов доставки с весовыми ограничениями | Стандартный функционал WooCommerce | Без кода | Показывает пользователю несколько вариантов, возможно путаница |