IOSOR База знань
Дублікат webhook не повинен писати другий debit
Шлях відмови: retries і replays лишаються ідемпотентними для prepaid money та inbox — один event ID, один рядок debit, один рядок inbox.
At-least-once доставка буде ретраїти. Дублікат webhook, який пише другий debit або другий рядок inbox — інцидент money/ops, а не «нешкідливий ACK». Ця сторінка — шлях відмови: retries і replays ідемпотентні для prepaid money та inbox. Це не есе про API send-idempotency і не playbook inbound SMS retry.
Пов’язані: Гейт підпису й вікна replay, Контракт webhook перед першим надсиланням, debit і delivery status в одному ledger.
IOSOR — white-label prepaid. USD 20 фінансує smoke дубліката на одному consumer; soft review близько USD 1 000/міс робить «retry = новий charge» боргом recon. Клієнт бачить лише white-label event ID і слова статусів.
Ідемпотентність — шлях відмови, не гасло
Happy path простий: одна signed подія, один accept, один debit. Шлях відмови спалює довіру — timeout, 5xx, provider replay, ручний re-push. Idempotency key із Контракт webhook перед першим надсиланням зберігають до side effects: ledger, inbox, CRM. Soft USD 1 000/міс вважає «ACK, потім новий ключ» боргом volume; USD 20 доводить: forced replay не подвоює money.
Що вважається дублікатом
| Сигнал | Дублікат, коли | Безпечний наслідок | |
|---|---|---|---|
| Event ID | Той самий ID уже accepted in-window | ACK; немає другого debit | |
| Message ID | Те саме повідомлення вже в ledger | Повторно використати рядок | |
| Inbox key | Той самий MO/MT уже у файлі | Немає другого рядка inbox | |
| Поза вікном replay | Stale retry після gate reject | Reject; немає money/status write | |
| Unknown type | Немає в списку контракту | Drop; немає invented success | . |
Money не повинна рухатися двічі
Другий debit за той самий event ID — баг, навіть якщо product «все ще показує delivered». Finance фільтрує за event/message ID і бачить один prepaid-рядок за UTC-вікно. Часткові side effects після ACK — спочатку CRM, потім ledger — створюють double truth. Якщо processing впав після persist, ретрайте worker за тим самим ключем. Soft volume language blocked, доки smoke не покаже один рядок ledger.
Inbox теж не повинен подвоюватися
Ідемпотентність — не лише money. Replay inbound/delivery, який відкриває другий inbox thread, вчить support ганятися за привидами й може запустити autoreply loops. Зберігайте inbox key з тим самим event ID, що й debit. Product і finance ділять слова reject/duplicate — не hero upstream codes: Спільна мова статусів для product і finance. USD 20 доводить: forced replay не змінює cardinality inbox.
Чекліст покупця: duplicate-safe webhooks
- Форму idempotency key узгоджено в контракті й збережено до side effects?
- Дублікат in-window event ID → ACK без другого debit?
- Той самий message ID ніколи не відкриває другий prepaid-рядок ledger?
- Inbox insert з тим самим ключем — немає другого thread на replay?
- Signature fail і window reject рахуються окремо від true duplicates?
- Розмова soft USD 1 000/міс blocked, доки duplicate smoke червоний?
Будь-яке «ні» тримає duplicate-safe webhook money — і довірений inbox — у draft.
Почніть з IOSOR
У консолі: Duplicate webhook must not second-debit; idempotency key enforced.. Назвіть власника і гейти перед розширенням.
Пов’язане: signature and replay window gate webhook contract before first send.
Підсумок IOSOR
Це ops-дисципліна для зміни—не брошура.
Робіть: name owner + gate. Не: skip the gate.
Чи був матеріал корисним?
Пов’язані гіди
- Моніторинг стану кінцевих точок вебхуків
Дізнайтеся, як відстежувати затримки відповідей та коди стану в IOSOR для запобігання збоям при доставці сповіщень та забезпечення стабільності системи.
- Налаштування вебхуків для контролю порогів балансу
Дізнайтеся, як налаштувати автоматичні сповіщення про баланс в IOSOR для запобігання перервам у сервісі та ефективного керування JIT-виділенням номерів.
- Обробка подій вебхуків для оперативного виділення номерів
Опануйте автоматизацію життєвого циклу каналів через JIT-вебхуки в IOSOR. Налаштовуйте миттєве призначення номерів та керування балансом у вашій CPaaS-платформі.