IOSOR Guias

Webhook duplicado não deve gerar um segundo débito

Caminho de falha: tentativas e replays permanecem idempotentes no saldo pré-pago e na caixa de entrada — um ID de evento, uma linha de débito, uma linha na caixa.

A entrega pelo menos uma vez vai tentar novamente. Um webhook duplicado que envia um segundo débito ou uma segunda linha de caixa é un incidente de dinheiro e operações, não um «ack inofensivo». Esta página é o caminho de falha: tentativas e replays mantêm a idempotência no saldo pré-pago e na caixa — não o ensaio de idempotencia de envio de API e nem o playbook de repetição de SMS de entrada.

Relacionado: Portão de assinatura e janela de replay, Contrato de webhook antes do primeiro envio, linhas de débito e estado de entrega no mesmo ledger.

A IOSOR é pré-paga de marca branca.

A idempotência é um caminho de falha, não um slogan

Caminho feliz: um evento assinado, um aceito, um débito. O caminho de falha destrói a confiança — timeout, 5xx, replay do provedor, reenvio do operador. Armazene a chave de idempotência do Contrato de webhook antes do primeiro envio antes dos efeitos colaterais: ledger, caixa, CRM.

O que conta como uma duplicata

Signal Tratar como duplicata quando Resultado seguro
ID de evento Mesmo ID já aceito na janela ACK; sem segundo débito
ID de mensagem Mesma mensagem já vinculada ao ledger Reutilizar linha; sem nova cobrança
Chave de caixa Mesmo MO/MT já arquivado Sem segunda linha na caixa
Fora da janela Tentativa obsoleta após rejeição Rejeitar; sem escrita de dinheiro/status
Tipo desconhecido Fora da lista do contrato Descartar;

O dinheiro não deve se mover duas vezes

Um segundo débito para o mesmo ID de evento é um bug, mesmo que o produto «ainda mostre entregue». O financeiro filtra por evento ou ID de mensagem e vê uma linha pré-paga para essa janela UTC. Efeitos colaterais parciais após o ACK — CRM primeiro, ledger depois — fabricam uma verdade dupla. Se o processamento falhar após a persistência, repita o worker na mesma chave; não reaceite o corpo HTTP como uma nova cobrança.

A caixa de entrada também não deve duplicar

Idempotência não é apenas dinheiro. Um evento de entrega ou entrada repetido que abre um segundo thread de caixa treina o suporte a caçar fantasmas e pode disparar loops de resposta automática. Armazene a chave da caixa com o mesmo ID de evento usado para o débito. Produto e finanças compartilham rejeição e duplicação.

Lista de verificação do comprador para webhooks seguros contra duplicatas

Exija que seu provedor confirme o armazenamento da chave de idempotência antes do efeito colateral. Verifique se falhas de rede não geram um segundo débito na mesma janela UTC. Exija que as tentativas retornen o mesmo ACK armazenado sem tocar no saldo. Teste com USD 20 antes de escalar para volumes maiores.

Comece com a IOSOR

Force um replay assinado dentro da janela num corredor que já debitou. Exporte o event id ao lado do id do ledger e prove uma só linha de débito e uma só linha de caixa de entrada. Se surgir um segundo débito, pare esse consumidor e reembolse a linha a mais — não a liquide com tráfego posterior. Esta porta é dinheiro de replay, não uma verificação E.164 nem um texto de envio.

Conclusão IOSOR

Um replay não é um envio novo. Um event id escreve um débito.

Faça: mantenha assinatura e janela de replay, depois prove um débito após um POST dentro da janela. Não faça: debitar cada POST, nem tratar um retry de rede como segunda fatura.

Este guia foi útil?

Guias relacionados