Интернет-магазин без доставки — как кофе без кофеина: вроде есть, а толку мало. Если вы работаете с Yii2 и хотите автоматизировать расчёт стоимости и отправку заказов в службы доставки, эта статья для вас. Разберём, как правильно построить интеграцию, чтобы не утонуть в коде и не получить головную боль от менеджеров.

Digital-студия WNDER

Зачем вообще интегрировать доставку с Yii2?

Представьте: клиент оформляет заказ, а менеджер вручную копирует адрес в личный кабинет СДЭК или Почты России. Медленно, ошибки, забытые заказы. Интеграция через API решает три задачи: автоматический расчёт стоимости, создание заявки на доставку и отслеживание статуса. Yii2 — отличный фреймворк для таких задач: у него есть компоненты, поведение (behaviors) и удобная работа с HTTP-клиентами.

Кстати, если вы только начинаете, не пытайтесь сразу подключить десять служб. Начните с одной, например, СДЭК или Boxberry. У них понятная документация и тестовые среды.

Архитектура: как не превратить код в кашу

Главная ошибка — писать вызовы API прямо в контроллере. Через месяц вы забудете, что там происходит, а тестировать это будет невозможно. В Yii2 принято выделять логику в отдельные компоненты или сервисы. Создайте папку services/delivery и для каждой службы — свой класс, реализующий общий интерфейс.

Вот пример интерфейса:


interface DeliveryServiceInterface
{
    public function calculateCost(array $orderData): float;
    public function createOrder(array $orderData): string;
    public function trackOrder(string $trackNumber): array;
}

Теперь любой сервис доставки должен реализовать эти три метода. В конфиге Yii2 можно зарегистрировать компонент, который будет выбирать нужный класс в зависимости от настроек.


// config/web.php
return [
    'components' => [
        'delivery' => [
            'class' => app\services\delivery\DeliveryManager::class,
            'defaultService' => 'cdek',
        ],
    ],
];

Внутри DeliveryManager вы можете использовать фабрику или DI-контейнер, чтобы подставлять нужный сервис. Это упрощает тестирование и замену службы доставки.

Правило: Никогда не вызывайте API доставки синхронно в момент оформления заказа. Если сервис недоступен, клиент не сможет завершить покупку. Используйте очереди (например, yii2-queue) для фоновой отправки заявок.

Практический пример: расчёт стоимости через API СДЭК

Возьмём для примера СДЭК. У них есть тестовый контур, где можно отлаживать запросы. Для работы с HTTP в Yii2 удобно использовать yii\httpclient\Client. Вот как может выглядеть метод расчёта стоимости:


public function calculateCost(array $orderData): float
{
    $client = new \yii\httpclient\Client();
    $response = $client->createRequest()
        ->setMethod('POST')
        ->setUrl('https://api.edu.cdek.ru/v2/calculator/tariff')
        ->setData([
            'type' => 1,
            'date' => date('Y-m-d'),
            'currency' => 1,
            'tariff_code' => 136,
            'from_location' => ['postal_code' => '194021'],
            'to_location' => ['postal_code' => $orderData['postal_code']],
            'packages' => [
                ['weight' => $orderData['weight'], 'length' => 10, 'width' => 10, 'height' => 10]
            ],
        ])
        ->send();

    if ($response->isOk) {
        $data = $response->getData();
        return $data['total_sum'];
    }

    throw new \Exception('Ошибка расчёта стоимости доставки');
}

Обратите внимание: для тестового контура URL будет другим. Всегда проверяйте документацию. И не забудьте про авторизацию — обычно нужен токен, который получают отдельным запросом.

Создание заявки и отслеживание: не забываем про статусы

Создание заказа в службе доставки — процесс похожий: отправляем POST-запрос с данными о получателе и посылке. В ответ получаем трек-номер. Его нужно сохранить в базе и показать клиенту. Для отслеживания статусов можно настроить cron-задачу, которая раз в час опрашивает API и обновляет статусы в вашей БД.

Вот пример метода создания заказа:


public function createOrder(array $orderData): string
{
    $client = new \yii\httpclient\Client();
    $response = $client->createRequest()
        ->setMethod('POST')
        ->setUrl('https://api.edu.cdek.ru/v2/orders')
        ->setHeaders(['Authorization' => 'Bearer ' . $this->token])
        ->setData([
            'number' => $orderData['order_id'],
            'recipient' => [
                'name' => $orderData['name'],
                'phone' => $orderData['phone'],
            ],
            'from_location' => ['postal_code' => '194021'],
            'to_location' => ['postal_code' => $orderData['postal_code']],
            'packages' => [
                ['number' => $orderData['order_id'], 'weight' => $orderData['weight']]
            ],
        ])
        ->send();

    if ($response->isOk) {
        $data = $response->getData();
        return $data['entity']['uuid'];
    }

    throw new \Exception('Не удалось создать заказ: ' . $response->getContent());
}

Для отслеживания статусов можно использовать отдельный метод trackOrder. Не забудьте добавить обработку ошибок: API может вернуть 400, 401 или 500. Логируйте все запросы и ответы — это сэкономит часы отладки.

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

Выбор службы зависит от вашего региона и бюджета. Вот краткая таблица, которая поможет определиться:

Сервис API Тестовый контур Сложность интеграции
СДЭК REST Да Средняя
Boxberry REST Да Низкая
Почта России SOAP Да Высокая
DHL REST Нет Средняя

Как видите, для старта проще всего Boxberry или СДЭК. Почта России использует устаревший SOAP, что добавляет мороки с WSDL.

Советы из опыта: как сэкономить нервы

  • Кэшируйте результаты расчёта доставки. Если клиент несколько раз меняет адрес, не дёргайте API каждый раз. Используйте yii2-cache с TTL в 10-15 минут.
  • Логируйте всё. Создайте отдельный лог-файл для запросов к API доставки. При ошибке вы сможете быстро найти причину.
  • Используйте mock-сервер для тестов. Если у сервиса нет тестового контура, напишите простой мок на PHP, который возвращает заданные ответы.
  • Не забывайте про лимиты запросов. Некоторые API ограничивают количество вызовов в минуту. Ставьте задержки или используйте очередь.
Лайфхак: Создайте консольную команду для массового обновления статусов заказов. Запускайте её по cron каждые 30 минут. Так вы не будете нагружать API при каждом открытии страницы заказа.

Что в итоге?

Интеграция доставки в Yii2 — задача не rocket science, но требует аккуратности. Главное — не пишите всё в контроллере, используйте интерфейсы и очереди, обрабатывайте ошибки и логируйте. Начните с одного сервиса, отладьте процессы, а потом добавляйте остальные. И помните: клиент не должен ждать, пока вы там что-то рассчитываете — делайте это в фоне.

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

Студия WNDER