Остатки на сайте и маркетплейсе расходятся: где искать причину

Расхождение остатков между сайтом и маркетплейсом почти всегда вызывает споры: “на сайте было 5, на маркетплейсе 0”, “заказ пришёл на товар без остатка”, “остаток обновился, но не там”. Чтобы разобраться, нужно знать не только итоговое число, но и путь его расчёта.

Остаток — это не просто колонка amount. Обычно это склад, резерв, виртуальный остаток, задержка синхронизации, маппинг товара и ответ внешнего API.

Сначала определить источник правды

Нужно понять, где остаток считается главным:

  • учётная система;
  • сайт;
  • складская таблица;
  • маркетплейс;
  • ручная админка;
  • промежуточная интеграционная база.

Если источник правды не определён, каждая система будет считать себя главной. Это быстро приводит к расхождениям.

Проверить товарный маппинг

Остаток мог уйти не на тот товар. Поэтому первым делом проверяют связь: системный товар, товар поставщика, offer_id маркетплейса, barcode, sku.

site_product_id: 1001
supplier_product_id: 5588
marketplace_offer_id: SKU-ABC-123

Если два системных товара связаны с одним offer_id, остатки будут перетирать друг друга.

Склады

Остатки часто считаются по нескольким складам. На сайт может идти сумма всех доступных складов, а на маркетплейс — только один склад или отдельный виртуальный остаток.

available = warehouse_1 + warehouse_2 - reserve

Нужно проверить, какие склады участвуют в расчёте и не попали ли туда архивные или технические склады.

Резервы

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

  • заказы в ожидании оплаты;
  • сборочные задания;
  • возвраты;
  • отменённые, но не освобождённые резервы;
  • ручные блокировки остатков.

Задержка синхронизации

Если остатки обновляются раз в 15 минут, некоторое расхождение нормально. Важно понимать допустимое окно задержки и показывать last_synced_at.

product_id: 1001
calculated_stock: 7
sent_stock: 7
last_synced_at: 2026-06-18 09:00:00

Если last_synced_at старый, проблема не в формуле, а в остановленной синхронизации.

Очередь и ошибки API

Остаток мог рассчитаться правильно, но не уйти в маркетплейс. Нужно смотреть очередь и ответ API.

[
    'offer_id' => 'SKU-ABC-123',
    'stock' => 7,
    'http_code' => 429,
    'error' => 'rate limit',
]

Если API вернул ошибку, задача должна перейти в retry или failed, а не исчезнуть.

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

Иногда в проекте есть правила: не отправлять меньше 1, не отправлять больше 10, оставлять страховой запас. Такие правила нужно документировать.

marketplace_stock = min(max(real_stock - safety_stock, 0), max_marketplace_stock)

Без этого поддержка будет искать ошибку там, где работает бизнес-ограничение.

Лог расчёта

Для спорных остатков полезно хранить не только итог, но и детали расчёта: какие склады вошли, какой резерв вычли, какое число отправили и какой ответ получили.

Чек-лист

  1. Определить источник правды по остаткам.
  2. Проверить маппинг товара и offer_id.
  3. Проверить склады, участвующие в расчёте.
  4. Проверить резервы и отменённые заказы.
  5. Проверить last_synced_at.
  6. Проверить очередь отправки остатков.
  7. Проверить ответы API маркетплейса.
  8. Проверить правила страхового запаса и лимитов.
  9. Сравнить лог расчёта с фактическим числом.

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

Комментарии (0)

Пока нет комментариев. Будьте первым!