Por que dois passos
Dividir um cash-out em iniciar e processar dá a você um ponto de verificação entre “quem é o recebedor?” e “envie o dinheiro”:
- Confirme o destino primeiro. A iniciação valida e resolve a conta do recebedor sem tocar em saldos. Uma chave Pix errada ou uma conta inválida falha aqui, antes de qualquer dinheiro se mover.
- Mostre ao pagador quem recebe o dinheiro. A resposta da iniciação retorna o titular resolvido da conta. Seu app pode mostrar o nome real e deixar o pagador confirmar antes.
- Mova os fundos apenas na confirmação. O plugin não debita nada até você processar a transferência. Se o pagador abandonar o fluxo, não há movimentação a desfazer.
Os dois passos aceitam uma chave
X-Idempotency. Repita com a mesma chave para evitar transferências duplicadas. Veja Novas tentativas e idempotência.Passo 1: iniciar (confirme o destino)
Iniciar uma transferência cria um registro de vida curta que valida e resolve o recebedor sem mover fundos. Como o plugin encontra o destino depende do que você tem no começo:
Para
KEY e QR_CODE, você nunca informa o destino. O plugin o resolve e o retorna na resposta, pronto para mostrar ao pagador para confirmação.
Requisição: escolha a aba do seu tipo de iniciação
type da conta são CACC (corrente), SVGS (poupança), TRAN (transacional) e OTHR (outra). endToEndId é opcional para todos os tipos. O plugin gera um quando você o omite.
Resposta
A resposta retorna oid da iniciação (usado como initiationId no passo 2) e o destination resolvido:
As iniciações expiram. A resposta inclui um timestamp
expiresAt. Processe a transferência antes que ela expire ou inicie de novo. Isso impede que um destino confirmado fique desatualizado entre a consulta e o pagamento.Passo 2: processar (mover o dinheiro)
O processamento executa o cash-out a partir da iniciação que você confirmou. Ele debita a conta de origem e depois roteia o pagamento ao BTG para liquidação com o BACEN. A liquidação com a rede Pix é assíncrona. A transferência volta como
PROCESSING enquanto o BTG liquida. O resultado final (por exemplo COMPLETED ou REJECTED) chega depois por um webhook TRANSFER / CASHOUT. Monte seu fluxo para reagir a esse evento, não para esperar a resposta do processamento. Veja Webhooks.
Requisição
Passe oid da resposta de iniciação como initiationId, junto com o amount a transferir:
amount é obrigatório. Você também pode passar um description opcional (máximo de 140 caracteres) e metadata (atributos chave-valor customizados).
O header X-Purpose
Use o header X-Purpose opcional para declarar o motivo do cash-out. Ele assume TRANSFER como padrão quando é omitido:
QR codes de valor fixo: a iniciação pode ser um
QR_CODE cujo payload EMV carrega um valor fixo. Nesse caso, o amount que você envia ao processar deve ser igual ao valor codificado. Uma divergência é rejeitada antes de qualquer fundo se mover.Resposta
Quando o destino pertence à sua própria instituição, o dinheiro nunca sai para o BTG. Ele liquida internamente como uma transferência P2P. Veja Transferências intra-PSP.
Acompanhar uma transferência
Uma transferência começa em
CREATED e passa por PENDING/PROCESSING enquanto está em trânsito. Depois, ela chega a um COMPLETED, FAILED, CANCELLED ou REJECTED terminal. Para ver em que ponto uma transferência está, consulte uma delas pelo id. Você também pode listar transferências filtradas por status, tipo (cash-out ou cash-in) ou período.
status, type (CASHOUT/CASHIN), end_to_end e modified_after/modified_before, além da paginação page/limit/sort_order.
Pagamentos agendados
Um pagamento agendado executa um cash-out Pix em uma data e hora futuras. Primeiro, inicie a transferência como no passo 1. Depois, passe o
id da iniciação como initiationId para POST /v1/schedules, com o amount e a data e hora scheduledFor:
scheduledFor deve estar pelo menos SCHEDULE_MIN_FUTURE_SECONDS no futuro e no máximo SCHEDULE_MAX_FUTURE_DAYS dias à frente. Você também pode passar uma description opcional (até 140 caracteres) e maxAttempts (1 ou 2). Se você omitir maxAttempts, o plugin usa SCHEDULE_MAX_ATTEMPTS.
Um agendamento começa em SCHEDULED. No horário agendado, o worker de agendamento o move para PROCESSING e executa o cash-out. Depois, o agendamento termina em EXECUTED, FAILED ou CANCELLED. Para cancelar um agendamento, envie DELETE /v1/schedules/{schedule_id} enquanto ele está em SCHEDULED. O plugin envia um webhook SCHEDULE / CASHOUT com o tipo de evento schedule.executed, schedule.failed ou schedule.cancelled.
Pix Automático (pagador)
O Pix Automático permite que um recebedor debite a conta do pagador em uma agenda, depois que o pagador autoriza. O plugin cuida do lado do pagador. As chamadas recebem a conta do pagador no header
X-Account-Id. Na listagem de autorizações, o header é opcional. Sem ele, a lista cobre todas as contas.
Quando você aceita uma solicitação, ela passa para
APPROVING. A autorização começa quando o BTG a aprova. Quando o plugin aceita uma cobrança do recebedor, ele cria um pagamento agendado para essa cobrança. O plugin envia webhooks RECURRING para as entidades AUTHORIZATION_REQUEST, AUTHORIZATION e CHARGE. Veja Webhooks.
Como as transferências chegam ao Midaz
O plugin lança toda movimentação liquidada no Midaz como uma transação no ledger, com a perna externa contra a conta
@external/BRL. O Midaz registra o lançamento e os metadados de correlação, não os dados bancários completos da transferência. Agência, número da conta, tipo de conta e chave Pix da contraparte nunca chegam ao Midaz. A única exceção é a identidade do pagador no cash-in (sourceBank, sourceDocument, sourceName), gravada quando é conhecida. O detalhe completo da contraparte fica no registro de transferência do plugin.
Os metadados gravados na transação do Midaz dependem do fluxo:
O
code da transação no Midaz também carrega o endToEndId (ou a returnIdentification nas devoluções), então o identificador E2E fica visível direto no lançamento do ledger.
A correlação funciona nos dois sentidos:
- O plugin guarda os identificadores de transação e de operação do Midaz nos seus próprios registros de transferência e de devolução, e os usa para confirmar, cancelar ou reverter lançamentos.
- A transação do Midaz carrega chaves de correlação nos seus metadados: filtre por
metadata.endToEndIdpara cash-outs e cash-ins, ou pormetadata.originalEndToEndId/metadata.returnIdentificationpara devoluções. Ocodeda transação é o fallback comum. Ele carrega o ID E2E nas transferências e a identificação de devolução nas devoluções.
O
metadata customizado que você passa ao processar um cash-out é guardado com o registro de transferência do plugin e retornado pela API do próprio plugin. Ele não é copiado para a transação do Midaz. O plugin fixa as chaves de metadados do Midaz listadas acima.Verificação de fraude em Pix recebido
O plugin pode consultar um endpoint de decisão que você opera antes de aceitar um Pix recebido ou uma devolução recebida. A verificação vem desligada por padrão. Para ligá-la, defina
ANTIFRAUD_HOOK_ENABLED=true e as outras variáveis da verificação de fraude.
O plugin envia uma requisição POST com um corpo JSON para ANTIFRAUD_HOOK_URL:
contractVersion:1.0.eventType:PIX_CASHINpara um Pix recebido, ouPIX_REFUND_CASHINpara uma devolução recebida.approvalId: um UUID que identifica a verificação.requestedAterespondBy: timestamps em UTC.respondByérequestedAtmaisANTIFRAUD_HOOK_TIMEOUT_MS.cashin, emPIX_CASHIN:amount,endToEndId,transactionIdentification,transactionType,paymentType,initiationType,urgency,remittanceInformation,movementIds,debitParty,creditPartyeaccount. Cada parte temname,taxId,personType,bank,branch,account,accountTypeekey.cashin.accounttemaccountId,aliasId,holderIdedocument.refundCashin, emPIX_REFUND_CASHIN:returnIdentification,originalEndToEndId,amount,reason,additionalInformationeoriginalTransaction.originalTransactiontemendToEndId,amount,createdAtecreditPartycomname,taxId,bank,brancheaccount.metadata: um objeto vazio.
transactionIdentification, remittanceInformation, key, aliasId, holderId e additionalInformation quando estão vazios.
Cada requisição traz estes headers:
X-Webhook-Timestamp: o horário Unix, em segundos, em que o plugin assinou a requisição.X-Webhook-Signature:v1,sha256=<hex>.<hex>é o HMAC-SHA256 dev1:<timestamp>.<raw body>comANTIFRAUD_HOOK_HMAC_SECRETcomo chave.<timestamp>é o valor deX-Webhook-Timestamp.Idempotency-Key: oapprovalId.
X-Webhook-Signature.
Responda com um status 2xx e um objeto JSON com decision e um reason opcional. O plugin registra reason como antifraudReason. Ele lê decision sem diferenciar maiúsculas de minúsculas:
APPROVEouALLOWaceita o Pix.REJECT,DENYouREVIEWrecusa o Pix ao BTG com o código de motivoFRAD.
2xx, uma resposta que ele não consegue ler ou um circuit breaker aberto. Também acontece quando um Pix recebido não traz dados do pagador.
O plugin não faz a verificação em créditos e devoluções intra-PSP, nem em créditos de devolução MED (INSTANT_PAYMENT_REFUND e REFUND_AUTOMATIC_PIX).
Um Pix recusado não cria cash-in nem devolução. O plugin registra cada decisão no webhook de entrada armazenado. Consultar um webhook de entrada retorna a decisão em payload.metadata: antifraudDecision, antifraudSource, antifraudReason e antifraudLatencyMs. Também retorna antifraudRawDecision quando o seu endpoint respondeu, ou antifraudPolicy quando o fallback decidiu.
Quando uma transferência trava
Se a chamada de liquidação ao BTG der timeout antes de o BTG confirmar, uma transferência pode ficar em
PROCESSING com os fundos retidos. O plugin oferece uma operação de desbloqueio. O desbloqueio reconsulta a transferência no BTG e a leva ao estado final correto. Ele liquida a transferência se o BTG confirmar, ou libera a retenção se o BTG nunca a tiver recebido.
O desbloqueio não se aplica a transferências intra-PSP. Não há transação no BTG para reconsultar. Para o comportamento completo do desbloqueio e suas opções, veja Operações de devolução.
Próximos passos
- Transferências intra-PSP: Liquidação P2P interna
- QR Codes: Geração e decodificação de QR codes
- Operações de devolução: Devoluções e desbloqueio
- Webhooks: Tratamento de eventos de cash-out e cash-in
- Referência da API: Detalhes completos de requisição e resposta, headers e schemas de campos

