Интернет-магазин без доставки — как кофе без кофеина: вроде есть, а толку мало. Если вы работаете с Yii2 и хотите автоматизировать расчёт стоимости и отправку заказов в службы доставки, эта статья для вас. Разберём, как правильно построить интеграцию, чтобы не утонуть в коде и не получить головную боль от менеджеров.
Зачем вообще интегрировать доставку с 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 СДЭК
Возьмём для примера СДЭК. У них есть тестовый контур, где можно отлаживать запросы. Для работы с 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 ограничивают количество вызовов в минуту. Ставьте задержки или используйте очередь.
Что в итоге?
Интеграция доставки в Yii2 — задача не rocket science, но требует аккуратности. Главное — не пишите всё в контроллере, используйте интерфейсы и очереди, обрабатывайте ошибки и логируйте. Начните с одного сервиса, отладьте процессы, а потом добавляйте остальные. И помните: клиент не должен ждать, пока вы там что-то рассчитываете — делайте это в фоне.
Если чувствуете, что не хватает времени или опыта, обратитесь к профессионалам. Digital-студия WNDER поможет настроить интеграцию быстро и без головной боли.

