Заказ собран и оплачен — дальше его надо отправить. Можно руками: сотрудник открывает личный кабинет перевозчика, переносит туда адрес и позиции, печатает этикетку, вечером сверяет, что уехало. На десятке заказов это работает. Дальше начинается то, ради чего пишут интеграции: перенос данных из одной системы в другую перестаёт быть работой человека.
Здесь — разбор рабочей связки с Яндекс.Доставкой на боевом проекте: заказы уходят из нашей системы по API, статусы возвращаются обратно, а человек подключается только там, где нужно решение, а не перепечатка.

Шесть шагов. Четвёртый — единственный, где что-то физически происходит с товаром, и именно вокруг него больше всего правил.
Почему свой канал продаж вообще заводят и когда он окупается — в разборе про комиссии маркетплейсов.
Что делает система вместо человека
Порядок такой:
- Расчёт — сколько будет стоить и когда приедет.
- Заявка — подтверждаем выбранный вариант, получаем номер отправления.
- Этикетка — штрихкод, который клеится на коробку.
- Забор — курьер приезжает на склад и увозит партию.
- Движение — статусы приходят к нам, заказ идёт по своему пути.
- Вручение или возврат — и здесь всё самое интересное.
Разберём по шагам, что вызывается и на что смотреть.
Расчёт и заявка: два вызова вместо одного
Отправление создаётся не одним запросом, а двумя, и это правильно устроено. Сначала предложения: мы отдаём состав заказа, адрес получателя и склад отправления, а в ответ получаем варианты — цену, интервал забора и интервал доставки, каждый со своим сроком годности. Потом подтверждение выбранного варианта — и только на этом шаге появляется отправление с номером.
Разделение полезное: между расчётом и подтверждением можно показать менеджеру цену и дать выбрать. Но у него есть цена — предложение живёт ограниченное время, и подтверждать надо сразу, а не через час.
Куда везём — тоже решается здесь, и вариантов два: курьером до двери (адрес строкой) или в пункт выдачи (идентификатор точки). Это не только разные поля назначения, но и разная политика последней мили: в первом случае интервал, во втором самовывоз. Перепутать нельзя — приедет не туда, куда ждёт клиент.
⚠️ И главное правило, оплаченное чужой ошибкой: номер отправления сохраняется в заказ сразу после ответа, до любых следующих действий. Если сохранить «в конце, когда всё получилось», то упавший следующий шаг оставит отправление без владельца, а повторная попытка создаст второе на тот же заказ. Первое так и будет висеть ничьим, и найдётся оно в лучшем случае при сверке, в худшем — приездом двух курьеров.
Вес и габариты: их у заказа нет
Неочевидное место, на котором интеграция буксует первой. Перевозчику нужны вес и размеры, а в заказе их нет — там артикулы и количество. Значит, их надо откуда-то взять.
Мы тянем их из карточек товара на витрине по артикулу: вес в граммах, длина, ширина, высота. Дальше собираем из позиций одно грузовое место: вес — сумма, высота — сумма (коробки ставятся друг на друга), ширина и длина — максимум из позиций.
⚠️ У каждого значения есть запасное на случай, если карточка не заполнена. Это не лень, а осознанный выбор: заказ должен уехать даже с неточными габаритами — расхождение перевозчик поправит на складе сам, а вот отказ создать отправление останавливает отгрузку целиком. Но запасное значение — это тихая ошибка, поэтому пустые веса в карточках стоит вычищать отдельно, а не жить на них.
Этикетка: «ещё не готова» — это не ошибка
Этикетку перевозчик генерирует не мгновенно. Запрос сразу после создания отправления честно отвечает, что она ещё не готова, — и это нормальный ответ, а не сбой.
Поэтому этикетка забирается отдельным фоновым процессом: раз в несколько минут он проходит по отправлениям без этикетки, спрашивает, готова ли, и когда получает файл — прикладывает его к заданию на складе. Логика простая, но именно она превращает «сотрудник не забыл распечатать» в «этикетка на складе появилась сама».
⚠️ Если склад у вас чужой (фулфилмент), этикетка должна доехать до него приложением к заданию на отгрузку, а не письмом кладовщику. Как это устроено со стороны склада — в разборе про фулфилмент для интернет-магазина.
Заказ курьера на склад
Отдельная механика, про которую в начале обычно не думают: отправления созданы, но за ними ещё должен приехать курьер. Это отдельный запрос — заказ забора на дату и интервал, с объёмом, весом и числом грузчиков.
Три правила, которые выясняются на практике:
- Дата и интервал не произвольные. Их нужно сначала спросить у перевозчика отдельным методом и выбрать пару из списка. Придуманная пара — отказ с формулировкой «не могу найти такой вариант забора».
- Есть минимальный объём. Меньше четверти кубометра забор не заказывается, даже если реально уезжает одна коробка.
- Вызов курьера — это деньги. Он списывается с баланса, поэтому в портале право на него есть только у администратора, а не у любого сотрудника. Кнопка, которая тратит деньги, не должна стоять рядом с кнопкой, которая печатает этикетку.
⚠️ И грабля, стоившая дня разбирательств: у метода со списком запланированных заборов адрес пишется через косую черту, а не через дефис. Ошибёшься в написании — перевозчик отвечает не «нет такого метода», а «доступ запрещён». Мы полтора дня были уверены, что нам просто не выдали права, и писали в поддержку. Правило на будущее: «доступ запрещён» на новом методе — сначала проверьте адрес запроса, а потом уже права.
Статусы: где статусная модель обманывает
Самая большая часть работы — не отправить заказ, а правильно показать, где он. Статусы приходят строками вида «сортировочный центр, загружено» или «доставка, прибыл в пункт выдачи», и соблазн простой: сопоставить каждую строку своему статусу таблицей. Так делать не стоит — модель перевозчика меняется и дополняется, и таблица однажды молча перестанет узнавать новые значения.
Мы разбираем статусы по ключевым словам и фазам. Фаза сортировочного центра означает одно, фаза доставки — другое, слова «возврат» и «отменено» перебивают всё остальное. Новые статусы, которых мы ещё не видели, попадают в свою фазу сами.
Три места, где буквальное прочтение врёт:
- «Загружено» в сортировочном центре — это не движение. Событие прилетает в момент подтверждения заявки, когда коробка ещё стоит у нас на складе. На боевом заказе это выглядело так: «загружено» в 8:56, курьер приехал между 15 и 18. Если считать это отправкой, клиент увидит «в пути» за полдня до того, как посылку вообще заберут.
- «Прибыл» бывает разный. Строка про прибытие в пункт выдачи содержит и слово «прибыл», и слово «пункт». Проверять её надо до общего правила про прибытие, иначе «ждёт вас в пункте выдачи» схлопнется в обычное «в пути» — и клиент не узнает, что за посылкой пора идти.
- Технические события — не про движение. «Интервал доставки изменён» приходит и тогда, когда заказ ещё в сортировочном центре. Такие события статус не трогают вовсе: сдвинуть заказ вперёд легко, вернуть назад — уже нет.
⚠️ Принцип, к которому мы пришли: портал обязан показывать то же, что личный кабинет перевозчика. Не «логичнее», не «раньше» — то же самое. Первое же расхождение между двумя экранами заканчивается тем, что сотрудник перестаёт верить порталу и идёт проверять в кабинет, а интеграция теряет смысл.
Отдельно про пункты выдачи: вместе со статусом мы забираем и срок хранения — до какого числа посылка ждёт клиента. Он живёт в заказе рядом со статусом, потому что это единственная дата, после которой заказ поедет назад сам собой.
Возврат: статус, который ставит человек
Любой возвратный статус перевозчика переводит заказ в «Возвращается». А вот терминальный «Возврат» автоматика не ставит — никогда.
Причина не техническая. Посылка поехала назад — дальше решает человек: принять её на склад, вернуть коды маркировки в оборот и пробить чек возврата, либо не принимать вовсе и отправить клиенту замену за свой счёт. Это разные деньги и разные документы, и автоматика такое решение принять не может. Хуже того, если она поставит «Возврат» сама, то перебьёт решение менеджера, который уже выбрал замену.
Поэтому в момент перехода в «Возвращается» портал один раз зовёт людей: уведомление сотрудникам с номером заказа, причиной и прямым текстом — что нужно решить и что автоматика дальше сама ничего не переведёт. Один раз, а не при каждом статусе возвратной цепочки: посылка едет назад несколько дней, и ежедневное «возврат!» перестают читать на второй день.
Общее правило, которое из этого выросло и работает не только с доставкой: у каждого статуса один хозяин. Промежуточные ведёт автоматика по данным перевозчика, терминальные ставит человек. Смешение ролей выглядит как «система живёт своей жизнью».
Акт приёма-передачи
Мелочь, которая экономит время каждый день: акт на партию отправлений забирается из портала одной кнопкой, тремя способами — всё ещё не отгруженное, за период или по конкретным номерам заказов. Файлом приезжает PDF, а если акт нужно править руками — редактируемый документ.
Смысл не в самом файле, а в том, что за ним не надо идти в чужой кабинет и вспоминать, какие заказы вошли в сегодняшнюю партию: система и так знает, что она отправила.
Что выяснить до начала работ
- Куда возите — до двери, в пункты выдачи или и то и другое: это разные поля и разные правила последней мили.
- Откуда возьмёте вес и габариты. Их нет в заказе, и это выясняется на первом же отправлении.
- Когда готова этикетка и кто её забирает — человек или фоновый процесс.
- Как заказывается забор: свободные даты, минимальный объём, кто имеет право нажимать кнопку, которая тратит деньги.
- Как устроена статусная модель — и какие статусы означают не то, что написано.
- Кто ставит терминальный статус возврата и что происходит с товаром, маркировкой и чеком после него.
- Что произойдёт при повторной попытке: создастся второе отправление или вернётся то же самое.
Принцип, общий для всех интеграций: ломается не сложная логика, а стыки, где две системы по-разному понимают простое слово. В доставке таких слов два — «отправлено» и «возврат», и оба стоят денег.
Как устроена оплата до этого шага — в разборе про приём платежей и ссылки на оплату, а что происходит с маркированным товаром при отгрузке — в статье про Честный Знак.
Если вы возите Яндекс.Доставкой
Всё описанное — не разовая история под один магазин. Расчёт и заявки, этикетки, заказ курьера на склад, разбор статусной модели, возвраты с правилом «терминальный статус ставит человек» и акты приёма-передачи уже пройдены на боевом проекте, и эти наработки применимы у любого клиента Яндекс.Доставки: перевозчик тот же, методы те же, грабли те же. Проходить их заново не нужно.
Что обычно входит в такую работу:
- разбор вашей схемы: откуда уезжают заказы, свой склад или фулфилмент, куда возите;
- отправления из вашей системы: расчёт, заявка, этикетки, заказ забора;
- статусы обратно — в понятных человеку словах и без расхождений с кабинетом перевозчика;
- возвраты: сигнал человеку, решение по товару, маркировка и документы;
- то, о чём вспоминают последним: куда придёт сообщение, когда обмен сломается.
Хотите такую же связку у себя — расскажите о задаче.
Коротко: частые вопросы
- Как отправлять заказы Яндекс.Доставкой из своей системы?
- Двумя вызовами: сначала расчёт вариантов с ценой и интервалами, потом подтверждение выбранного — так появляется отправление с номером. Дальше система забирает этикетку и следит за статусами.
- Откуда берутся вес и габариты для расчёта?
- В заказе их нет — только артикулы и количество. Мы подтягиваем вес и размеры из карточек товара на витрине и собираем из позиций одно грузовое место.
- Кто ставит статус «Возврат»?
- Человек. Автоматика переводит заказ в «Возвращается» по данным перевозчика, а терминальный статус ставит менеджер: принять посылку на склад или отправить замену — это разные деньги и разные документы.