Заказ с сайта проходит через пять систем: витрину, платёжный сервис, учётную систему, склад и службу доставки. Ломается он не внутри них — каждая по отдельности работает годами, — а на четырёх стыках между ними. Заказ уходит в учёт дважды, потому что связь оборвалась на середине ответа. Не уходит вовсе, потому что учётная система была на обслуживании и никто не переслал запрос повторно. Приходит на позицию, которой нет в продаже, потому что товар переименовали, а сопоставление шло по названию. Висит неоплаченным при успешном платеже, потому что уведомление от платёжного сервиса не дошло.
Общее у всех четырёх случаев одно: они не выглядят как поломка. Сайт открывается, заказы принимаются, обмен в журнале успешен. Покупатель видит «заказ принят» и ждёт. Через два дня он звонит спросить, где заказ, и оказывается, что в учёте его нет вообще.
Дальше — маршрут заказа по шагам с указанием, кто на каждом владеет статусом; очередь повторов и что происходит, пока учёт недоступен; защита от повторной обработки по внешнему номеру; сопоставление номенклатуры по артикулу; отдельно оплаты и их подтверждения; и суточная сверка «создано — доехало», которая делает потерю заметной в тот же день. Общая механика связи витрины и учёта разобрана в опорной статье раздела; здесь мы разбираем один контур — самый дорогой в ошибках.
Маршрут заказа: пять систем и четыре стыка
Первое, что нужно нарисовать до начала работ, — таблица владения. В ней у каждого шага есть система, которая создаёт запись, и система, которая в этот момент имеет право менять статус. Если на каком-то шаге в колонке владельца оказывается две системы, вы уже нашли будущий баг.
| Шаг | Кто создаёт запись | Кто владеет статусом | Что ломается на этом стыке |
|---|---|---|---|
| Покупатель нажал «Оформить» | Сайт | Сайт | Двойное нажатие создаёт два заказа с разными номерами и одинаковым составом |
| Оплата | Платёжный сервис | Платёжный сервис до итогового ответа | Уведомление об успешной оплате не дошло — заказ висит неоплаченным |
| Заказ уехал в учёт | Учётная система | Учётная система | Повтор при обрыве связи даёт дубль; недоступность учёта — потерю заказа |
| Сборка и отгрузка | Склад | Учётная система по документам склада | Статус меняется на складе, но не возвращается на сайт — покупатель звонит |
| Передача в доставку | Служба доставки | Служба доставки | Трек-номер есть у перевозчика, но не доехал до карточки заказа |
Отдельно стоит зафиксировать порядок запуска. Направления «из учёта на витрину» — номенклатура, цены, остатки — безопасны: худшее последствие ошибки в них — неверная цифра на карточке, и мы разбирали этот контур в статье про обмен остатками и ценами. Направление «с витрины в учёт» создаёт в боевой базе документ, который пойдёт в отгрузку, в кассу и в отчётность, поэтому заказы всегда подключаются последними и всегда с защитой от повторной обработки. Обратный порядок — самая частая причина, по которой проект приходится останавливать на второй неделе и разбирать созданные документы вручную.
Горизонтальная схема из пяти блоков со стрелками: «Сайт» → «Платёжный сервис» → «Учётная система» → «Склад» → «Служба доставки». Под каждым блоком подпись «владелец статуса на этом шаге». На четырёх стыках между блоками нарисованы отметки-разрывы с подписями: «двойное нажатие», «уведомление об оплате не дошло», «повтор при обрыве или недоступность учёта», «статус не вернулся на сайт». Обратная стрелка от учёта к сайту подписана «статус покупателю». Чертёжная манера, подписи по-русски.
Владелец статуса: правило одного хозяина
Единственная система, которая на данном шаге имеет право изменить состояние заказа. Все остальные системы это состояние только читают и отображают. Правило нарушается, когда менеджер меняет статус в админке сайта, а кладовщик — в учётной системе: обе правки законны с точки зрения человека, но одна из них будет затёрта при следующем обмене, и предсказать, какая именно, невозможно.
Практическая трудность в том, что статусов в учётной системе обычно втрое больше, чем нужно покупателю. «Заказ клиента проведён», «резерв установлен», «отбор выполнен», «реализация проведена» — это внутренние состояния склада и бухгалтерии. Покупателю нужно пять: принят, собран, передан в доставку, прибыл в пункт выдачи, вручён. Между двумя наборами должна лежать явная таблица соответствия, а не логика в голове программиста.
- Внутренних статусов может быть сколько угодно — это дело учётной системы. Наружу выходят пять, и таблица соответствия согласуется с тем, кто отвечает за магазин, а не пишется подрядчиком по своему усмотрению.
- Каждое изменение статуса возвращается на сайт по событию, а не подбирается ночной выгрузкой. Статус, который приезжает раз в сутки, покупателю бесполезен: он успевает позвонить раньше.
- Статусы «отменён» и «частично отгружен» проектируются отдельно и заранее. Они редкие, поэтому их обычно забывают, и именно на них потом приходятся самые тяжёлые обращения в поддержку.
- Изменение статуса руками в админке сайта либо запрещено, либо ограничено списком состояний, которых нет в учёте. Иначе обмен будет затирать правки менеджера, а менеджер — терять доверие к системе.
Очередь и повторы: что происходит, пока учёт недоступен
Учётная система бывает недоступна регулярно и по нормальным причинам: обновление конфигурации, выгрузка отчётности, ночное обслуживание, обрыв канала. Вопрос не в том, случится ли это, а в том, что произойдёт с заказом, который оформили именно в эту минуту. Правильный ответ — ничего страшного: заказ уже записан на вашей стороне и ждёт в очереди.
- 1Шаг 1. Сначала записать у себя
Заказ сохраняется в базе сайта или в промежуточном хранилище до всякой попытки передать его дальше. Это главное архитектурное решение всего контура: система, недоступная в момент оформления, не должна приводить к потере заказа ни при каких обстоятельствах.
- 2Шаг 2. Поставить в очередь на передачу
Передача — отдельная задача со своим состоянием: «ожидает», «отправляется», «доставлено», «ошибка». Пока задача не перешла в «доставлено», заказ считается непереданным, и это видно в интерфейсе, а не только в логах.
- 3Шаг 3. Повторять с нарастающей паузой
Первый повтор через минуту, второй через пять, третий через пятнадцать и так далее. Повторы без пауз добивают систему, которая и так на обслуживании, и превращают короткую недоступность в долгую.
- 4Шаг 4. Сдаться заметно
После нескольких неудачных попыток задача помечается как требующая внимания, и уходит алерт живому человеку. Тихое исчезновение заказа из очереди — самый дорогой сценарий: заказ не потерян технически, но о нём никто не знает.
- 5Шаг 5. Уметь отправить повторно вручную
Кнопка «отправить в учёт ещё раз» рядом с заказом. Она нужна не для регулярной работы, а для того, чтобы разбор инцидента занимал минуты, а не звонок подрядчику. Работать она обязана безопасно — за это отвечает защита от повторной обработки из следующего раздела.
Схема слева направо: «Покупатель оформил» → «Запись в своей базе» (блок выделен как обязательный) → «Очередь передачи» с четырьмя состояниями «ожидает / отправляется / доставлено / ошибка» → «Учётная система». От блока очереди вниз ветка повторов с подписями «1 минута», «5 минут», «15 минут» и далее блок «алерт человеку». Сбоку кнопка-блок «отправить повторно вручную» со стрелкой в очередь. Чертёжная манера, подписи по-русски.
Защита от повторов: внешний номер, а не состав
Дубль возникает не из-за плохого кода, а из-за физики связи. Сайт отправил заказ, учётная система его создала, и в этот момент оборвался канал — ответ не дошёл. Сайт не знает, дошёл заказ или нет, и по правилам надёжности повторяет отправку. Учёт создаёт второй документ. Оба документа корректны, оба пойдут в отгрузку.
Правильное лечение — внешний номер: сайт присваивает заказу собственный неизменяемый идентификатор и передаёт его вместе с заказом, а учётная система перед созданием документа проверяет, нет ли уже документа с таким внешним номером. Есть — возвращает существующий, а не создаёт новый. Это делает повторную отправку безопасной, и именно поэтому кнопка «отправить ещё раз» из предыдущего раздела не превращается в генератор дублей.
Соблазн сравнить «клиент, сумма, состав, дата» и считать совпадение дублем понятен, но он ломает нормальную работу: постоянный покупатель, заказывающий один и тот же товар два раза за день, получит отказ во втором заказе. Единственный корректный признак дубля — совпадение внешнего номера, потому что он присвоен один раз и не меняется. Подробный разбор источников задвоений и процедуру разбора уже возникших дублей мы вынесли в отдельную статью.
Сопоставление номенклатуры: артикул как ключ
Заказ доехал, документ создался, но в нём не тот товар или пустая строка. Причина почти всегда одна: сопоставление позиций шло по названию. Названия меняют постоянно и без всякого злого умысла — маркетолог добавил в наименование цвет, контент-редактор убрал лишнее слово, менеджер поправил опечатку. Для человека это тот же товар, для обмена — новый.
- Ключ сопоставления — артикул или внутренний код номенклатуры, и он не меняется никогда. Название, штрихкод и цена меняться могут; ключ — нет. Если артикулы у вас исторически задвоены, это чинится до интеграции, а не во время неё.
- Товар с характеристиками — отдельная сложность. Ключом становится пара «артикул позиции плюс характеристика», иначе футболка размера M приедет в документ как футболка вообще, и склад соберёт наугад.
- Позиция, которую не удалось сопоставить, не молчит. Она попадает в отчёт несопоставленных с указанием заказа и строки, а заказ помечается как требующий внимания — но не отбрасывается.
- Отчёт несопоставленных смотрит человек со стороны магазина, а не подрядчик. Обычно там пять-десять строк в месяц, и разбираются они за пятнадцать минут; без ответственного он превращается в свалку через две недели.
Сравнение в две колонки на одном примере. Слева «Ключ — название»: строка заказа «Футболка синяя хлопок» не находит карточку «Футболка хлопковая, синяя», создаётся вторая карточка с остатком 0, заказ приходит на позицию, которой нет в продаже. Справа «Ключ — артикул»: строка заказа с артикулом FT-1042 находит ту же карточку независимо от названия. Внизу отдельная плашка «Товар с характеристиками: ключ — артикул + характеристика». Чертёжная манера, подписи по-русски.
Оплаты: почему заказ висит неоплаченным при успешном платеже
Покупатель заплатил, деньги списались, банк прислал ему уведомление — а в магазине заказ по-прежнему в статусе «ожидает оплаты», и склад его не собирает. Механика этой ситуации всегда одна и та же и не зависит от платёжного сервиса.
- 1Покупатель уходит на страницу оплаты платёжного сервиса и там платит. Ваш сайт в этот момент в процессе не участвует — он только ждёт.
- 2После списания платёжный сервис отправляет на ваш сайт служебное уведомление об успешной оплате. Это отдельный запрос от сервиса к вам, и именно он меняет статус заказа.
- 3Возврат покупателя на сайт после оплаты — это не подтверждение платежа. Покупатель мог закрыть вкладку, потерять связь или уйти по кнопке «назад»; на статус заказа это влиять не должно.
- 4Если служебное уведомление не дошло — упал ваш сервер, сработала блокировка на стороне защиты сайта, случился обрыв, — заказ остаётся неоплаченным при списанных деньгах. Платёжные сервисы обычно повторяют уведомление несколько раз, но полагаться только на это нельзя.
- 5Поэтому нужен второй контур: регламентная сверка неоплаченных заказов старше 15–30 минут напрямую через запрос статуса платежа в сервисе. Она ловит все уведомления, которые не дошли, и стоит нескольких часов работы.
И отдельное правило безопасности, которое стоит проверить на приёмке: сумма и валюта платежа сверяются с суммой заказа до перевода его в оплаченные, а само уведомление проверяется на подлинность подписью от платёжного сервиса. Заказ, который переводится в оплаченные по факту получения любого запроса на нужный адрес, — это не интеграция, а открытая дверь.
Суточная сверка: создано N — доехало N
Всё описанное выше работает, только если кто-то ежедневно смотрит одну цифру: сколько заказов создано на сайте за сутки и сколько документов появилось в учёте. Расхождение — это либо потеря, либо дубль, и разбирается оно в тот же день, а не через неделю по звонку покупателя.
| Показатель | Где смотрим | Норма | Что означает отклонение |
|---|---|---|---|
| Создано заказов на сайте за сутки | База сайта | Базовая цифра для сравнения | — |
| Создано документов в учёте за сутки | Учётная система, отбор по внешнему номеру | Совпадает с первой цифрой | Меньше — потеря, больше — дубли |
| Задач в очереди со статусом «ошибка» | Интерфейс очереди передачи | 0 | Учёт был недоступен или отклонил заказ по содержанию |
| Строк в отчёте несопоставленных позиций | Отчёт обмена | Единицы в месяц | Переименование товара или расхождение артикулов |
| Заказов «ожидает оплаты» старше 30 минут при успешном платеже | Сверка с платёжным сервисом | 0 | Не дошло служебное уведомление об оплате |
Теперь цена вопроса. Модельный магазин: 900 заказов в месяц, средний чек 6 200 ₽, валовая маржа 24 % — 1 488 ₽ с заказа, ставка сотрудника 700 ₽ в час. Обмен настроен «в лоб»: без очереди повторов, без защиты от дублей и без сверки.
Лечится это пятью работами, и все они делаются на уже существующем обмене — переписывать его не нужно.
Столбиковая диаграмма из пяти частей с подписями в рублях за месяц: «Потерянная маржа 9 заказов — 13 392», «Обращения «где мой заказ» — 5 040», «Разбор опоздавших заказов — 3 150», «Разбор дублей — 2 567», «Обратная логистика — 900». Итог справа «25 049 ₽ в месяц». Ниже горизонтальная плашка «Смета устранения — 150 000 ₽, окупаемость 6 месяцев». Ось подписана в рублях, все значения проставлены. Чертёжная манера, подписи по-русски.
Ответственный за сверку должен быть со стороны магазина, а не подрядчика. Подрядчик видит техническую сторону: очередь пуста, ошибок нет. Расхождение на два заказа означает, что двум конкретным покупателям надо позвонить сегодня, и это решение принимает тот, кто отвечает за магазин. В договоре на поддержку эта роль описывается отдельно — вместе со сроком реакции на алерт; что должно быть в такой поддержке и чем она отличается от абонентской платы, разобрано на нашей странице о поддержке. Заказы с маркетплейсов при этом сверяются отдельным потоком: там внешним номером служит идентификатор отправления, а не номер заказа сайта, и контур площадок мы разбирали в отдельной статье.
Когда всё это делать не надо
Есть три ситуации, в которых полный контур заказов не окупается, и признать это честнее, чем продать проект.
- Меньше 90–120 заказов в месяц. Потери составят один-два заказа, то есть 1 500–3 000 ₽, против 150 000 ₽ вложений. Рабочий вариант — суточная сверка вручную по двум цифрам и письменный регламент, кто её делает и что происходит в его отпуск. Это пятнадцать минут в день и ноль рублей.
- Заказ и так подтверждается менеджером звонком. Если каждый заказ перед сборкой проходит через живого человека, потеря обнаруживается в тот же день сама собой. Здесь дешевле автоматизировать не передачу, а подготовку звонка — подсказку менеджеру и заполнение карточки.
- Учётная система пока не готова принимать документы автоматически. Если конфигурация в активной доработке или в ней нет заказа клиента как документа, контур передачи придётся переделывать через два месяца вместе с доработкой. Правильный порядок — сначала торговый контур в учёте, потом обмен.
И один вывод, который важнее всех расчётов. Контур заказов проектируется от предположения, что каждая система в цепочке рано или поздно будет недоступна, и в этот момент заказ не должен исчезнуть. Всё остальное — очередь, повторы, внешний номер, сверка — это лишь способы выполнить одно требование: заказ, за который покупатель уже заплатил, обязан быть найден и обработан, даже если в момент оформления половина систем лежала.
Заказ, за который уже заплатили, не имеет права зависеть от того, была ли доступна учётная система в ту минуту, когда его оформили.
