API de Pedidos e Pagamentos
consistênciaNo arO gateway de pagamento avisa duas vezes que o mesmo pedido foi pago. E se a fila cair logo depois do banco confirmar?
Webhooks de pagamento são entregues “pelo menos uma vez” — a repetição faz parte do contrato, não é falha. Cada evento recebido tem o id registrado numa tabela com restrição de unicidade, na mesma transação que aplica o efeito. A segunda entrega colide ali e é descartada; em teste, doze entregas simultâneas do mesmo evento produzem um único efeito.
O segundo problema é que gravar o pedido e publicar o evento na fila são operações em sistemas diferentes, sem transação comum — qualquer ordem pode deixar um dos lados para trás. Com o padrão outbox, o evento é gravado numa tabela do próprio banco junto com o pedido, e um worker separado cuida da publicação:
POST /webhooks/stripe -- assinatura verificada antes de tudo BEGIN INSERT INTO eventos_processados (evento_id) -- 2ª entrega colide aqui UPDATE pedidos SET status = 'PAGO' INSERT INTO outbox (tipo, payload) -- mesmo commit do pedido COMMIT worker: lê outbox → publica no RabbitMQ → marca entregue consumidor: idempotente, porque a entrega é “pelo menos uma vez”
Troquei a promessa de “entrega exatamente uma vez”, que não existe entre sistemas distribuídos, por “pelo menos uma vez com consumidores idempotentes” — que é como integrações reais funcionam.
- Java 21
- Spring Boot 4
- RabbitMQ
- Stripe
- PostgreSQL
- Testcontainers
- WireMock