Главная/WordPress Fullstack/Блупринты/WooCommerce/Разработка кастомного метода доставки (Custom Shipping Method) с интеграцией карты и пунктов выдачи (ПВЗ)
К карточкам раздела «WooCommerce»
WooCommerce(ТЗ 40 из 54)
ТЗ: Разработка кастомного метода доставки (Custom Shipping Method) с интеграцией карты и пунктов выдачи (ПВЗ)
WooCommerce5 шагов • +25 XP

ТЗ: Разработка кастомного метода доставки (Custom Shipping Method) с интеграцией карты и пунктов выдачи (ПВЗ)

Создание расширения доставки на базе класса WC_Shipping_Method: динамический расчет стоимости по габаритам и весу, интеграция с API службы доставки, интерактивная карта выбора ПВЗ и надежная запись адреса самовывоза в заказ.

~14 ч работыУровень: MiddleWC_Shipping_MethodWC_Shipping_RateLeaflet / OpenStreetMapCheckout Modal APIHPOS Shipping MetaREST API Courier Integration
+5 XP за шаг
Выполнено 0 из 5 шагов (0%)
Трудозатраты~14 рабочих часов
Фриланс вилка~$630 – $1,050 (€560 – €980)
Оценка веб-студии~$1,330 – $2,240 (€1260 – €2100)

ТЗ заказчика (исходный бриф):

«Нам нужен собственный способ доставки "Доставка в пункт выдачи (ПВЗ)". Стоимость должна считаться динамически: базовый тариф + вес корзины. На чекауте покупатель должен нажать "Выбрать на карте", открывается попап с картой, где точками отмечены ПВЗ. При клике на точку адрес ПВЗ и его ID подставляются в чекаут и обязательно сохраняются в заказ!»
Ключевые требования:
  • •Создание кастомного метода доставки унаследованного от базового класса WC_Shipping_Method
  • •Динамический расчет стоимости доставки: фиксированная ставка + надбавка за каждый килограмм веса корзины
  • •Интерактивный виджет выбора ПВЗ на карте (Leaflet) с поиском и фильтром по станциям метро / адресам
  • •Запись идентификатора выбранного ПВЗ и его точного адреса в сессию и метаданные доставки заказа
  • •Валидация: запрет завершения оформления заказа, если выбран данный способ доставки, но ПВЗ не указан
Ограничения проекта:
  • •Бесплатный картографический движок (Leaflet + OpenStreetMap) без жесткой привязки к платным ключам API
  • •Полная совместимость с HPOS и нативным чекаутом WooCommerce
  • •Отображение выбранного пункта выдачи в накладных и личном кабинете покупателя
Критерии приёмки (KPI):
  • Время открытия карты ПВЗ < 200 мс
  • 100% фиксация кода ПВЗ в метаданных доставки заказа для автоматической передачи в курьерскую службу
  • Точный расчет стоимости с учетом веса всех вложенных товаров

Конфигурация блупринта под условия проекта

Выберите архитектуру и стек — шаги роадмапа, структура файлов и примеры кода переключатся автоматически:

Пошаговое практическое руководство по ТЗ

Подробный разбор архитектуры, код реализации и советы эксперта по каждому этапу:

1
Этап 1 из 5

Создание класса доставки WC_Shipping_Method

~50 минСредний

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

Создайте класс WC_Shipping_Pvz, унаследованный от WC_Shipping_Method. Настройте форму параметров в админке (базовая стоимость, цена за 1 кг, включение/выключение). Зарегистрируйте метод через хук woocommerce_shipping_methods.

План и контрольные точки реализации:
1Унаследовать класс от WC_Shipping_Method
2Определить поля init_form_fields() для настройки тарифов
3Реализовать метод calculate_shipping с динамическим расчетом стоимости
Важные технические нюансы и подводные камни:

Метод calculate_shipping($package) должен корректно суммировать вес товаров в корзине.

Совет эксперта (Best Practice):

Округление веса в большую сторону: Большинство курьерских служб тарифицируют вес с округлением вверх до целого килограмма (ceil($total_weight)). Учитывайте это при калькуляции. (Важно: Если у товара не указан вес в админке, $product->get_weight() вернет пустую строку — обязательно приводите к (float).)

Ожидаемый артефакт этапа:

Полноценный метод доставки в зонах доставки WooCommerce.

PHP
<?php
declare(strict_types=1);

if (!defined('ABSPATH')) exit;

class WC_Shipping_Pvz extends \WC_Shipping_Method {
    public function __construct(int $instance_id = 0) {
        $this->id                 = 'pvz_shipping';
        $this->instance_id        = $instance_id;
        $this->method_title       = __('Доставка в ПВЗ (Самовывоз)', 'agenticlab');
        $this->method_description = __('Доставка до пункта выдачи с динамическим расчетом по весу и картой.', 'agenticlab');
        $this->supports           = ['shipping-zones', 'instance-settings'];

        $this->init();
    }

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

        $this->title = $this->get_option('title', 'Самовывоз из ПВЗ');
        $this->enabled = $this->get_option('enabled', 'yes');

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

    public function init_form_fields(): void {
        $this->form_fields = [
            'enabled' => [
                'title'   => __('Включить', 'agenticlab'),
                'type'    => 'checkbox',
                'default' => 'yes',
            ],
            'title' => [
                'title'   => __('Название на чекауте', 'agenticlab'),
                'type'    => 'text',
                'default' => __('Пункт выдачи заказов (ПВЗ)', 'agenticlab'),
            ],
            'base_cost' => [
                'title'   => __('Базовая стоимость ($)', 'agenticlab'),
                'type'    => 'price',
                'default' => '250',
            ],
            'cost_per_kg' => [
                'title'   => __('Доплата за каждый 1 кг ($)', 'agenticlab'),
                'type'    => 'price',
                'default' => '50',
            ],
        ];
    }

    public function calculate_shipping($package = []): void {
        $base_cost = (float) $this->get_option('base_cost', 250);
        $cost_per_kg = (float) $this->get_option('cost_per_kg', 50);

        $total_weight = 0.0;
        foreach ($package['contents'] as $item) {
            /** @var \WC_Product $product */
            $product = $item['data'];
            $weight = (float) $product->get_weight();
            $total_weight += ($weight * (int) $item['quantity']);
        }

        $final_cost = $base_cost + ($total_weight * $cost_per_kg);

        $this->add_rate([
            'id'        => $this->get_rate_id(),
            'label'     => $this->title,
            'cost'      => $final_cost,
            'package'   => $package,
        ]);
    }
}

add_filter('woocommerce_shipping_methods', function ($methods) {
    $methods['pvz_shipping'] = 'WC_Shipping_Pvz';
    return $methods;
});
2
Этап 2 из 5

Интерфейс выбора ПВЗ и модальное окно с картой Leaflet

~60 минСложный
3
Этап 3 из 5

Серверная валидация выбора ПВЗ при оформлении заказа

~35 минСредний
4
Этап 4 из 5

Запись данных ПВЗ в строку доставки заказа (HPOS Item Shipping Meta)

~40 минСредний
5
Этап 5 из 5

Проверка полного цикла и тестирование изменения веса

~30 минЛегкий

Типичные грабли на этом ТЗ

2 антипаттерна

Инструменты экосистемы Fullstack AI Lab для этого ТЗ

Интеграция