Один заказ пришёл дважды: как связать маркетплейсы с ERP без дублей и старых остатков

2026-09-16 14:26:44 Время чтения 11 мин 35

Два одинаковых заказа в ERP, системе управления ресурсами компании, и товар, проданный в офлайне, но всё ещё доступный на маркетплейсе, выглядят для оператора как разные ошибки. Часто у них одна причина: системы обмениваются данными, однако у обмена нет точных правил.

Один заказ пришёл дважды. Это вполне реальный класс событий. В документации Яндекс Маркета прямо сказано, что площадка может несколько раз отправить уведомление об одном изменении. Там же предупреждают: время и состояние заказа в уведомлении, ответе API и системе магазина могут различаться.

Привет, я Антон Фокин, CEO Qtim. Разберу, как проектировать интеграцию с маркетплейсами и ERP, чтобы заказ не размножался, статусы не спорили друг с другом, а остаток отражал продажи во всех каналах. В конце будет короткий критерий готовности, который можно проверить до запуска.

API подключили. Правила обмена ещё не появились

Токен, работающий запрос и первый полученный заказ доказывают только техническую доступность канала. Рабочая интеграция начинается с ответов на более неудобные вопросы: какая система владеет каждым полем, как распознать повторное событие, какой статус считать актуальным и что делать после тайм-аута.

У площадок разные контракты и операционные модели. В WB API отдельно описаны товары, остатки и несколько схем исполнения заказов. Яндекс Маркет делит методы по кабинетам, магазинам, складам и моделям работы. ERP хранит собственные документы, регистры, резервы и правила проведения. Прямое соединение «API в ERP» быстро обрастает условиями внутри учётной системы.

Мы обычно выносим работу с площадками в интеграционный слой. Он переводит внешние сущности во внутреннюю модель, хранит соответствия идентификаторов, принимает события, запускает повторы и ведёт журнал. ERP получает согласованный контракт вместо логики трёх площадок, размазанной по обработчикам.

Сама 1С допускает несколько способов интеграции. Её REST-интерфейс позволяет читать и изменять объекты, создавать документы и получать остатки. Конкретный транспорт выбирают после разбора конфигурации, нагрузки и допустимых изменений. Схема обмена важнее модного названия протокола.

Пять сущностей, пять владельцев: без этой карты обмен спорит сам с собой

Перед разработкой полезно собрать карту источников истины. Это короткая таблица или схема: сущность, владелец, направление обмена, частота, ключ и поведение при ошибке. В типовом проекте она выглядит так:

  1. товар и SKU: ERP или PIM (система управления товарными данными) хранит внутренний идентификатор, интеграционный слой связывает его с внешним ID каждой площадки;
  2. цена: владелец зависит от модели ценообразования; рядом фиксируются акции, минимальная цена и момент вступления значения в силу;
  3. доступный остаток: ERP, WMS (система управления складом) или отдельная система управления заказами считает физический запас, резервы и страховой остаток;
  4. заказ: маркетплейс владеет внешним номером и исходными условиями, ERP создаёт внутренний документ с постоянной ссылкой на этот номер;
  5. статусы, возвраты и выплаты: площадка сообщает внешнее состояние, а компания отдельно ведёт операционный, логистический и финансовый контуры.

Карту нельзя заполнять по принципу «всё берём из ERP». Учётная система может знать количество на складе и не знать, что площадка уже создала заявку на отмену. Маркетплейс видит свой заказ и не учитывает продажу из розничной точки. Интеграционный слой связывает эти факты, не присваивая себе владение бизнес-данными.

Минимальная строка карты

Сущность → источник → внешний ключ → направление → допустимая задержка → действие при ошибке → ответственный. Когда хотя бы одно поле пустует, спор о данных переезжает с доски аналитика в рабочий заказ.

Повторное уведомление не должно создавать второй заказ

Сетевой обмен не обещает, что каждое событие придёт ровно один раз и строго по порядку. Площадка повторяет уведомление, клиент повторяет запрос после тайм-аута, очередь доставляет сообщение заново. Поэтому мы делаем создание заказа идемпотентным: повтор той же команды сохраняет прежний результат.

Практический ключ можно собрать из площадки, кабинета продавца и внешнего ID заказа. На эту комбинацию ставят уникальное ограничение. При повторе слой интеграции находит созданный документ, сверяет версию или время обновления и применяет только новое изменение.

Мы сохраняем след каждого события: внешний ID, внутренний ID, направление, тип операции, время источника, номер попытки и результат. В журнал записываем и цифровой отпечаток сообщения, то есть хэш полезной нагрузки. Тогда оператор видит, пришла копия прежнего сообщения или площадка прислала другой состав с тем же номером.

Тайм-аут требует особой осторожности. Отсутствие ответа не доказывает, что операция провалилась: ERP могла принять документ, а сеть потеряла подтверждение. Без проверки по внешнему ключу автоматический повтор создаст дубль именно в тот момент, когда система пытается восстановиться.

Статус «доставлен» живёт отдельно от оплаты и возврата

Попытка свести все состояния к одному полю рождает странные значения: «отгружен, частично выкуплен, возврат в пути, выплата ожидается». Человеку фраза ещё понятна. Для автоматизации это четыре разных процесса.

Мы разделяем как минимум внешний статус площадки, внутренний статус обработки, доставку и финансовое состояние. Затем описываем разрешённые переходы. Система знает, кто меняет статус, какое событие разрешает следующий шаг и можно ли откатить операцию.

Такой граф защищает от запоздавших сообщений. Событие «готов к отгрузке», пришедшее после подтверждённой доставки, попадёт в журнал и очередь разбора, но не вернёт заказ на склад. В документации Яндекс Маркета порядок переходов указан отдельно: нарушение последовательности приводит к ошибке.

Для бизнеса карта статусов даёт ещё один результат: становится видно, где заказ застрял и кто должен действовать. «Ошибка интеграции» превращается в конкретную очередь: не найден SKU, ERP отклонила документ, склад не подтвердил резерв, площадка не приняла переход.

Остаток должен учитывать продажи во всех каналах

Остаток для маркетплейса означает количество, доступное к заказу. Его рассчитывают из свободного физического запаса с учётом активных резервов и страхового остатка. Продажу в другом канале сразу вычитаем из доступного количества. Для всех площадок используем одно правило расчёта.

Яндекс Маркет отдельно подчёркивает, что продажа вне площадки тоже должна сразу уменьшать передаваемый остаток. В запросе указываются SKU, склад, количество и момент актуальности значения. Эта отметка времени важна: новое обновление не должно уступить место опоздавшему старому пакету.

Один лишь обмен по расписанию оставляет окно для перепродажи. Его ширина равна интервалу синхронизации плюс время обработки. Поэтому критичные изменения отправляют по событию, а периодическую сверку оставляют как страховку от потерянных сообщений. Событийный поток даёт скорость, сверка восстанавливает целостность.

Формула, которую согласовываем до кода

Доступно к продаже = свободный физический остаток − активные резервы − страховой запас. Продажа в другом канале сразу меняет свободный остаток. Для каждого слагаемого фиксируем владельца и момент обновления.

Семь сбоев, которые разыгрываем до запуска

Успешный сценарий проверяет API. Набор аварийных ситуаций проверяет всю операционную систему. Перед первым боевым заказом мы проводим семь испытаний:

  1. одно уведомление приходит дважды;
  2. два статуса приходят в обратном порядке;
  3. ERP создаёт документ, но ответ теряется по тайм-ауту;
  4. площадка возвращает ограничение частоты или временную серверную ошибку;
  5. в пакете из ста остатков часть строк отклонена;
  6. один внешний SKU связан с неверной номенклатурой;
  7. товар одновременно покупают на маркетплейсе и в другом канале.

Для каждого сценария фиксируют ожидаемое состояние заказа и остатка, максимальное время восстановления, маршрут оповещения и действие оператора. Повтор должен быть безопасным, ошибка видимой, а восстановление доступным без правки данных напрямую в базе.

Один сквозной заказ важнее трёх подключённых площадок

Первый релиз разумно ограничить одной площадкой, одной схемой исполнения, одним складом и одним типом заказа. Заказ проходит весь путь: появляется на площадке, создаётся в ERP, резервирует товар, меняет статусы, отгружается, отменяется или возвращается. После этого подключение следующего канала становится добавлением адаптера к устойчивому ядру.

В проекте HOTZ мы связали с 1С одну витрину для четырёх продуктовых линеек: товары, цены, остатки и заказы участвуют в двустороннем обмене. За интерфейсом работает тот же принцип: у сущностей есть владельцы, операции идут в правильной последовательности, а состояние заказа можно разобрать по шагам.

Интеграция готова, когда один заказ проходит от площадки до ERP и обратно с тем же внешним ID, составом, количеством и разрешённой цепочкой статусов. Повтор события сохраняет один документ, ошибка попадает в журнал, а сверка восстанавливает пропущенные изменения.

Тогда оператор открывает ERP и видит один заказ вместо двух, а покупатель видит доступным только тот товар, который компания действительно может отгрузить.

Мы проектируем интеграции с 1С, ERP, WMS и API площадок в направлении e-commerce и маркетплейсов. Можно прислать схему текущего обмена или описать проблемный заказ: разберём источники данных, статусы и точки отказа, затем предложим состав первого релиза.