Система доставки WooCommerce является одной из наиболее гибких частей интернет-магазина. Она позволяет создавать зоны доставки, использовать различные методы расчета стоимости, интегрироваться со службами доставки и полностью изменять стандартную логику при помощи PHP API.

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

В этом руководстве рассмотрим основные возможности работы с доставкой WooCommerce и приведем множество практических примеров кода.

Как устроена система доставки WooCommerce

Механизм доставки состоит из нескольких компонентов:

  • зоны доставки (Shipping Zones);
  • методы доставки (Shipping Methods);
  • классы доставки (Shipping Classes);
  • пакеты доставки (Shipping Packages);
  • объекты доставки.

Каждый заказ проходит через систему расчета стоимости, после чего покупателю отображаются доступные варианты доставки.

Стандартные методы доставки

WooCommerce поддерживает несколько встроенных способов:

  • Фиксированная стоимость (Flat Rate).
  • Бесплатная доставка (Free Shipping).
  • Самовывоз (Local Pickup).

При необходимости можно добавить собственные методы доставки через API.

Получение объекта доставки

$shipping = WC()->shipping();

Объект предоставляет доступ к зарегистрированным способам доставки и их настройкам.

Получение всех методов доставки

$methods = WC()->shipping()->get_shipping_methods(); print_r($methods);

Получение пакетов доставки

$packages = WC()->shipping()->get_packages(); print_r($packages);

Каждый пакет содержит список товаров, стоимость и доступные способы доставки.

Проверка необходимости доставки

if ( WC()->cart->needs_shipping() ) { echo 'Требуется доставка'; }

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

$chosen = WC()->session->get('chosen_shipping_methods'); print_r($chosen);

Получение стоимости доставки

echo WC()->cart->get_shipping_total();

Получение общей суммы доставки с налогами

echo WC()->cart->get_shipping_total() + WC()->cart->get_shipping_tax();

Пересчет доставки

WC()->cart->calculate_shipping();

Используется после изменения корзины или адреса доставки.

Полный пересчет корзины

WC()->cart->calculate_totals();

Фильтр woocommerce_package_rates

Один из самых популярных фильтров доставки.

Позволяет изменить список доступных методов.

add_filter( 'woocommerce_package_rates', 'my_shipping_rates', 10, 2 ); function my_shipping_rates($rates, $package){ return $rates; }

Удаление способа доставки

Например, отключим самовывоз.

add_filter( 'woocommerce_package_rates', function($rates){ foreach($rates as $key => $rate){ if($rate->method_id == 'local_pickup'){ unset($rates[$key]); } } return $rates; },10,2);

Оставить только бесплатную доставку

add_filter( 'woocommerce_package_rates', function($rates){ foreach($rates as $key=>$rate){ if($rate->method_id!='free_shipping'){ unset($rates[$key]); } } return $rates; },10,2);

Изменение стоимости доставки

add_filter( 'woocommerce_package_rates', function($rates){ foreach($rates as $rate){ $rate->cost = 500; } return $rates; },10,2);

Бесплатная доставка от определенной суммы

add_filter( 'woocommerce_package_rates', function($rates){ if(WC()->cart->subtotal > 10000){ foreach($rates as $rate){ $rate->cost = 0; } } return $rates; },10,2);

Скрытие доставки для виртуальных товаров

add_filter( 'woocommerce_cart_needs_shipping', '__return_false' );

Проверка выбранной страны

$country = WC()->customer->get_shipping_country(); echo $country;

Получение города доставки

echo WC()->customer->get_shipping_city();

Получение индекса

echo WC()->customer->get_shipping_postcode();

Изменение стоимости по региону

add_filter( 'woocommerce_package_rates', function($rates){ if( WC()->customer->get_shipping_state()=='77' ){ foreach($rates as $rate){ $rate->cost=250; } } return $rates; },10,2);

Добавление собственной комиссии за доставку

add_action( 'woocommerce_cart_calculate_fees', function(){ if( WC()->cart->needs_shipping() ){ WC()->cart->add_fee( 'Упаковка', 100 ); } });

Получение класса доставки товара

global $product; echo $product->get_shipping_class();

Проверка класса доставки

if( $product->get_shipping_class()=='heavy' ){ echo 'Крупногабаритный товар'; }

Создание собственного метода доставки

class My_Shipping extends WC_Shipping_Method{ public function __construct(){ $this->id='my_shipping'; $this->method_title='Моя доставка'; } }

После этого класс регистрируется через фильтр woocommerce_shipping_methods.

Регистрация собственного метода

add_filter( 'woocommerce_shipping_methods', function($methods){ $methods['my_shipping']='My_Shipping'; return $methods; });

Изменение названия доставки

add_filter( 'woocommerce_package_rates', function($rates){ foreach($rates as $rate){ $rate->label='Экспресс-доставка'; } return $rates; },10,2);

Получение всех зон доставки

$zones = WC_Shipping_Zones::get_zones(); print_r($zones);

Получение зоны по ID

$zone = new WC_Shipping_Zone(1); print_r($zone->get_data());

Практические примеры

Бесплатная доставка только для Москвы

add_filter( 'woocommerce_package_rates', function($rates){ if( WC()->customer->get_shipping_city()=='Москва' ){ foreach($rates as $rate){ $rate->cost=0; } } return $rates; },10,2);

Увеличение стоимости доставки для тяжелых товаров

add_filter( 'woocommerce_package_rates', function($rates){ foreach($rates as $rate){ $rate->cost+=300; } return $rates; },10,2);

Скрытие доставки при отсутствии адреса

if( empty( WC()->customer->get_shipping_country() ) ){ return array(); }

Типичные ошибки

Изменения стоимости не применяются

После изменения тарифов необходимо вызвать пересчет корзины:

WC()->cart->calculate_totals();

Методы доставки дублируются

Проверьте, что фильтр woocommerce_package_rates не подключен несколько раз.

Стоимость рассчитывается неверно

Убедитесь, что зоны доставки настроены корректно и товары имеют правильные классы доставки.

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

WooCommerce предоставляет мощный API для управления доставкой и позволяет реализовать практически любую бизнес-логику без изменения файлов ядра. С помощью классов WC_Shipping, WC_Shipping_Method, фильтров woocommerce_package_rates и других инструментов можно изменять стоимость доставки, создавать собственные методы, автоматически выбирать подходящие тарифы, ограничивать доступные способы доставки и интегрироваться с внешними службами. Использование официального API делает код совместимым с будущими обновлениями WooCommerce и значительно упрощает поддержку интернет-магазина.

Метки: ,