Увечері менеджер відкриває кабінет маркетплейсу, адмінку сайту й таблицю складу. На Rozetka товар уже продано, але інтернет-магазин досі показує його в наявності. За цей час інший покупець оформлює замовлення на сайті. Йому доводиться телефонувати, пояснювати помилку й скасовувати покупку. Якщо те саме стається на маркетплейсі, скасування б'є по рейтингу продавця. День закінчується ручною звіркою: хтось переносить цифри між системами й сподівається, що до ранку вони не розійдуться знову. Це не проблема запуску магазину. Вона з'являється пізніше, коли один фізичний товар продається через склад, сайт і кілька зовнішніх каналів. Тому рух залишків після запуску варто проєктувати разом із каталогом та оформленням замовлення під час розробки інтернет-магазину.

Коротко: щоб залишки магазину, складу й маркетплейсів не розходилися, одна система має бути єдиним джерелом правди, а всі канали повинні лише отримувати з неї доступну до продажу кількість. Із фізичного залишку треба віднімати резерв одразу під час створення замовлення, а для ризикових каналів задавати страховий буфер. Після скасування резерв повертається лише один раз, а повернений товар стає доступним після перевірки складу, не в момент отримання посилки. Ручні коригування також вносять у головній системі. Зміни краще передавати дельтами, тобто оновлювати лише товари, у яких змінилася кількість, замість повторного завантаження всього каталогу. Вебхуки повідомляють про подію одразу, а періодичне опитування підхоплює канали, які не надсилають подій або пропустили їх. Повторне повідомлення не повинно вдруге списувати товар: для цього кожна операція має унікальний ідентифікатор. Оновлення проходять через чергу з повторними спробами, тому тимчасово недоступний API не губить дані. Окремий журнал фіксує розбіжності між системами. Якщо готовий конектор не підтримує ці правила, потрібна власна інтеграція.

Звідки беруться розбіжності

Залишок рідко стає неправильним через одну велику помилку. Частіше кілька систем чесно показують різні стани одного товару, бо оновлюються в різний час і по-різному трактують слово «в наявності».

  • Синхронізація працює за інтервалом. Маркетплейс прийняв замовлення, а наступний обмін із сайтом ще не почався. У цьому проміжку старе число виглядає актуальним, хоча товар уже проданий.
  • Резерв не дорівнює фізичному залишку. Товар лежить на полиці, але вже є в незавершеному замовленні. Якщо канал бачить тільки складську кількість, він пропонує покупцеві те, що фактично не можна продавати.
  • Повернення запізнюються. Посилку прийняли назад, однак товар ще не перевірили або не повернули в доступний залишок. Інша крайність: повернення внесли на складі, але сайт про нього не дізнався.
  • Ручне коригування лишається локальним. Комірник виправив пересорт, списав пошкоджену пару чи знайшов товар, але зміна залишилася тільки в складській програмі.
  • Офлайн-продаж не доходить до каталогу. Останню одиницю купили у фізичній точці, каса закрила продаж, а онлайн-канали продовжили показувати наявність.
  • Один товар виставлений у кількох місцях. Сайт, Rozetka і Prom.ua одночасно бачать ту саму фізичну одиницю. Два замовлення приходять раніше, ніж будь-який канал отримує новий залишок.
  • Постачальник живе за власним розкладом. Його CSV або XML-фід оновив кількість у момент, не пов'язаний із вашими продажами, резервами та поверненнями. Свіжий файл постачальника може перезаписати новіший стан вашого складу.

Тому звірка лише фінального числа не пояснює причину. Треба бачити події навколо нього: замовлення, резерв, скасування, повернення, офлайн-продаж, ручне коригування та імпорт постачальника.

Розбіжність іноді маскується сама. Один канал ще не списав продаж, інший уже додав неперевірене повернення, і підсумкові числа випадково збігаються. Ручна перевірка бачить однакову кількість і завершується, хоча походження залишку вже різне. Наступна подія відкриває проблему знову. Саме тому робоча система порівнює не тільки число в картці товару, а й те, з яких підтверджених операцій воно склалося. Для менеджера результат має бути простим: одиниця вільна, зарезервована, очікує перевірки після повернення або недоступна.

Три способи синхронізувати залишки

Ручний експорт та імпорт CSV/XML

Найдешевший варіант: відповідальна людина вивантажує файл зі складу й завантажує його на сайт або маркетплейс. Це нормально для малого каталогу й одного каналу, де замовлення з'являються нечасто. Формат зрозумілий, окрема розробка не потрібна, помилку можна знайти у файлі.

Межа підходу настає разом зі зростанням обсягу. Файл застаріває ще до завантаження, різні канали вимагають різної структури, а вечірня звірка стає постійною роботою. Ручний процес також не встигає заблокувати товар, який щойно зарезервували.

Готові конектори

Конектор можна швидко ввімкнути й налаштувати без окремого проєкту інтеграції. Для типового каталогу він передає залишки через доступний XML-фід або API-обмін із сайтом, Rozetka чи Prom.ua. Це практичний вибір, якщо правила магазину збігаються з тим, що вже закладено постачальником конектора.

Разом із швидким стартом ви приймаєте його інтервал оновлення, зіставлення полів і межі. Власна логіка резервів, різні буфери для каналів або незвичне повернення можуть не поміститися в готову схему. Є й підписка за підключені канали. Перед вибором варто окремо порахувати не лише технічне підключення, а й економіку продажу через майданчик; для Prom.ua ми розібрали це в матеріалі про комісію маркетплейсу та власний магазин.

Власна інтеграція

Вона дорожча на старті, зате правила повторюють ваш процес. Можна визначити головну систему, момент резервування, пріоритет каналів, буфери, повторні спроби й спосіб розбору помилок. Плати за кожен підключений канал немає, хоча саму інтеграцію треба підтримувати, коли змінюються системи з обох боків.

Власний обмін особливо доречний, коли склад уже працює в 1С/BAS, WMS або окремій обліковій системі. Тут спершу складають карту відповідальності даних. Такий самий принцип детально пояснений у статті про інтеграцію 1С/BAS з CRM: для кожної сутності треба знати, де вона створюється й хто має право її змінювати.

Як влаштована робоча синхронізація

Одна система володіє залишком

Єдине джерело правди означає, що остаточну кількість змінює одна система. Зазвичай це складський або обліковий контур. Сайт і маркетплейси не сперечаються з ним, а показують розраховану доступність. Якщо оперативний залишок уже ведеться у WMS-системі, саме вона може виконувати цю роль.

Спершу треба домовитися, що саме передавати. Фізична кількість не підходить для продажу напряму. Від неї віднімають активні резерви й, за потреби, страховий буфер. Повернення додається тільки після того, як склад підтвердив, що товар знову можна продавати.

Правило одного власника стосується і ручних змін. Якщо працівник виправляє кількість у кабінеті маркетплейсу, ця дія не повинна залишатися окремою правдою каналу. Вона або повертається до головної системи як контрольована операція, або забороняється, а коригування роблять там, де ведеться склад. Так само скасування замовлення не може саме по собі додавати товар: спершу головна система перевіряє, чи існує активний резерв і чи його ще не звільнили. Це прибирає подвійне повернення кількості.

Резерв створюється разом із замовленням

Якщо віднімати товар лише під час відвантаження, між оформленням і пакуванням він продовжує продаватися в інших каналах. Тому резерв виникає під час створення замовлення. Після оплати або підтвердження він переходить далі за процесом; після коректного скасування звільняється. Статуси замовлень і правила скасування часто зручно тримати у CRM-системі, але власником складської кількості вона від цього не стає.

Передаються зміни, а не весь каталог

Дельта-синхронізація бере тільки позиції, у яких щось сталося: продаж, резерв, приймання, повернення або коригування. Це швидше й створює менше навантаження, ніж повторне завантаження повного каталогу. Повний обмін все одно корисний як контрольна звірка, але він не повинен бути єдиним способом реагувати на продаж.

Масштаб каталогу добре видно в кейсі інтернет-магазину взуття Airstep: 6700+ SKU, автоматичний XML-імпорт від 3 постачальників, Django 4.2, PostgreSQL, Meilisearch і власне оформлення замовлення. Коли джерел кілька, важливо не дозволити черговому фіду безумовно перезаписати резерви й локальні складські зміни.

Вебхуки реагують, опитування перевіряє

Вебхук працює як повідомлення: канал каже, що замовлення створене або статус змінився. Це правильний варіант для подій, на які треба реагувати одразу. Опитування працює інакше: ваша система сама за розкладом питає, чи є нові дані. Воно потрібне, коли канал не надсилає потрібної події, а також як контроль, якщо повідомлення загубилося.

Повторне повідомлення не повторює списання

Мережа може повторно доставити ту саму подію, а система після затримки може не знати, чи пройшла перша спроба. Ідемпотентність тут означає просте правило: одна й та сама операція з тим самим ідентифікатором змінює залишок лише один раз. Без цього повтор замовлення виглядатиме як новий продаж.

Черга переживає недоступність каналу

API маркетплейсу іноді не відповідає. Оновлення не можна просто відкинути. Воно потрапляє в чергу, де зберігається до успішної передачі, а невдалі спроби повторюються. Водночас система має показати оператору, що певний канал відстає, інакше технічна затримка знову стане прихованою розбіжністю.

Журнал показує, який канал помиляється

Журнал розбіжностей зберігає товар, очікувану й фактичну кількість, канал, час і пов'язану операцію. Один запис допомагає виправити конкретний товар. Повторюваний рисунок важливіший: наприклад, розбіжності виникають тільки після повернень або імпорту постачальника. Тоді команда виправляє правило, а не редагує залишки вручну по колу.

Що робити з останньою одиницею товару

Остання одиниця найбільш ризикована, бо її одночасно бачать усі канали, а часу на виправлення немає. Для неї використовують страховий буфер або поріг зупинки продажу. Логіка проста: канал отримує не фізичний залишок, а кількість після резервів і власного буфера. Коли доступність доходить до заданого порога, канал показує нуль і перестає приймати замовлення.

Поріг не обов'язково однаковий усюди. Власний сайт може швидше підтвердити резерв, а зовнішній майданчик може оновлюватися за інтервалом. Для товару постачальника потрібне одне правило, для одиничного товару на вашій полиці інше. Це свідомий обмін: магазин інколи раніше знімає позицію з продажу, зате не обіцяє одну річ двом покупцям.

Скільки це коштує і скільки триває

Окремої чесної ціни «за синхронізацію» без схеми каналів немає. Вузький обсяг може означати обмін між готовим складом і одним сайтом. Ширший охоплює маркетплейси, офлайн-касу, постачальників, резерви та повернення. Найбільший варіант включає створення системи, яка стане джерелом залишку.

Реальні стартові ціни Artbrain такі: WMS від $2500, інтернет-магазин від $2500, CRM від $3000. Модуль обміну оцінюється окремо після опису потоків даних. Термін так само залежить від кількості каналів, якості артикулів і каталогів, правил резерву та повернення, доступності обміну в кожній системі й обсягу тестування. Називати календарний діапазон до цієї перевірки було б здогадкою.

Типові помилки

  • Дозволити всім системам змінювати залишок. Після першого конфлікту вже незрозуміло, яке число правильне і чия зміна остання.
  • Передавати фізичну кількість без резервів. Товар є на полиці, але вже обіцяний іншому покупцеві.
  • Покладатися лише на повний імпорт. Великий файл не вирішує проблему подій між двома завантаженнями.
  • Резервувати під час відвантаження. До цього моменту сайт і маркетплейси продовжують продавати ту саму позицію.
  • Не захищатися від повторів. Повторно доставлене замовлення вдруге віднімає кількість, хоча нового продажу не було.
  • Мовчки пропускати помилки API. Без черги, повторних спроб і сповіщення оператор дізнається про збій від покупця.
  • Запускати без реальних сценаріїв. Треба перевірити скасування, повернення, офлайн-продаж, останню одиницю, повтор події та тимчасово недоступний канал.

Ще одна помилка менш технічна: автоматизувати хаос. Якщо склад не має правила для списання, повернення й ручного коригування, інтеграція лише швидше рознесе суперечливі дані по всіх каналах.

Коли синхронізація не потрібна

Власна інтеграція не потрібна магазину з невеликим каталогом, одним каналом і рідкими змінами. Ручний CSV/XML або звичайна звірка можуть бути дешевшими й зрозумілішими. Немає сенсу будувати чергу та журнали, якщо одна людина без напруги контролює весь рух товару.

Не варто поспішати й тоді, коли сам складський процес ще змінюється. Спершу визначте, хто створює резерв, коли повернення знову стає доступним і де фіксується офлайн-продаж. Автоматизація потрібна після появи повторюваного правила, а не замість нього.

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

Часті питання

Чому залишки на сайті й маркетплейсі не збігаються?

Розбіжності виникають, коли кожен канал зберігає свою кількість, а оновлення затримується, відхиляється або прив’язується до неправильного SKU чи варіанта. Бронювання, скасування, повернення й ручні зміни також можуть враховуватися на різних етапах. Потрібне одне джерело правди для залишку та журнал обміну з повторною відправкою подій, які завершилися помилкою.

Як часто потрібно синхронізувати залишки між магазином і складом?

Залишок варто оновлювати після кожної події, що змінює доступну кількість: продажу, резерву, скасування, повернення, приймання або ручного коригування. Окремо потрібна планова звірка всіх каналів, щоб знаходити пропущені події. Для активних каналів одного періодичного повного вивантаження недостатньо.

Чи вистачить готового конектора для синхронізації залишків?

Готового конектора зазвичай достатньо, якщо системи мають стабільні API, а бізнес використовує стандартні правила для товарів, варіантів і складів. Кастомна інтеграція потрібна для кількох складів, комплектів, резервів, офлайн-продажів, нестандартного зіставлення SKU або окремих обмежень каналів. Рішення варто приймати після перевірки API та процесів, а не лише за списком функцій конектора.

Як не продати останню одиницю товару одночасно на кількох майданчиках?

Доступну кількість треба резервувати в одній центральній системі до підтвердження замовлення, причому перевірка й резерв мають виконуватися як одна операція. Якщо кілька каналів одночасно запитують останню одиницю, успішним буде лише перший резерв, а інші отримають статус «немає в наявності» або підуть на ручну перевірку. Після цього новий залишок передається на всі канали з повторними спробами та захистом від дублювання подій.

Скільки коштує інтеграція синхронізації залишків?

Фіксованої ціни для синхронізації залишків немає, бо обсяг залежить від облікової системи, API каналів, правил складу та обробки конфліктів. Якщо це частина нової WMS, розробка починається від $2500; новий інтернет-магазин також коштує від $2500, а CRM для керування замовленнями — від $3000. Точну оцінку можна дати після перевірки поточних систем і схеми обміну даними.

Anton Kunashenko, CEO & Lead Developer
CEO та провідний розробник Artbrain

Anton Kunashenko

Засновник Artbrain з 2018 року. Розробляє цифрові продукти для бізнесу: від лендингів до enterprise-систем.