Pular para o conteúdo principal
Um aspecto fundamental da confiabilidade do Midaz é garantir que as operações sejam seguras para retentativa e nunca processadas mais de uma vez. Seja ao lidar com transações ou criar entidades, sua integração deve ser resiliente, mesmo diante de falhas de rede, timeouts ou interrupções temporárias. Esta página explica como o Midaz protege contra duplicações usando chaves de idempotência, e como você pode implementá-las para lidar com retentativas no seu sistema com confiança.

Tornando as retentativas seguras

Em sistemas reais, falhas em requisições de API são comuns. Talvez ocorra um timeout de rede. Talvez seu serviço caia logo após enviar uma requisição. Nesses casos, é natural tentar novamente, mas como você pode ter certeza de que o Midaz não processará a mesma operação duas vezes? É aí que as chaves de idempotência entram em ação. Ao anexar uma chave única a cada requisição, você está dizendo ao Midaz: “Esta é a mesma operação. Se você já a processou, não faça novamente.” O Midaz armazena essa chave temporariamente e a utiliza para determinar se a requisição é nova, já foi concluída ou ainda está sendo processada. Isso protege seu sistema contra duplicatas enquanto oferece controle total sobre sua estratégia de retentativa.

Idempotência no Midaz


O Midaz usa chaves de idempotência para garantir que as operações de transação sejam seguras para retentativa e nunca processadas mais de uma vez. Este mecanismo está disponível em todos os endpoints de transações: /transactions/json, /transactions/dsl, /transactions/inflow, /transactions/outflow, /transactions/annotation e /transactions/{id}/revert.
Outros produtos da Lerian também suportam idempotência através de seus próprios headers — veja a seção Idempotência nos produtos Lerian abaixo. Esta página foca na idempotência para a API do Midaz Ledger.
Os endpoints commit e cancel de transações usam um lock baseado em Redis para prevenir processamento concorrente da mesma transação, mas não suportam idempotência completa (sem respostas em cache ou header X-Idempotency-Replayed).
Para usá-lo, sua requisição pode incluir dois headers:
  • X-Idempotency: a chave única que identifica a requisição.
  • X-TTL: o tempo de vida (em segundos) que o Midaz deve armazenar essa chave em cache.
Se você não enviar o header X-Idempotency, o Midaz gera um automaticamente calculando um hash SHA-256 do corpo da requisição. Isso significa que corpos de requisição idênticos enviados para a mesma organização e ledger são automaticamente deduplicados.
Veja o que acontece nos bastidores:
  1. Quando uma nova chave chega, o Midaz a marca como pending, processa a requisição e armazena a resposta completa em cache.
  2. Se a mesma chave for usada novamente dentro da janela de TTL:
    1. Se a operação ainda estiver em execução, o Midaz retorna um 409 Conflict (código de erro 0084) com X-Idempotency-Replayed: false.
    2. Se estiver concluída, o Midaz retorna exatamente a mesma resposta com código de status 201 Created e X-Idempotency-Replayed: true.
  3. Se a transação falhar por erros de validação ou saldo insuficiente, o Midaz deleta a chave de idempotência, permitindo que você retente com a mesma chave após corrigir o problema.
No Midaz, as chaves de idempotência são escopadas por organização e ledger. Isso significa que o mesmo valor de chave pode ser usado independentemente em diferentes organizações ou ledgers sem conflito. Outros produtos da Lerian utilizam estratégias de escopo diferentes — consulte a tabela comparativa para mais detalhes.

Resumo do fluxo

A Figura 1 mostra o ciclo de vida completo de uma requisição idempotente:
Ciclo de vida completo de uma requisição idempotente no Midaz, da recepção da chave de idempotência até o retorno da resposta em cache ou recém-processada

Figura 1. Ciclo de vida de uma requisição idempotente no Midaz.

Como funciona:
  • Se a requisição não incluir uma chave de idempotência existente, o Midaz cria uma nova (ou gera uma automaticamente a partir do hash do corpo da requisição), processa a requisição, armazena a resposta e a retorna com X-Idempotency-Replayed: false.
  • Se a chave já existir:
    • Se a operação ainda estiver em execução, o Midaz retorna um 409 Conflict com X-Idempotency-Replayed: false.
    • Se a operação estiver concluída, o Midaz ignora a execução e retorna a resposta em cache com código de status 201 Created e X-Idempotency-Replayed: true.
  • Se a requisição original falhou por erros de validação ou saldo, a chave é limpa automaticamente, permitindo que você retente com a mesma chave de forma segura.
Esse comportamento garante que cada requisição seja tratada de forma segura, previsível e sem duplicação, mesmo quando retentada.

Exemplo de requisição

Veja como enviar uma requisição idempotente para criar uma transação:
Se a requisição for bem-sucedida e você enviá-la novamente dentro de 60 segundos, o Midaz retornará o resultado em cache com:
Se você enviá-la novamente enquanto a original ainda estiver sendo processada, você receberá:

Geração de chaves


Você pode fornecer sua própria chave X-Idempotency ou deixar o Midaz gerar uma automaticamente.

Geração automática de chaves

Se você omitir o header X-Idempotency, o Midaz calcula um hash SHA-256 do corpo da requisição e o usa como chave de idempotência. Isso significa que enviar o mesmo corpo JSON exato para a mesma organização e ledger será automaticamente deduplicado — sem trabalho adicional. Isso é suficiente para a maioria dos cenários de retentativa onde o corpo da requisição não muda entre tentativas.

Geração personalizada de chaves

Use uma chave personalizada quando precisar:
  • Correlacionar a chave de idempotência com um ID no seu próprio sistema (ex: um ID de pedido).
  • Retentar com um corpo de requisição modificado e ainda assim deduplicar (ex: após corrigir um campo).
  • Controlar o formato da chave para fins de log ou auditoria.
A chave deve ser determinística: se a mesma operação lógica for retentada, a chave permanece a mesma. Uma abordagem comum é usar um UUID ou um hash baseado na sua referência interna:

Boas práticas


Sempre valide o header X-Idempotency-Replayed

Quando seu sistema recebe uma resposta de um endpoint de transação, sempre verifique o header de resposta X-Idempotency-Replayed antes de processar o resultado. Esse header indica se a resposta é de uma operação nova ou um replay do cache:
  • X-Idempotency-Replayed: false — Esta é uma resposta nova. A transação acabou de ser processada.
  • X-Idempotency-Replayed: true — Esta é uma resposta em cache. A transação já foi processada anteriormente.
Não verificar esse header é um erro de integração comum. Sem ele, seu sistema pode interpretar uma resposta repetida como uma nova transação, levando a processamento duplicado do seu lado — mesmo que o Midaz tenha executado apenas uma vez.
Por exemplo, se seu sistema liquida boletos com base nas respostas de transação, você deve verificar X-Idempotency-Replayed para evitar liquidar o mesmo boleto duas vezes.

Use chaves de idempotência explícitas para fluxos críticos

Embora o Midaz gere chaves automaticamente a partir do corpo da requisição, para fluxos financeiros críticos (liquidações, pagamentos, transferências), sempre forneça uma chave X-Idempotency explícita vinculada ao ID do seu processo de negócio. Isso oferece:
  • Controle total sobre a deduplicação, mesmo se o corpo da requisição mudar ligeiramente entre retentativas.
  • Um rastro de auditoria claro vinculando as transações do Midaz às suas operações internas.
  • Proteção contra casos extremos onde a serialização da requisição pode diferir.

Defina valores de TTL apropriados

Escolha valores de TTL que correspondam à sua janela de retentativa:
  • Para operações síncronas com retentativas rápidas: 60–120 segundos.
  • Para fluxos assíncronos com possíveis atrasos: 300–600 segundos.
  • Para processamento em lote com janelas de retentativa longas: considere TTLs maiores e chaves explícitas.

Estratégia de retentativas


Quando uma requisição falha, como você retenta é importante. Aqui estão os padrões recomendados para lidar com diferentes cenários de falha:

Falhas retentáveis

Estas falhas são seguras para retentar com a mesma chave de idempotência:

Falhas não retentáveis

Estas falhas requerem uma abordagem diferente:

Backoff exponencial

Para erros transitórios, use backoff exponencial com jitter para evitar sobrecarregar o servidor:
Uma sequência típica de retentativas com esse padrão seria: 1s, 2s, 4s, 8s, 16s (mais jitter aleatório em cada tentativa).

Prevenindo duplicação de entidades


Para alguns endpoints, você não precisa de chaves de idempotência para evitar duplicação. O Midaz aplica restrições de unicidade em recursos críticos. Se você tentar criar uma entidade que conflite com uma existente, o sistema bloqueia a requisição e retorna um 409 Conflict com um erro descritivo: Isso garante que seus dados permaneçam limpos, sem ambiguidade e fáceis de gerenciar, mesmo quando vários serviços estão operando em paralelo ou quando retentativas ocorrem automaticamente. Diferente das chaves de idempotência, essas restrições são permanentes e não expiram.

Idempotência nos produtos Lerian


Múltiplos produtos da Lerian suportam idempotência, cada um com sua própria convenção de headers. A maioria dos produtos retorna o header de resposta X-Idempotency-Replayed para indicar se a resposta é um replay do cache. O Midaz sempre inclui este header (false para requisições novas, true para replays), enquanto os demais serviços só o adicionam quando a resposta é um replay — se o header estiver ausente, a requisição foi processada como nova. O Pix Direto não retorna este header.
O Midaz sempre inclui o header X-Idempotency-Replayed na resposta (false para requisições novas, true para replays). Os demais serviços (Matcher, TED, Indirect Pix e Reporter) só adicionam este header quando a resposta é um replay — se o header estiver ausente, a requisição foi processada como nova. O Pix Direto não retorna este header; seu middleware de idempotência faz replay da resposta completa de forma transparente, sem um indicador de replay.
Fees Engine, Tracer, Auth e CRM atualmente não suportam headers de idempotência. As validações do Tracer são idempotentes por requestId — POST /v1/validations faz deduplicação pelo campo do body e retorna o resultado em cache com HTTP 200 (HTTP 201 na primeira chamada). As operações de tokens do Auth são inerentemente idempotentes. CRM e entidades de onboarding dependem de restrições de unicidade em vez disso.

FAQ


O Midaz gera uma automaticamente calculando um hash SHA-256 do corpo da requisição. Isso significa que corpos de requisição idênticos enviados para a mesma organização e ledger são automaticamente deduplicados. Você só precisa fornecer uma chave personalizada se quiser controlar a deduplicação independentemente do corpo da requisição.
Sim. As chaves de idempotência são escopadas por organização e ledger, então o mesmo valor de chave usado em diferentes organizações ou ledgers não entrará em conflito. Porém, dentro da mesma organização e ledger, cada chave deve ser única por operação.
No Midaz, as chaves de idempotência são escopadas por organização e ledger, não por endpoint. Se você reutilizar a mesma chave em um endpoint diferente dentro da mesma organização e ledger, receberá a resposta em cache do endpoint original. Sempre use chaves únicas para cada operação distinta.
Apenas o TTL da primeira requisição é utilizado. Alterá-lo depois não tem efeito.
Sim. O Midaz repete a resposta completa, incluindo código de status (201 Created), headers e corpo, para requisições concluídas.
A janela padrão é de 300 segundos (5 minutos).
Se a transação falhar por erros de validação ou saldo insuficiente, o Midaz deleta a chave de idempotência do cache. Isso permite que você corrija o problema e retente com a mesma chave.