O cliente clica em pagar. A aplicação envia a cobrança. O tempo limite estoura.
Na interface, nada aconteceu. No provedor, talvez tenha acontecido tudo.
Esse é um cenário ilustrativo, mas a diferença que ele expõe é concreta: não receber a resposta não prova que a operação deixou de ser executada.
Se o sistema enviar imediatamente outra cobrança por outro caminho, uma recuperação pode se transformar em duplicidade.
Primeiro, separe o que você sabe
Uma falha de validação antes do envio é diferente de uma resposta perdida depois do processamento.
Uma recusa definitiva é diferente de um provedor temporariamente indisponível.
E um pagamento pendente não deve ser convertido em falha só porque sua tela precisa apresentar alguma mensagem.
Essas situações podem parecer iguais quando todas chegam ao mesmo bloco de tratamento de erro. Na operação financeira, pedem decisões diferentes.
| Situação | O que ela informa | Próxima decisão |
|---|---|---|
| Requisição rejeitada antes da execução | A operação não passou naquela etapa | Corrigir o motivo antes de reenviar |
| Recusa definitiva | Há uma negativa que não deve ser contornada por troca de provedor | Seguir o tratamento permitido para a recusa |
| Falha elegível com resultado conhecido | Pode existir espaço para recuperação | Avaliar outra rota compatível |
| Timeout ou resultado desconhecido | Falta saber se houve execução | Recuperar estado antes de iniciar cobrança independente |
Classificar não é um detalhe do log. É o que impede que a mesma palavra, “erro”, autorize ações incompatíveis.
Repetir a chamada não precisa criar outra operação
Dentro de uma integração que oferece idempotência, uma repetição da mesma intenção pode reutilizar a chave e os parâmetros originais, respeitando o contrato e o prazo de retenção daquele serviço.
A documentação da Stripe, por exemplo, trata erros de rede como situações em que o cliente pode não saber se a requisição chegou ao servidor e orienta a repetição idempotente. Isso não é autorização para criar uma cobrança nova em outro provedor. Tratamento de erros de baixo nível.
Uma chave não é uma trava distribuída entre empresas diferentes. Se dois provedores recebem duas ordens independentes, usar o mesmo texto como chave não os faz compartilhar conhecimento sobre a compra.
Um caminho de recuperação precisa terminar em estado
Para uma operação de resultado desconhecido, preserve a identidade da compra e as referências da tentativa. Consulte o estado pelo caminho suportado. Processe os eventos que chegarem. Se a ambiguidade persistir, mantenha o caso identificável para reconciliação e intervenção.
A interface também precisa participar: “estamos confirmando seu pagamento” é diferente de um convite para clicar de novo.
Bloquear um segundo clique ajuda, mas não substitui uma proteção no servidor. A mesma compra pode chegar por duas abas, por um job e pelo navegador, ou por uma repetição após uma queda.
Depois da confirmação, liberar acesso também precisa ser idempotente. Evitar uma segunda cobrança e evitar uma segunda concessão de crédito são responsabilidades relacionadas, mas distintas.
Fallback tem condição de entrada
Na Infi, fallback é limitado a falhas elegíveis e rotas compatíveis. Resultado desconhecido não deve ser tratado como convite para trocar de provedor; recusas definitivas não são reenviadas a outro para tentar contorná-las. Infi Routing.
Para investigação, pagamentos por fatura e registros de entrega de webhook ajudam a separar execução de pagamento e comunicação com a aplicação. Os logs do seu produto completam o caminho até o acesso concedido. SDK da Infi.
A pergunta depois de um timeout não é “para onde tentamos agora?”.
É “o que aconteceu com a tentativa que já existe?”.