Проблема: необходимость добавить уникальный тип доставки в WooCommerce
Стандартные методы доставки WooCommerce не всегда покрывают все бизнес-сценарии. Часто требуется добавить собственный тип доставки с особыми условиями, например, доставка по определённым регионам, с разным тарифом по весу или времени суток.
Диагностика задачи
Перед началом важно убедиться, что ваш магазин использует стандартные методы доставки WooCommerce, и что вы понимаете, как устроена система доставки в WooCommerce:
- Классы и зоны доставки — базовые элементы для настройки;
- Методы доставки — подключаемые классы с разным функционалом;
- Возможность добавления собственных методов через наследование
WC_Shipping_Method.
Если у вас уже есть зоны доставки, но ни один из стандартных методов не подходит — пора создавать свой.
Пошаговое решение: добавляем собственный метод доставки
1. Создаём класс метода доставки
Добавьте следующий код в файл functions.php вашей дочерней темы или в собственный плагин:
if ( ! class_exists( 'WC_Custom_Shipping_Method' ) ) {
class WC_Custom_Shipping_Method extends WC_Shipping_Method {
public function __construct() {
$this->id = 'custom_shipping';
$this->method_title = __( 'Custom Shipping', 'woocommerce' );
$this->method_description = __( 'Custom shipping method with conditional rules', 'woocommerce' );
$this->enabled = 'yes';
$this->title = 'Custom Shipping';
$this->init();
}
function init() {
// Load the settings API
$this->init_form_fields();
$this->init_settings();
// Save settings
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function calculate_shipping( $package = array() ) {
$cost = 0;
// Пример условия: бесплатная доставка для заказов от 5000 руб
$order_total = WC()->cart->get_cart_contents_total();
if ( $order_total >= 5000 ) {
$cost = 0;
} else {
$cost = 300; // базовая стоимость
// Дополнительно можно учитывать вес
$weight = 0;
foreach ( $package['contents'] as $item_id => $values ) {
$weight += $values['data']->get_weight() * $values['quantity'];
}
if ( $weight > 10 ) {
$cost += 200; // доплата за вес
}
}
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost,
'calc_tax' => 'per_order'
);
$this->add_rate( $rate );
}
}
}2. Регистрируем метод доставки в WooCommerce
Добавьте этот код, чтобы WooCommerce увидел ваш метод:
function add_custom_shipping_method( $methods ) {
$methods['custom_shipping'] = 'WC_Custom_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_custom_shipping_method' );3. Добавляем метод доставки к нужной зоне
Зайдите в админку WooCommerce: WooCommerce > Настройки > Доставка > Зоны доставки, выберите нужную зону и добавьте новый метод доставки «Custom Shipping».
Проверка результата
- Добавьте товары в корзину с разной суммой и весом;
- Перейдите на страницу оформления заказа;
- Проверьте, что стоимость доставки меняется в зависимости от суммы заказа и веса, согласно логике из
calculate_shipping; - Если стоимость не отображается — убедитесь, что метод доставки активирован в нужной зоне и что корзина соответствует условиям.
Частые ошибки и как исправить
- Метод не отображается в зоне доставки: проверьте, что вы добавили метод к правильной зоне и что зона покрывает адрес доставки.
- Стоимость доставки всегда 0: возможно, условие
if ($order_total >= 5000)срабатывает всегда, проверьте переменную$order_totalи типы данных. - Ошибка PHP или белый экран: проверьте синтаксис, особенно в классах и хуках, используйте
WP_DEBUGдля диагностики. - Вес товаров не учитывается: убедитесь, что веса установлены в карточках товаров и возвращаются корректно через
get_weight().
Практические советы по оптимизации и безопасности
- Для крупных магазинов вычисления стоимости доставки лучше кэшировать, чтобы уменьшить нагрузку;
- Для более сложных условий (например, по регионам или времени суток) можно расширить класс, добавив настройки в панель администратора;
- Избегайте использования глобальных переменных и всегда проверяйте входные данные;
- Регулярно проверяйте обновления WooCommerce, чтобы адаптировать свой код под новые версии;
- Используйте дочерние темы или собственные плагины для сохранения изменений при обновлении.
Сравнение вариантов реализации собственного метода доставки
| Вариант | Плюсы | Минусы | Пример использования |
|---|---|---|---|
| Плагин готового метода | Быстрая установка, поддержка | Может не подходить под бизнес-логику | WooCommerce Table Rate Shipping |
| Собственный класс метода доставки | Полный контроль, гибкость | Требует навыков программирования | Код из статьи |
| Использование фильтров для изменения стоимости | Простота, подходит для мелких изменений | Ограниченная гибкость | Фильтр woocommerce_package_rates |