СтатьяИИАналитика

Почему webhook создаёт два заказа в CRM и как защитить интеграцию

Как разделить доставку события и создание заказа, выбрать ключи защиты от дублей и проверить повторы, параллельную обработку и сетевые сбои.

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

В интернет-магазине один оплаченный заказ, а в CRM появились две сделки. Прежде чем искать вторую покупку, проверьте доставку webhook: уведомление о том же событии могло прийти повторно, и интеграция выполнила создание ещё раз.

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

Как повтор превращается во второй заказ

Учебный сценарий: магазин отправил событие об оплате. Обработчик создал заказ в CRM, но отправитель не получил ответ вовремя. Он повторил доставку. Если обработчик каждый раз без проверки вызывает «создать заказ», появится вторая запись. Это пример устройства ошибки, а не история реального магазина.

Повторы предусмотрены в конкретных системах: Stripe описывает повторные доставки и отсутствие гарантии порядка событий, а Shopify — дубли после таймаута или повторной отправки. Правила и сроки повторов нужно читать у поставщика вашей интеграции.

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

Разделите событие и бизнес-операцию

Для разбирательства нужны два ключа.

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

Ключ операции отвечает на вопрос, выполняли ли вы конкретное действие с конкретным объектом. Например, shop-1:order-4821:create-crm-order — учебный ключ создания заказа. Для возврата или отдельной отгрузки потребуется своё правило идентификации.

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

Названия полей тоже различаются. В документации Shopify X-Shopify-Webhook-Id используется для распознавания повторной доставки; X-Shopify-Event-Id связывает доставки одного действия продавца, в том числе через разные подписки. Зафиксируйте в ТЗ, какое поле читает ваша интеграция.

Успешный HTTP-ответ и выполненная операция

Отправитель видит ответ вашего endpoint. В Shopify 200 OK подтверждает получение webhook; документация также предлагает очередь для последующей обработки. Из этого следует практическое разделение: статус доставки и результат создания записи в CRM нужно хранить отдельно.

Рабочая схема для обсуждения с разработчиком: проверить подлинность запроса, надёжно сохранить событие и задачу, затем быстро ответить отправителю. Обработчик очереди выполняет операцию и записывает результат. Если очередь живёт только в памяти, подтверждённое уведомление можно потерять при остановке процесса.

Схема: событие сначала проверяется и надёжно сохраняется; ответ 2xx подтверждает приём. Отдельный обработчик выполняет операцию, затем фиксирует completed и ID заказа. Повтор обращается к сохранённой задаче.

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

Состояние задачи должно позволять восстановление

Запись «событие получено» не равна записи «действие выполнено». Если сохранить ID как обработанный до вызова CRM, а вызов завершится ошибкой, простой фильтр повторов может заблокировать восстановление.

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

Проверки «сначала найти, потом создать» недостаточно

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

Например, PostgreSQL поддерживает уникальность группы колонок. Для обязательных частей ключа задайте запрет пустого значения: обычное ограничение UNIQUE допускает особенности сравнения NULL. Конкретную схему выбирает разработчик.

Если изменения происходят в одной базе, транзакция объединяет их в одну операцию: изменения подтверждаются вместе или откатываются. Но вызов внешней CRM обычно находится за границей такой транзакции.

Если CRM создала заказ, а ответ потерялся, ищите результат по внешнему ключу либо повторяйте запрос через поддерживаемый механизм идемпотентности. Идемпотентность означает, что повтор того же действия не создаёт дополнительный эффект. Например, Stripe API позволяет повторять запрос с сохранённым ключом. Это отдельный механизм от распознавания входящего webhook; его наличие и срок хранения ключа проверяют у принимающей системы.

Что включить в приёмку интеграции

Следующие проверки — редакционный регламент для тестовой среды. Они не означают, что интеграция вашего магазина уже протестирована.

ПроверкаОжидаемый результат
Повторить одно событиеОдин заказ и одна задача на его создание
Доставить две копии одновременноДва обработчика не создают два заказа
Остановить обработку после сохранения событияЗадача восстанавливается, событие не исчезает
Потерять ответ после создания заказа в CRMСистема находит созданный результат или безопасно повторяет действие
Отправить отдельное событие возвратаДопустимый возврат не подавляется как дубль заказа
Передать события в обратном порядкеСтарое уведомление не откатывает актуальное состояние

В журнале интеграции сохраняйте источник, ID события, ключ операции, время приёма, попытку обработки, результат и ID записи в CRM. Для суммы храните валюту отдельным полем; для белорусского магазина базовая валюта — BYN. Полные платёжные реквизиты и лишние данные клиента для такой сверки не нужны.

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

Как поставить задачу команде

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

Материал рассчитан на уже работающую интеграцию магазина и CRM в Беларуси или другом регионе. Документация международных платформ используется как пример поведения webhook; подключать эти сервисы для выполнения проверки не требуется.

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

Источники

Материал подготовлен редакцией WiseLab с помощью AI. Источники и фактические утверждения проверены при подготовке.

Загружаем рейтинг…

Насколько полезен материал?

Выберите оценкуСлева — меньше пользы, справа — больше

Загружаем вашу оценку…

Что думаете?

Загружаем комментарии…

СЛЕДУЮЩИЙ ШАГ

Что ещё поможет в этой задаче