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 .

Гейт підпису й вікна replay.

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

  1. Форму idempotency key узгоджено в контракті й збережено до side effects?
  2. Дублікат in-window event ID → ACK без другого debit?
  3. Той самий message ID ніколи не відкриває другий prepaid-рядок ledger?
  4. Inbox insert з тим самим ключем — немає другого thread на replay?
  5. Signature fail і window reject рахуються окремо від true duplicates?
  6. Розмова 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.

Чи був матеріал корисним?

Пов’язані гіди