Залиште заявку
Дякуємо за ваш запит
Ми розглянемо деталі вашого проєкту та підготуємо для вас комерційну пропозицію.

Інтеграції через API: як будувати стабільний обмін із CRM та складами

Два тижні тому один магазин прийшов до нас із проблемою, яка спочатку виглядала дрібницею: раз на кілька днів на складі «губилося» замовлення. Не критично — три-чотири штуки на тиждень. Але клієнт телефонує, менеджер шукає замовлення в CRM, знаходить, а на складі його ніхто не бачив. З’ясувалось: інтеграція між магазином і складською системою тихо падала кожні кілька годин, і ніхто про це не знав, бо помилка просто губилась у логах, які ніхто не читав.

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

Webhooks чи опитування: не завжди очевидний вибір

Перше рішення при будь-якій інтеграції — як система дізнається про зміни в іншій. Варіантів фактично два: чекати, поки зовнішня система сама надішле подію (webhook), або періодично питати самому «що нового» (polling).

Webhook виглядає елегантніше. Подія сталась — прилетів запит, обробили, все миттєво. Але тут є нюанс: webhook працює тільки якщо приймаюча сторона доступна саме в момент відправки. Сервер впав на 40 секунд для деплою — і подія, яка прилетіла саме в ці 40 секунд, просто зникла. Більшість систем не повторюють відправку, або повторюють один-два рази й здаються.

Опитування навпаки — негарне, зате передбачуване. Раз на п’ять хвилин запит «дай мені все, що змінилось з такого часу» завжди наздожене пропущені зміни, бо наступний запит просто підхопить те, що не встиг попередній. Ціна — затримка (дані не миттєві) і навантаження на обидві системи, особливо якщо каталог великий.

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

Сервери та мережеві кабелі в дата-центрі

Чому один і той самий запит не повинен створювати два замовлення

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

Рішення називається ідемпотентність, і насправді воно просте: кожному запиту, який щось змінює (створює замовлення, списує товар, оновлює баланс), присвоюється унікальний ключ — ідемпотентний ключ. CRM перед обробкою перевіряє: цей ключ вже приходив? Якщо так — повертає результат попередньої обробки, нічого не створюючи вдруге. Якщо ні — обробляє і запам’ятовує ключ.

Хто генерує ключ? Той, хто ініціює запит, і генерувати його треба один раз — на етапі формування замовлення, а не на етапі кожної спроби відправки. Інакше retry просто згенерує новий ключ і проблема повернеться в тому ж вигляді.

Retry — це не просто «спробувати ще раз»

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

Робочий підхід — експоненційна затримка між спробами: перша повторна спроба через секунду, наступна через дві, потім чотири, вісім і так далі, з якимось розумним максимумом і невеликим випадковим розкидом (jitter), щоб сотні клієнтів не били по серверу рівно в одну секунду одночасно.

І окремо — що робити, коли спроби скінчились, а результату немає. Тут з’являється черга непридатних повідомлень, dead-letter queue: замість того, щоб просто загубити подію після п’ятої невдалої спроби, її кладуть в окрему чергу для ручного розбору. Хтось із команди раз на день переглядає цю чергу і вирішує — повторити, пропустити чи розібратись вручну. Без такої черги подія просто зникає, і ви дізнаєтесь про пропущене замовлення від клієнта, а не від системи.

Робочий стіл розробника з кількома моніторами

Хто головний, коли дані розходяться

Уявімо: клієнт змінив номер телефону в CRM під час дзвінка менеджеру. Через годину той самий клієнт змінив телефон у себе в кабінеті на сайті. Яке значення правильне?

Без чіткого правила відповідь залежить від того, яка синхронізація відпрацювала останньою — а це випадковість, не логіка. Тому перед тим, як писати код, варто прямо визначити: яка система є джерелом правди для яких даних. Найчастіше це виглядає так — CRM головна для статусу замовлення й історії спілкування з клієнтом, магазин головний для каталогу і цін, склад головний для залишків. Клієнтські дані (телефон, адреса) — найчастіше найбільш спірна зона, і тут варто явно вирішити: останній за часом запис виграє, чи один бік взагалі не приймає зміни з іншого.

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

Як зрозуміти, що синхронізація тихо зламалась

Найгірший сценарій — не той, коли інтеграція падає з гучною помилкою. Найгірший — коли вона продовжує «працювати», просто нічого не роблячи: endpoint повертає 200 OK, чергу обробляє, а дані насправді вже кілька днів не оновлюються, тому що змінився формат відповіді на боці постачальника, чи протух токен, чи хтось випадково поміняв URL.

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

  • Лічильник останнього успішного синку з таймстампом — і алерт, якщо він старіший за очікуваний інтервал.
  • Моніторинг не тільки помилок, а й «підозрілої тиші» — різке падіння кількості оброблених подій теж сигнал.
  • Періодична звірка контрольних цифр: скільки замовлень у магазині за добу і скільки за той самий період прийшло в CRM.

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

Наостанок

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

Поділитися цією статтею:
Свіжі статті
Усі статті
HTTP 304 Not Modified: що це за код і як він впливає на швидкість сайту
Відкрийте вкладку Network у браузері, перезавантажте будь-яку сторінку вдруге — і серед рядків із кодом 200 обов’язково з’явиться кілька зі статусом 304.…
Як відкрити інтернет-магазин в Україні: повний гайд для початківців
Знайомий днями написав: «Хочу свій інтернет-магазин, з чого почати?» Перше, що я запитав — а що продаєш і кому. Він завис секунд…
Як створити інтернет-магазин з нуля: покрокова інструкція для бізнесу
Власник невеликого магазину дитячого одягу якось написав нам одну фразу: «Хочу інтернет-магазин, зробіть як у конкурентів». За тиждень з’ясувалося, що постачальник видає…
Обговоримо проєкт?
Напишіть нам, і ми найближчим часом зв’яжемося з Вами для обговорення деталей Вашої ідеї.
Круті проєкти починаються з заповнення цієї форми.

    * Обов'язково до заповнення