← к кейсам

Модуль доставки СДЭК для OpenCart

2020
PHP OpenCart API СДЭК v2

Контекст

СДЭК в 2020 году запустил API v2.0, который кардинально отличался от v1 по структуре запросов и авторизации. Большинство существующих модулей для OpenCart работали со старым API и не поддерживали актуальные возможности: тарифы с дверной доставкой, автоматическое создание накладных, трекинг через вебхуки.

Написал модуль с нуля под новое API.

Что реализовал

Авторизация OAuth 2.0

СДЭК v2 использует OAuth 2.0 с client credentials. Написал обёртку, которая получает токен, кэширует его (токен живёт 24 часа) и автоматически обновляет при истечении. Все запросы к API идут через неё.

Расчёт тарифов на оформлении заказа

На странице оформления заказа покупатель видит список способов доставки СДЭК с актуальными ценами и сроками. Модуль обращается к /v2/calculator/tarifflist, передаёт параметры посылки (вес, габариты) и адрес получателя, получает список доступных тарифов.

Запрос к СДЭК кэшируется на 15 минут по ключу (адрес + параметры товаров) — чтобы не дёргать API при каждом обновлении страницы.

Создание заказа и накладная

После оплаты заказа модуль автоматически создаёт отправление в СДЭК через /v2/orders. Возвращённый uuid сохраняется в базу OpenCart вместе с номером заказа.

Через 5–10 минут (когда СДЭК завершает обработку) модуль получает штрихкод накладной и сохраняет ссылку. Менеджер из админки OpenCart одним кликом открывает PDF для печати.

Трекинг через вебхуки

СДЭК умеет присылать статусы посылки на вебхук. Реализовал эндпоинт, который принимает статусы, обновляет статус заказа в OpenCart и при изменении на «Доставлено» отправляет email покупателю.

Для магазинов без фиксированного IP — альтернативный режим: polling каждые 2 часа через cron.

Что оказалось нетривиальным

API СДЭК v2 на этапе запуска был нестабилен: эндпоинт расчёта тарифов иногда возвращал 500 без объяснений. Добавил retry с логированием — если два запроса подряд падают, модуль отдаёт старый кэшированный результат и показывает покупателю предупреждение.

Документация по расчёту для пунктов выдачи vs дверная доставка отличалась от фактического поведения API — пришлось разбираться эмпирически.

Итог

Модуль выложил на GitHub как SDK: TimurTurdyev/sdk2.0. Его использовали несколько магазинов на разных движках, а не только OpenCart — потому что ядро (HTTP-клиент + авторизация + методы API) не зависит от фреймворка.