Pular para o conteúdo principal
Este guia é para desenvolvedores que implementam a integração com o plugin Bank Transfer. Ele cobre os padrões e as decisões que vão além de chamadas isoladas a endpoints: idempotência, estratégia de novas tentativas, tratamento de estado e validação de webhook. Para parâmetros de endpoint e schemas de resposta, veja a Referência da API.

Idempotência


Cada requisição que altera dados (initiate, process, cancel, return) exige um header X-Idempotency. Uma requisição sem ele é recusada com 400 BTF-0001. Se você enviar a mesma requisição duas vezes com uma mesma chave, o plugin retorna a resposta original sem criar uma operação duplicada. Regras:
  • Use um UUID v4 ou um identificador de negócio único (por exemplo, o ID do pedido no seu sistema)
  • Comprimento máximo: 255 caracteres, formados por letras, dígitos, ., _ e -
  • O plugin dá a cada chave o escopo da organização efetiva. A mesma chave vinda de duas organizações conta como duas requisições distintas.
  • O plugin repete uma resposta de sucesso por 7 dias. A repetição traz o mesmo código de status e o mesmo corpo, mais o header X-Idempotency-Replayed: true.
  • Uma resposta 4xx não consome a chave: corrija a requisição e envie de novo com a mesma chave.
  • Depois de uma resposta 5xx, o resultado é desconhecido: leia o recurso primeiro e envie a requisição de novo apenas com uma nova chave. Uma chave que a resposta bloqueou (X-Idempotency-Fenced: true) é recusada com 422 BTF-0014. Uma resposta 503 BTF-9000 ou 503 BTF-9017 não executou nada: envie a requisição de novo com a mesma chave.
  • A mesma chave com um corpo diferente é recusada com 422 BTF-0017. Um novo envio enquanto a primeira requisição ainda está em execução recebe 409 BTF-0016 com Retry-After.
  • Cada recusa de idempotência informa sua solução em detail. Leia-a antes de enviar de novo.
Não reutilize chaves de idempotência entre operações diferentes. Não reutilize uma chave de initiate para processar ou cancelar a mesma transferência.

Detecção de duplicatas

Além das chaves de idempotência, o plugin detecta duplicatas por conteúdo. Ele monta uma impressão digital a partir de:
  • senderAccountId
  • dados do destinatário (ISPB, agência, conta, documento do titular)
  • valor
  • finalidade
O plugin guarda a impressão digital no Redis por 5 minutos. O padrão é 300 segundos. Os operadores ajustam isso por tenant pela configuração idempotency.duplicate_guard_ttl_seconds do systemplane. A organização não faz parte da impressão digital. O isolamento de tenant vem do prefixo da chave no Redis. O plugin rejeita a requisição com 409 BTF-0012 se o cliente já enviou uma transferência correspondente dentro da janela. Isso pega os casos em que o cliente envia a mesma transferência com uma chave de idempotência diferente. Um exemplo é uma nova tentativa após um timeout, quando o cliente não recebeu a resposta original.

Estratégia de novas tentativas


Use backoff exponencial para erros transitórios. Não repita a tentativa em todo erro. Cronograma de backoff recomendado para 5xx: 0s, 5s, 25s, 60s, 120s (5 tentativas no total).
Durante POST /v1/transfers/process, quando o JD SPB está indisponível, a resposta é HTTP 503 com code BTF-1000, ou BTF-1003 em um timeout da JD. upstream.code carrega o código próprio da JD quando a JD retornou um. transferId e transferStatus identificam a transferência. Uma transferência em PROCESSING mantém sua retenção enquanto a conciliação pergunta o resultado à JD: não a processe de novo.

Tratamento de estado


Máquina de estados da TED OUT

As transferências seguem uma progressão estrita. Você não pode cancelar uma transferência depois que ela sai de CREATED ou PENDING.
Máquina de estados da TED OUT
O que fazer em cada estado:

Máquina de estados da iniciação

O endpoint initiate cria uma entidade PaymentInitiation. Essa entidade tem seu próprio ciclo de vida antes de o plugin criar um Transfer.
Máquina de estados da iniciação

Máquina de estados da TED IN

Máquina de estados da TED IN

Máquina de estados do P2P

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

Polling vs. webhooks

Prefira webhooks para status em tempo real. Se você ainda não configurou webhooks, consulte GET /v1/transfers/{transferId}. Use no máximo 10 tentativas com o mesmo cronograma de backoff das novas tentativas. Sinalize a transferência para revisão manual depois de 10 minutos sem estado terminal (COMPLETED, REJECTED, FAILED, CANCELLED). Veja Obter transferência e Webhooks.

Integração de webhook


Para os schemas de payload dos eventos e a lista completa de eventos, veja Webhooks.

Validação da assinatura

Cada requisição de webhook inclui headers que seu endpoint usa para verificar a autenticidade:
  • X-Webhook-Signature: assinatura HMAC-SHA256 versionada no formato v1,sha256=<hex>
  • X-Webhook-Timestamp: timestamp Unix em segundos (UTC) de quando o plugin montou a requisição
  • X-Webhook-Event: o tipo do evento (por exemplo, transfer.completed). Este header não faz parte da assinatura.
O plugin calcula a assinatura assim:
A string assinada tem quatro partes, nesta ordem: o prefixo v1:, o valor do timestamp vindo de X-Webhook-Timestamp, um ponto ASCII (.) e então os bytes brutos do corpo da requisição. Use os bytes do corpo exatamente como chegam pela rede. Não os analise nem os recodifique antes. Para validar:
  1. Leia X-Webhook-Signature e X-Webhook-Timestamp nos headers da requisição.
  2. Monte a string assinada: "v1:" + timestamp + "." + rawBody.
  3. Calcule HMAC-SHA256 sobre a string assinada com o signingSecret do registro do webhook e codifique o resultado em hexadecimal.
  4. Coloque v1,sha256= na frente e compare com X-Webhook-Signature usando uma função de igualdade de tempo constante.
  5. Rejeite a requisição se o timestamp estiver fora de uma janela de validade aceitável (uma tolerância de 5 minutos é típica) para evitar replay.

Processamento idempotente de webhook

Seu endpoint pode receber o mesmo evento mais de uma vez (entrega pelo menos uma vez). Use transferId + o header X-Webhook-Event como chave composta para deduplicar. Para os eventos de devolução de um TED IN, adicione status e reconciliationReasonCode do corpo à chave.

Padrões de tratamento de erros


Mapeie os códigos de erro da API para ações voltadas ao usuário. Veja a lista completa de erros para todos os códigos. As respostas de erro são documentos de problema RFC 9457 (application/problem+json). Os campos específicos de cada rota ficam no nível superior:

Checklist de entrada em produção


Antes de habilitar a integração em produção:
  • Envie X-Idempotency em cada requisição de initiate, process e cancel
  • Lógica de nova tentativa implementada com backoff exponencial para erros 5xx/503
  • Endpoint de webhook com o deploy feito e retornando 200 em até 5 segundos
  • Validação de assinatura ativa no endpoint de webhook
  • Deduplicação de eventos de webhook implementada com transferId + event
  • Horário de funcionamento validado no cliente antes de chamar initiate (reduz 422 desnecessários)
  • transferId e confirmationNumber armazenados para conciliação
  • Estados terminais (COMPLETED, REJECTED, FAILED, CANCELLED) tratados na interface
  • Expiração da iniciação tratada (expiresAt): peça ao usuário para recomeçar quando ela passar
  • Readiness do serviço monitorada no seu sistema de alertas para deploys BYOC
  • Redis acessível e monitorado: o serviço rejeita requisições quando o Redis está fora
  • PLUGIN_AUTH_ENABLED=true configurado em produção, com um PLUGIN_AUTH_ADDRESS válido (HTTPS)