Como tornar um webhook de pagamento ou WhatsApp idempotente?
Share

In this article
Associe cada webhook a um ID único fornecido pelo remetente, como um ID de pedido ou ID de mensagem, e execute seus efeitos colaterais apenas uma vez. Uma entrega repetida encontra o ID já processado e não faz nada. Publique o trabalho real em uma fila em vez de executá-lo inline, para que o remetente não fique esperando.
Por que os webhooks chegam mais de uma vez?
Os remetentes tentam novamente em casos de timeout, falhas na rede e respostas que não sejam 2xx, preferindo entregar duas vezes a não entregar nenhuma. Gateways de pagamento e o WhatsApp fazem isso. Um manipulador que age em cada entrega pode emitir tickets duplicados, enviar confirmações de reserva em dobro ou cobrar duas vezes.
Qual deve ser a chave de idempotência?
Use o identificador que o remetente garante ser estável entre as tentativas: o ID do pedido para webhooks de pagamento, o ID da mensagem para WhatsApp. Armazene as chaves processadas e verifique antes de agir. Uma chave gerada por você para cada entrega não funciona, pois cada tentativa pareceria um evento novo.
Por que publicar em uma fila em vez de fazer o trabalho no manipulador?
Gerar um ticket e enviar um e-mail inline faz o gateway esperar por um trabalho que ele não precisa, o que pode causar timeouts e mais tentativas. Reconheça rapidamente, publique um evento de pagamento confirmado no RabbitMQ e deixe um consumidor executar o trabalho. Uma entrega repetida publica uma vez; a segunda é uma operação sem efeito.
Onde isso é usado em produção?
No FindYourVibe, o webhook de pagamento é idempotente com base no ID do pedido e publica no RabbitMQ antes que um consumidor emita o ticket. No Trexind, cada manipulador de webhook do WhatsApp é idempotente com base no ID da mensagem, então uma entrega repetida atualiza o estado uma vez em vez de reativar efeitos colaterais de reserva ou cobrança.
Como testar se um webhook é idempotente?
Envie o mesmo payload duas vezes, idealmente simultaneamente, e verifique se o efeito colateral ocorreu apenas uma vez: um ticket, uma reserva, uma cobrança. Depois, reenvie um payload antigo após o primeiro ter sido totalmente processado. Se algum contador estiver acima de um, a verificação da chave está com condição de corrida ou falta uma restrição única.
Publicado originalmente em sakshamjain.codes/blog/idempotent-payment-and-whatsapp-webhooks. Precisa disso implementado? Veja meus serviços em NexoRush ou envie uma mensagem.