Idempotência
Cada requisição que altera dados (initiate, process, cancel) exige um header
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 (por exemplo, o ID do pedido no seu sistema)
- Comprimento máximo: 255 caracteres
- 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 retorna uma resposta em cache durante a janela de idempotência configurada (
IDEMPOTENCY_RETRY_WINDOW_SEC, padrão de 300 segundos) - Uma resposta reenviada é idêntica byte a byte à original: mesmo código de status, mesmo corpo. A resposta não tem header que marque um reenvio, então projete seu cliente para ficar seguro nos dois casos.
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
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/503: 0s, 5s, 25s, 60s, 120s (5 tentativas no total).
Quando o JD SPB está indisponível, a resposta é
HTTP 503. O campo error.code carrega então o código bruto do fornecedor JD, por exemplo TRANSPORT para falhas de transporte ou ACE95 para timeouts. O plugin não embrulha as falhas da cadeia JD em um código BTF-. Sinalize a transferência para conciliação manual depois que as novas tentativas se esgotam. Não tente de novo sem limite. A rede JD SPB tem horário de funcionamento definido.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 deCREATED ou PENDING.
Máquina de estados da iniciação
O endpoint initiate cria uma entidadePaymentInitiation. Essa entidade tem seu próprio ciclo de vida antes de o plugin criar um Transfer.
Máquina de estados da TED IN
Máquina de estados do P2P
O P2P não tem estadoPENDING. A liquidação é atômica e instantânea.
Polling vs. webhooks
Prefira webhooks para status em tempo real. Se você ainda não configurou webhooks, consulteGET /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 formatov1,sha256=<hex>X-Webhook-Timestamp: timestamp Unix em segundos (UTC) de quando o plugin montou a requisiçãoX-Webhook-Event: o tipo do evento (por exemplo,transfer.completed). Este header não faz parte da assinatura.
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:
- Leia
X-Webhook-SignatureeX-Webhook-Timestampnos headers da requisição. - Monte a string assinada:
"v1:" + timestamp + "." + rawBody. - Calcule
HMAC-SHA256sobre a string assinada com seuWEBHOOK_SIGNING_SECRETe codifique o resultado em hexadecimal. - Coloque
v1,sha256=na frente e compare comX-Webhook-Signatureusando uma função de igualdade de tempo constante. - 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.
X-Webhook-Signature e X-Webhook-Timestamp, o plugin define apenas X-Webhook-Event (o tipo do evento). Ele não envia X-Webhook-Event-Type, X-Webhook-Routing-Key nem X-Webhook-Delivery-Attempt.
JavaScript
JavaScript
Python
Python
Go
Go
Processamento idempotente de webhook
Seu endpoint pode receber o mesmo evento mais de uma vez (entrega pelo menos uma vez). UsetransferId + event como chave composta para deduplicar.
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 seguem esta estrutura:
Checklist de entrada em produção
Antes de habilitar a integração em produção:
- Envie
X-Idempotencyem 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
200em 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)
-
transferIdeconfirmationNumberarmazenados para conciliação - Estados terminais (
COMPLETED,REJECTED,FAILED,CANCELLED) tratados na interface - Expiração da iniciação (24h) tratada: peça ao usuário para recomeçar quando a janela 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=trueconfigurado em produção, com umPLUGIN_AUTH_ADDRESSválido (HTTPS)

