Сайт принял заявку, но в CRM её нет. Или заявка появилась дважды после повторной отправки. Такие ситуации показывают разницу между первым успешным запросом и работающей интеграцией. Команда Гуси-Лебеди объясняет, как соединить системы через API, согласовать данные и проверить результат после задержек и сбоев.
Разберём учебный обмен между сайтом и CRM. Названия полей и сценарии ниже условные: это пример проектирования, а не инструкция к API конкретного поставщика.
Что такое API-интеграция и как она работает

API задаёт интерфейс, через который одна программа обращается к другой. Интеграция использует этот интерфейс для рабочего процесса: передать заявку, обновить остаток товара, получить статус доставки или показать заказ в личном кабинете. Пользователю не нужно переносить одну и ту же запись вручную.
В HTTP API программа отправляет запрос по определённому адресу. Метод, заголовки и тело запроса описывают действие и данные. Принимающая система проверяет доступ, обрабатывает запрос и возвращает ответ. Что именно означает ответ, определяется документацией метода.
REST API и webhook решают разные части обмена. Через API ваша система может запросить или изменить данные. Webhook позволяет другой системе прислать уведомление о событии на ваш адрес. В одном процессе могут использоваться оба способа. Выбор зависит от доступных интерфейсов и допустимой задержки.
До разработки опишите проверяемый результат: каждое принятое сайтом обращение либо связано с записью CRM, либо имеет видимое состояние ошибки. Фраза «подключить CRM» не определяет, что делать с повтором, потерей ответа и недоступностью сервиса.
Успешный HTTP-код нельзя автоматически считать завершением всего процесса. Например, 202 означает принятие запроса к обработке, а не её окончание. Семантика кодов описана в стандарте HTTP; бизнес-результат проверяйте по контракту конкретного API и записи в целевой системе.
Как подготовить данные, документацию и доступ

Начните с документации поставщика: методы, авторизация, схема данных, ограничения, версии и тестовая среда. Получение ключа и выполнение пробного запроса позволяют проверить доступ, но ещё не подтверждают правильность бизнес-логики.
Для каждого поля определите источник, целевое значение, тип, обязательность и преобразование. Пустая строка, null и отсутствие поля могут означать разные вещи. Не превращайте пропущенное поле в команду очистить существующую запись без явного правила.
| Учебное поле | Правило | Контроль |
|---|---|---|
| request_id | Устойчивый ID обращения на сайте | Не меняется при повторе |
| service_code | Код согласованного справочника | Неизвестное значение не заменяется произвольным |
| created_at | Время с определённым часовым поясом | Обе системы одинаково читают дату |
| contact | Необходимые контактные данные | Валидация и ограничение доступа |
| crm_id | ID результата в CRM | Хранится отдельно от локального ID |
Суммы передавайте с валютой и согласованной точностью, количество с единицей измерения. Строка «10» без контекста не сообщает, что это рубли, копейки или число товаров. Корректный JSON может содержать неправильную бизнес-информацию.
Назначьте владельца данных. В учебном примере сайт хранит исходное обращение, а CRM управляет статусом работы менеджера. Для двустороннего обмена нужны правила конфликтов и версий, иначе системы способны бесконечно перезаписывать изменения друг друга.
При разработке интеграции между сервисами согласуйте контракт и правила его изменения. Используйте отдельный доступ с нужными полномочиями. Серверный секрет не должен попадать в клиентский JavaScript, публичный репозиторий или URL. В диагностике сохраняйте ID операции и безопасное описание ошибки, не записывайте по умолчанию полные тела с токенами и контактами.
Как повторять запросы и не создавать дубли

Представьте: CRM создала запись, но ответ потерялся в сети. Сайт видит тайм-аут. Если просто повторить создание, может появиться вторая заявка. Тайм-аут сообщает об отсутствии полученного ответа, а не доказывает, что операция не выполнилась.
Защиту от такого повтора называют идемпотентностью. Одно бизнес-действие получает устойчивый ключ. Повтор той же операции должен распознаваться и давать согласованный результат без второго создания. Ключ относится к операции, а не к каждой попытке её доставки.
Некоторые API предусматривают такой механизм. Например, Stripe описывает идемпотентные запросы и правила повторов с одним ключом. Эти правила принадлежат конкретному API. Нельзя предполагать, что такой же заголовок и срок хранения действуют у вашей CRM.
Если готового механизма нет, проверьте поддержку внешнего ID, поиска результата и уникальных ограничений. Простая последовательность «проверить наличие, затем создать» без защиты от параллельных запросов может оставить гонку. Способ предотвращения дублей нужно выбрать до запуска повторной обработки.
| Ситуация | Что выяснить | Следующее действие |
|---|---|---|
| Данные не проходят проверку | Какое поле нарушает контракт | Исправить запись, не повторять бесконечно |
| Доступ отозван | Состояние полномочий и учётных данных | Остановить бесполезные попытки и дать сигнал |
| Ограничена частота запросов | Правило ожидания из документации | Снизить нагрузку и отложить допустимый повтор |
| Тайм-аут после отправки | Могла ли операция выполниться | Найти результат или повторить с защитой от дублей |
| Временный отказ сервера | Допустим ли повтор этой операции | Ограничить попытки и соблюдать задержки |
Политику повторов определяйте по типу ошибки и контракту. Задайте предел попыток и путь ручного разбора. Бесконечный повтор неправильных данных только увеличивает нагрузку и прячет проблему.
Зачем интеграции очередь и понятные статусы

Если внешняя система недоступна, принятая сайтом заявка не должна исчезнуть. Один из подходов состоит в сохранении обращения и задания на передачу, после чего отдельный обработчик выполняет обмен. Пользователь получает честный статус, а временная недоступность CRM не уничтожает исходные данные.
Продумайте границу сохранения. Если заявка сохранена, а задание на отправку не создано, очередь о ней не узнает. Нужен согласованный способ сохранять данные и намерение отправки без такого пропуска. Конкретная реализация зависит от хранилища и архитектуры.
Разделяйте состояния: принято сайтом, ожидает передачи, отправлено, подтверждено в CRM, требует разбора. Не называйте результат подтверждённым только потому, что обработчик начал запрос. Храните локальный ID, ID результата и номер попытки.
Проверьте перезапуск между отправкой и подтверждением. Обработчик должен восстановить работу и распознать уже выполненную операцию. Очередь сама по себе не гарантирует отсутствие дублей: она дополняет правила идемпотентности и подтверждения результата.
Для сопровождения полезны возраст самого старого задания, число ожидающих операций, окончательные ошибки и время последнего успешного обмена. Это помогает отличить нормальное ожидание от остановившегося процесса.
Как обрабатывать webhook и изменения статусов

Webhook сообщает о событии во внешней системе. Перед обработкой проверяйте его подлинность способом, предусмотренным поставщиком. Сохраните событие устойчиво и только затем подтверждайте получение в соответствии с контрактом. Если подтвердить приём раньше сохранения, сбой может лишить вас уведомления.
Учитывайте повторную доставку и порядок событий. В документации webhook Stripe прямо описаны дубли и отсутствие гарантии порядка. Для своего сервиса проверьте аналогичные условия, а не переносите их автоматически.
ID события и ID объекта нужны для разных проверок. Первый помогает распознать повтор уведомления, второй связывает изменение с бизнес-записью. Два различных события об одной сделке нельзя просто считать дублями по ID сделки.
Учебная ситуация: обновление версии 8 со статусом «в работе» пришло раньше версии 7 «новая». Позднее старое сообщение не должно откатывать состояние. Используйте надёжную версию, если её предоставляет источник. В другом контракте может понадобиться перечитать актуальную запись через API. Время получения сообщения не заменяет время изменения объекта.
После восстановления сервиса проведите сверку. Уведомление могло не прийти вообще, и отсутствие ошибок в журнале этого не покажет. Сравните объекты, которые должны быть переданы, с подтверждёнными результатами. Для списков и пагинации соблюдайте правила API, чтобы изменения во время выгрузки не создавали пропуски.
Как проверить API-интеграцию перед запуском

Проверяйте не только нормальный путь, но и исключения. В согласованной тестовой среде подготовьте контрольные записи и заранее определите ожидаемый результат каждого сценария.
- Обычная заявка создаёт один результат, связь идентификаторов сохранена.
- Повтор одного запроса не создаёт второй бизнес-объект.
- Потерянный ответ после создания не приводит к дублю.
- Недоступность CRM оставляет обращение сохранённым и видимым.
- Отзыв доступа вызывает понятный сигнал.
- События в обратном порядке не откатывают актуальный статус.
- Перезапуск обработчика не теряет задание.
- Сверка обнаруживает пропуск и позволяет исправить его контролируемо.
Для каждого случая пройдите от исходной записи до объекта в целевой системе. Проверьте поля, статусы и журнал попыток. Сообщение «запрос выполнен» не заменяет такую проверку. После тестирования проведите ограниченный безопасный сценарий в производстве и прочитайте фактический результат.
В приёмку включите инструкцию восстановления, ответственных и контроль качества обмена. Связь с отчётами разобрана в статье о сквозной аналитике: потеря заявки способна исказить показатели рекламы. Интеграцию можно считать работающей, когда команда понимает её состояния и может восстановить правильные данные после сбоя.
