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

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

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

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

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

Для начала нужно получить параметры заказа: общий вес и, если необходимо, габариты (длина, ширина, высота) всех товаров. Вес уже хранится в стандартном поле _weight продуктов WooCommerce, а для габаритов можно использовать поля _length, _width, _height.

function get_order_total_dimensions_and_weight( $package ) {
    $total_weight = 0;
    $total_volume = 0;
    foreach ( $package['contents'] as $item ) {
        $product = $item['data'];
        $qty = $item['quantity'];

        $weight = floatval( $product->get_weight() );
        $length = floatval( $product->get_length() );
        $width = floatval( $product->get_width() );
        $height = floatval( $product->get_height() );

        // Рассчитываем объем (в кубических единицах, например, см³)
        $volume = $length * $width * $height;

        $total_weight += $weight * $qty;
        $total_volume += $volume * $qty;
    }
    return array(
        'weight' => $total_weight,
        'volume' => $total_volume,
    );
}

Добавление пользовательского метода доставки с динамическим тарифом

Для гибкого изменения стоимости доставки рекомендуется создать собственный класс доставки, который будет рассчитывать тариф в зависимости от веса и объема заказа.

add_action( 'woocommerce_shipping_init', 'custom_weight_volume_shipping_method_init' );
function custom_weight_volume_shipping_method_init() {
    class WC_Shipping_Weight_Volume extends WC_Shipping_Method {

        public function __construct() {
            $this->id = 'weight_volume_shipping';
            $this->method_title = __('Вес и объем доставки', 'woocommerce');
            $this->method_description = __('Доставка с расчетом стоимости по весу и объему заказа.');
            $this->enabled = 'yes';
            $this->title = 'Доставка по весу и объему';

            $this->init();
        }

        function init() {
            $this->init_form_fields();
            $this->init_settings();

            add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
        }

        public function calculate_shipping( $package = array() ) {
            $params = get_order_total_dimensions_and_weight( $package );
            $weight = $params['weight'];
            $volume = $params['volume'];

            // Пример тарифной логики
            $base_cost = 100; // базовая ставка в рублях
            $cost_by_weight = $weight * 20; // 20 руб. за кг
            $cost_by_volume = ($volume / 1000) * 10; // 10 руб. за литр (1000 см³)

            $total_cost = $base_cost + $cost_by_weight + $cost_by_volume;

            $rate = array(
                'id' => $this->id,
                'label' => $this->title,
                'cost' => $total_cost,
                'calc_tax' => 'per_order'
            );

            $this->add_rate( $rate );
        }
    }
}

add_filter( 'woocommerce_shipping_methods', 'add_weight_volume_shipping_method' );
function add_weight_volume_shipping_method( $methods ) {
    $methods['weight_volume_shipping'] = 'WC_Shipping_Weight_Volume';
    return $methods;
}

Пошаговое руководство по внедрению

  1. Добавьте функцию get_order_total_dimensions_and_weight в файл functions.php вашей темы или в кастомный плагин.
  2. Создайте класс доставки WC_Shipping_Weight_Volume и зарегистрируйте его через хуки woocommerce_shipping_init и woocommerce_shipping_methods.
  3. В админке WooCommerce в разделе «Настройки» → «Доставка» добавьте новый способ доставки «Вес и объем доставки» и активируйте его для нужной зоны.
  4. Настройте базовые тарифы и коэффициенты в коде под свои требования.

Как проверить, что расчет стоимости работает корректно

  • Добавьте в корзину несколько товаров с разными параметрами веса и габаритов.
  • Перейдите к оформлению заказа, выберите адрес доставки, и убедитесь, что стоимость доставки меняется в зависимости от состава корзины.
  • Для отладки можно временно вывести значения веса и объема:
add_action('woocommerce_review_order_before_shipping', function() {
    $package = WC()->cart->get_shipping_packages()[0];
    $params = get_order_total_dimensions_and_weight( $package );
    echo '<pre>Вес: ' . $params['weight'] . ' кг\nОбъем: ' . $params['volume'] . ' см³</pre>';
});

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

  • Вес или габариты не заполнены в карточках товара. Решение: проверьте, что у каждого продукта заданы параметры веса и размеров в разделе «Данные о товаре» → «Доставка».
  • Класс доставки не отображается в админке. Проверьте правильность подключение класса и хуков. Класс должен быть объявлен до фильтра woocommerce_shipping_methods.
  • Стоимость всегда одна и та же. Убедитесь, что расчет стоимости происходит внутри метода calculate_shipping и что используются актуальные данные из корзины.

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

  • Не храните расчетные значения в сессии или базе — всегда получайте актуальные данные из корзины.
  • Оптимизируйте расчет объема — если в магазине много товаров, кешируйте результаты в Transient API на время сессии пользователя.
  • Используйте проверку типов и фильтрацию данных, чтобы исключить некорректные значения веса и размеров.
  • Для крупных магазинов рассмотрите вариант оптимизации расчетов на стороне сервера отдельно от фронтенда, чтобы снизить нагрузку.

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

МетодГибкостьСложность внедренияПроизводительностьКомпромиссы
Стандартные зоны и классы доставкиОграниченнаяНизкаяВысокаяНе учитывает сложные параметры (объем, вес одновременно)
Плагины для расчета доставки (например, Table Rate Shipping)ВысокаяСредняяСредняяПлатные, могут быть избыточны
Кастомный класс доставки на PHP (как в статье)МаксимальнаяСредняяВысокаяТребует знаний PHP, поддержка своими силами
Как создать автоматический генератор временных постов в WordPress
16.03.2026
WooCommerce: автоматическое изменение скидок на товары по атрибутам
04.07.2026
Как добавить автоматический хендлер для обработки форм в WordPress
08.04.2026
Как создать автоматизированные ответы на формы обратной связи в WordPress с помощью WPGPT
08.01.2026
Как удалить неиспользуемые медиа файлы в WordPress
10.12.2025