Дубли сервисных SMS возникают, когда одно и то же событие — например, смена статуса заказа или подтверждение оплаты — обрабатывается системой дважды. Клиент получает два одинаковых сообщения, доверие падает, поддержка получает лишние обращения. В статье разберём, почему это происходит и как за несколько шагов настроить защиту от повторных уведомлений с помощью ключей идемпотентности. Вы получите практический чек-лист, который подойдёт даже небольшому интернет-магазину.
Почему клиент получает два одинаковых SMS?
Чаще всего виновата не злая воля, а технический сбой или неаккуратная ручная отправка. Менеджер дважды нажал кнопку «Отправить», CRM повторно отправила вебхук, скрипт перезапустился после ошибки — и событие ушло в шлюз ещё раз. Иногда повторный запрос приходит из-за таймаута: система не получила подтверждение от оператора и решила, что сообщение потеряно, а оно уже доставлено.
В Беларуси к этому добавляются особенности доставки: сообщение может идти дольше обычного, а ответ от оператора — приходить с задержкой. Если ваша система настроена на «переотправку по таймауту», дубль почти гарантирован. Подробнее о том, почему уведомления задерживаются, мы разбирали в отдельном материале о статусах заказов в Беларуси.
Что такое идемпотентность и как она помогает?
Идемпотентность — это свойство операции, при котором повторное выполнение даёт тот же результат, что и первое. Применительно к SMS это значит: какое бы количество раз ни пришло событие, клиент получит только одно сообщение.
Технически это реализуется через уникальный ключ. Например, для уведомления о смене статуса заказа ключом будет связка «номер заказа + новый статус». Для оплаты — «номер платежа». Перед отправкой система проверяет, отправляла ли она уже сообщение с таким ключом. Отправляла — пропускает. Нет — отправляет и сохраняет ключ в базу или кэш.
Ключ не должен быть просто номером телефона: с одного номера у вас много разных событий, и все они будут ошибочно приняты за одно. Нужна именно комбинация, которая однозначно определяет событие.
Чек-лист: как настроить защиту от дублей
- Добавьте в таблицу отправленных SMS поле unique_key — строку вида
order_12345_shippedилиpayment_9876. - Перед вызовом SMS-шлюза проверяйте, существует ли уже запись с таким ключом.
- Отправляйте сообщение и только после успешного ответа оператора записывайте ключ.
- Если ответа нет — не отправляйте повторно автоматически. Поместите запись в очередь на ручную проверку. Альтернатива — настроить переотправку с проверкой статуса предыдущего сообщения через API.
- Ведите журнал всех попыток с указанием ключа, времени и результата. Это поможет быстро найти источник сбоя.
Если вы используете готовую платформу (CRM, скрипт интернет-магазина), проверьте, есть ли в ней встроенный механизм идемпотентности. У многих популярных решений он уже есть, но бывает выключен по умолчанию. Включите его и укажите, какое поле считать ключом события.
Сравнение подходов: база данных vs кэш
| Критерий | База данных | Кэш (Redis, Memcached) |
|---|---|---|
| Надёжность | Высокая, данные не теряются | Средняя, при перезапуске кэш может очиститься |
| Скорость | Ниже на больших объёмах | Высокая |
| Простота внедрения | Подойдёт для малого бизнеса, нет лишних зависимостей | Требуется отдельный сервис кэширования |
| Срок хранения | Долгий, можно хранить как архив | Ограничен настройками TTL |
Для интернет-магазина с 30–50 заказами в день хватит обычной таблицы в базе данных. Кэш имеет смысл, если у вас тысячи событий в час и вы упираетесь в производительность.
Типичные ошибки при защите от дублей
- Использовать только номер телефона как ключ. Это блокирует все последующие уведомления после первого. Ключ обязан включать идентификатор события.
- Проверять ключ после вызова шлюза. Если ответ пришёл, но запись не сохранилась из-за сбоя, следующий запрос уйдёт повторно.
- Переотправлять при таймауте без проверки. Лучше подождать и запросить статус через API, чем отправить второе SMS.
- Игнорировать распределённые системы. Если у вас два сервера обрабатывают события, нужна блокировка или транзакция, иначе оба пройдут проверку одновременно.
- Не чистить старые ключи. База растёт, но это не страшно. Главное — не забудьте про индекс по полю unique_key, иначе проверка станет медленной.
Как проверить, что защита работает
Создайте тестовый заказ с заведомо повторным событием. Отправьте одно и то же уведомление дважды с интервалом в несколько секунд. Если во втором случае система не отправила SMS — всё настроено правильно.
Также проверьте сценарий, когда от SMS-шлюза не приходит ответ. Запустите отправку, прервите соединение до получения подтверждения, затем повторите попытку. Ваша система должна либо запросить статус, либо отправить сообщение с тем же ключом — и оно должно быть заблокировано.
Если клиент жалуется на пропажу уведомлений, а не на дубли — есть смысл отдельно разобрать как проверить недоставку SMS и что делать в этом случае. Дубли и потери часто соседствуют: одна ошибка может вызывать и то, и другое.
Для более глубокого понимания причин, по которым SMS вообще не доходят до абонента, посмотрите чек-лист по проблемам доставки — он поможет отделить проблему дублей от системных сбоев канала.
3 шага, которые можно сделать сегодня:
- Добавьте поле unique_key в таблицу отправленных сообщений и проставьте индекс.
- Внедрите проверку ключа перед каждым вызовом SMS-шлюза.
- Настройте журнал всех попыток с ключами и результатами — так вы увидите дубли ещё до того, как они дойдут до клиента.


