Idempotência
Toda requisição de mutação (initiate, process, cancel) requer um cabeçalho
X-Idempotency. Se você enviar a mesma chave duas vezes, o plugin retorna a resposta original sem criar uma operação duplicada.
Regras:
- Use um UUID v4 ou um identificador de negócio único (ex: o ID interno do seu pedido)
- Comprimento máximo: 255 caracteres
- As chaves têm escopo por organização — a mesma chave de duas organizações diferentes é tratada como duas requisições distintas
- As respostas em cache são retornadas por 24 horas
X-Idempotency-Replayed: true quando a resposta é servida do cache.
Detecção de duplicatas
Além das chaves de idempotência, o plugin detecta duplicatas baseadas em conteúdo. Ele gera um hash a partir da organização (do cabeçalhoX-Tenant-Id), senderAccountId, dados do destinatário e valor, e o armazena no Redis por 60 segundos (configurável). Se uma transferência correspondente já foi enviada dentro da janela, a requisição é rejeitada com 409 BTF-0012.
Isso captura casos em que o cliente envia a mesma transferência com uma chave de idempotência diferente — por exemplo, após um timeout em que a resposta original não foi recebida.
Estratégia de retry
Use backoff exponencial para erros transientes. Nem todos os erros devem ser retentados.
| Status HTTP | Tipo de erro | Retry? | Observações |
|---|---|---|---|
400 | Erro de validação | Não | Corrija a requisição antes de tentar novamente |
404 | Não encontrado | Não | O recurso não existe |
409 | Duplicata | Não | Idempotente — use a resposta original |
410 | Expirado | Não | Crie uma nova iniciação |
422 | Regra de negócio | Não | Horário de funcionamento, limites — a condição deve mudar primeiro |
429 | Limite de taxa | Sim | Aguarde o valor do cabeçalho Retry-After (em segundos) |
500 | Erro interno | Sim | Retry com backoff |
503 | Indisponível | Sim | Retry com backoff; verifique /health/ready se persistir |
Para
503 BTF-1000 (JD SPB indisponível): após esgotar as tentativas, a transferência deve ser sinalizada para reconciliação manual. Não continue tentando indefinidamente — a rede JD SPB tem horários de funcionamento definidos.Gerenciamento de estado
Máquina de estados do TED OUT
As transferências seguem uma progressão estrita. Uma vez que uma transferência sai deCREATED ou PENDING, ela não pode ser cancelada.

| Estado | Significado | Ação recomendada |
|---|---|---|
CREATED | Confirmado pelo usuário, aguardando envio | Exibir “Processando” na UI; aguardar polling ou webhook |
PENDING | Enviado para a JD, aguardando reconhecimento | Exibir “Processando”; não permitir cancelamento |
PROCESSING | JD aceitou e está roteando a transferência | Exibir “Processando”; SLA típico inferior a 10 minutos |
COMPLETED | Liquidada | Exibir confirmação com confirmationNumber |
REJECTED | JD rejeitou (dados inválidos, violação de regra) | Exibir erro ao usuário; fundos já liberados |
FAILED | JD inacessível ou timeout | Exibir erro; fundos já liberados; permitir retry se desejado |
CANCELLED | Cancelada antes do envio | Exibir confirmação de cancelamento |
Máquina de estados da iniciação
A entidadePaymentInitiation (criada pelo endpoint de initiate) tem seu próprio ciclo de vida antes de um Transfer ser criado.

Máquina de estados do TED IN

Máquina de estados do P2P
O P2P não tem um estadoPENDING. A liquidação é atômica e instantânea.

Polling vs. webhooks
Prefira webhooks para status em tempo real. Se os webhooks ainda não estiverem configurados, faça polling emGET /v1/transfers/{transferId} com no máximo 10 tentativas usando o mesmo cronograma de backoff do retry. Após 10 minutos sem um estado terminal (COMPLETED, REJECTED, FAILED, CANCELLED), sinalize a transferência para revisão manual.
Consulte Obter Transferência e Webhooks.
Integração com webhooks
Para esquemas de payload de eventos e a lista completa de eventos, consulte Webhooks.
Validação de assinatura
Toda requisição de webhook inclui um cabeçalhoX-Signature com uma assinatura HMAC-SHA256. Sempre valide antes de processar.
JSON.stringify — a representação em bytes deve corresponder exatamente) usando seu webhookSecret, depois compare usando uma função de tempo constante.
JavaScript
JavaScript
Python
Python
Go
Go
Processamento idempotente de webhooks
Seu endpoint pode receber o mesmo evento mais de uma vez (entrega at-least-once). UsetransferId + event como chave composta para deduplicar.
Padrões de tratamento de erros
Mapeie códigos de erro da API para ações voltadas ao usuário. Consulte a lista completa de erros para todos os códigos.
| Cenário | Código | Mensagem ao usuário | Ação |
|---|---|---|---|
| Fora do horário | BTF-0010 | ”Transferências disponíveis seg–sex, 06:30–17:00 (Brasília). Próxima janela: “ | Exibir próximo horário disponível |
| Limite diário excedido | BTF-0011 | ”Limite diário de transferências atingido. Tente novamente amanhã.” | Exibir limite restante |
| Transferência duplicada | BTF-0012 | ”Esta transferência já foi enviada.” | Retornar o transferId original |
| Dados do destinatário inválidos | BTF-0001 | ”Verifique os dados do destinatário e tente novamente.” | Destacar campos inválidos |
| Iniciação expirada | BTF-0202 | ”Sessão expirada. Por favor, inicie uma nova transferência.” | Reiniciar o fluxo de iniciação |
| JD SPB indisponível | BTF-1000 | ”Serviço de transferência temporariamente indisponível. Tente novamente em alguns minutos.” | Retry com backoff |
| Midaz indisponível | BTF-2000 | ”Serviço temporariamente indisponível. Tente novamente em alguns minutos.” | Retry com backoff |
Checklist para entrar em produção
Antes de habilitar a integração em produção:
-
X-Idempotencyé enviado em cada requisição de initiate, process e cancel - Lógica de retry implementada com backoff exponencial para erros 5xx/503
- Endpoint de webhook implantado e retornando
200em até 5 segundos - Validação de assinatura ativa no endpoint de webhook
- Deduplicação de eventos de webhook implementada usando
transferId + event - Horários de funcionamento validados no lado do cliente antes de chamar initiate (reduz 422s desnecessários)
- Tanto
transferIdquantoconfirmationNumberarmazenados para reconciliação - Estados terminais (
COMPLETED,REJECTED,FAILED,CANCELLED) tratados na UI - Expiração da iniciação (24h) tratada — o usuário é solicitado a reiniciar se a janela encerrar
-
GET /health/readymonitorado no seu sistema de alertas para deployments BYOC - Redis está disponível e monitorado — o serviço não aceitará requisições se o Redis estiver inacessível
-
PLUGIN_AUTH_ENABLED=trueconfigurado em produção, comPLUGIN_AUTH_ADDRESS,PLUGIN_AUTH_CLIENT_IDePLUGIN_AUTH_CLIENT_SECRETválidos

