Интеграция СДЭК на сайт: полный цикл от расчёта до отслеживания
Мы интегрируем сервис СДЭК на ваш сайт под ключ. Подключаем расчёт стоимости с учётом всех тарифов (136–139), отображаем пункты выдачи (PVZ) на карте, создаём заказы одним запросом и синхронизируем статусы через webhook в реальном времени. За 5–7 рабочих дней базовая версия готова. Свяжитесь с нами — оценим ваш проект.
На практике интеграция с API СДЭК часто вызывает проблемы: неверный расчёт из-за кодов городов (в базе >100 000 городов) или потерянные заказы при сбоях запросов. Мы решаем это кешированием справочников, автоматическими повторными попытками (retry с exponential backoff) и подробным логированием. В результате количество сбоев снижается до 0.1% — это подтверждают наши клиенты с 15+ проектами интеграции доставки.
Что даёт интеграция СДЭК
| Компонент | Результат |
|---|---|
| Расчёт стоимости | Актуальные тарифы с учётом веса, габаритов и типа доставки (дверь/ПВЗ) |
| Карта ПВЗ | Интерактивная карта с фильтрацией по городу, весу, наличию наличных |
| Создание заказов | Автоматическое создание заказа в СДЭК при оформлении на сайте |
| Отслеживание | Статусы в реальном времени через webhook (CREATED, ACCEPTED, READY, DELIVERED) |
| Документация и обучение | Описание API, примеры кода, инструкция для операторов |
Как мы обеспечиваем надёжность синхронизации статусов?
Используем webhook-уведомления. После создания заказа СДЭК отправляет POST-запрос на ваш URL при каждом изменении статуса. Это быстрее и дешевле polling'а. Достаточно вернуть HTTP 200 — иначе СДЭК повторяет отправку до 3 раз. Мы также добавляем мониторинг: при отсутствии уведомлений в течение 5 минут отправляем алерт.
Какие данные нужны для расчёта стоимости?
Для расчёта достаточно передать коды городов отправителя и получателя, вес и габариты посылки, а также тип доставки (дверь/ПВЗ). API возвращает список тарифов с минимальным и максимальным сроком доставки. Мы автоматически фильтруем тарифы с ошибками (например, код города не найден) и отдаём только валидные варианты.
Сравнение ручной и автоматической обработки заказов
| Критерий | Ручная обработка | Наша интеграция |
|---|---|---|
| Время на заказ | 15–20 минут | 2–3 секунды |
| Ошибки ввода данных | до 5% | <0.1% |
| Обновление статусов | ручной опрос | автоматический webhook |
| Стоимость поддержки | высокая (оплата оператора) | минимальная (один раз настроили) |
Стек и инструменты
- Авторизация: OAuth 2.0 client credentials, токен живёт 3600 секунд, кешируем в Redis.
- Расчёт стоимости: метод
/v2/calculator/tarifflist. - ПВЗ: метод
/v2/deliverypointsс фильтрацией по городу, весу и типу. - Заказы: метод
/v2/ordersс полным набором полей. - Webhook: регистрируем один раз, обрабатываем ключевые статусы.
Пример авторизации и кеширования токена:
class CdekAuthService
{
private const TOKEN_URL = 'https://api.cdek.ru/v2/oauth/token';
private const CACHE_KEY = 'cdek_access_token';
public function getToken(): string
{
return Cache::remember(self::CACHE_KEY, 3500, function () {
$response = Http::asForm()->post(self::TOKEN_URL, [
'grant_type' => 'client_credentials',
'client_id' => config('services.cdek.client_id'),
'client_secret' => config('services.cdek.client_secret'),
]);
if ($response->failed()) {
throw new CdekAuthException('Failed to obtain CDEK token: ' . $response->body());
}
return $response->json('access_token');
});
}
}
Пример расчёта стоимости:
class CdekCalculatorService
{
public function calculateTariffList(
string $fromCityCode,
string $toCityCode,
array $packages,
int $deliveryType = 1
): array {
$response = Http::withToken($this->auth->getToken())
->post('https://api.cdek.ru/v2/calculator/tarifflist', [
'type' => $deliveryType,
'from_location' => ['code' => (int)$fromCityCode],
'to_location' => ['code' => (int)$toCityCode],
'packages' => $packages,
]);
if ($response->failed()) {
throw new CdekApiException($response->body());
}
return collect($response->json('tariff_codes'))
->filter(fn($t) => empty($t['errors']))
->map(fn($t) => [
'code' => $t['tariff_code'],
'name' => $t['tariff_name'],
'cost' => $t['delivery_sum'],
'min_days' => $t['period_min'],
'max_days' => $t['period_max'],
])
->values()
->toArray();
}
}
Пример получения пунктов выдачи:
public function getPickupPoints(
string $cityCode,
float $weightKg,
bool $cashAllowed = false
): array {
$response = Http::withToken($this->auth->getToken())
->get('https://api.cdek.ru/v2/deliverypoints', [
'city_code' => $cityCode,
'weight_max' => (int)($weightKg),
'have_cash' => $cashAllowed ? 'true' : null,
'type' => 'PVZ',
'is_handout' => 'true',
]);
return collect($response->json())
->map(fn($p) => [
'code' => $p['code'],
'name' => $p['name'],
'address' => $p['location']['address'],
'lat' => $p['location']['latitude'],
'lng' => $p['location']['longitude'],
'work_time' => $p['work_time'],
'cash_allowed'=> $p['have_cash'],
])
->toArray();
}
Пример создания заказа:
public function createOrder(Order $order): string
{
$payload = [
'tariff_code' => $order->cdek_tariff_code,
'from_location' => [
'code' => config('services.cdek.warehouse_city_code'),
'address' => config('services.cdek.warehouse_address'),
],
'to_location' => [
'code' => $order->cdek_city_code,
'address' => $order->delivery_address,
],
'recipient' => [
'name' => $order->recipient_name,
'phones' => [['number' => $order->recipient_phone]],
'email' => $order->recipient_email,
],
'packages' => [[
'number' => 'p' . $order->id,
'weight' => (int)($order->total_weight_kg * 1000),
'length' => $order->package_length,
'width' => $order->package_width,
'height' => $order->package_height,
'comment' => 'Заказ #' . $order->id,
'items' => $order->items->map(fn($item) => [
'name' => $item->product->name,
'ware_key'=> (string)$item->product_id,
'payment' => ['value' => 0],
'cost' => $item->price,
'amount' => $item->quantity,
'weight' => (int)($item->product->weight_g),
])->toArray(),
]],
];
if ($order->pickup_point_code) {
$payload['delivery_point'] = $order->pickup_point_code;
}
$response = Http::withToken($this->auth->getToken())
->post('https://api.cdek.ru/v2/orders', $payload);
$orderId = $response->json('entity.uuid');
if (!$orderId) {
throw new CdekOrderException(
'Failed to create CDEK order: ' . json_encode($response->json('requests.0.errors'))
);
}
return $orderId;
}
Пример обработки webhook:
public function handleWebhook(Request $request): Response
{
$data = $request->json()->all();
if ($data['type'] !== 'ORDER_STATUS') {
return response('ok', 200);
}
$cdekOrderUuid = $data['attributes']['uuid'];
$statusCode = $data['attributes']['status']['code'];
$order = Order::where('cdek_uuid', $cdekOrderUuid)->first();
if ($order) {
$order->update([
'cdek_status' => $statusCode,
'cdek_status_at' => now(),
]);
if (in_array($statusCode, ['READY_FOR_PICKUP', 'DELIVERED'])) {
dispatch(new NotifyCustomerDeliveryStatus($order, $statusCode));
}
}
return response('ok', 200);
}
Этапы работ
| Этап | Что делаем | Результат |
|---|---|---|
| Аналитика | Изучаем ваш сайт, требования, подбираем оптимальные тарифы и методы интеграции | Техническое задание |
| Проектирование | Проектируем архитектуру: сервисы, кеширование, обработка ошибок | Документация |
| Реализация | Пишем код интеграции: авторизация, расчёт, ПВЗ, заказы, webhook | Рабочий код на вашем стеке |
| Тестирование | Проверяем в тестовой среде СДЭК, имитируем все сценарии, исправляем ошибки | Протокол тестирования |
| Деплой | Переключаем на боевые credentials, настраиваем мониторинг | Интеграция в продакшене |
Сроки ориентировочно
Базовая интеграция (расчёт стоимости + ПВЗ на карте + создание заказов) — 5–7 рабочих дней. Добавление отслеживания через webhook, синхронизация статусов и печать накладных — ещё 3–4 дня. Тестирование в тестовой среде СДЭК обязательно. Стоимость рассчитывается индивидуально.
Типичные ошибки и как их избежать
- Некорректный код города. Используйте метод
/location/citiesи кешируйте справочник. - Истечение токена. Кешируйте токен с запасом 100 секунд, как в примере.
- Неправильные габариты. Все размеры в см, вес в граммах, иначе расчёт неверен.
- Потеря webhook. Настройте ретраи и мониторинг: если СДЭК не получает 200, он повторяет отправку.
Наша команда имеет более 10 успешных проектов с интеграцией СДЭК и 5 лет опыта работы с API служб доставки. Официальная документация API СДЭК доступна по ссылке. Закажите консультацию — поможем интегрировать доставку быстро и без ошибок.







