Pular para o conteúdo principal
Um cash-out Pix move dinheiro de uma conta para um destino externo. O Plugin Pix Indireto (BTG) executa isso em dois passos: iniciar e depois processar. Você confirma para onde o dinheiro vai antes de qualquer valor sair do ledger.

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

Os valores de 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 o id 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.
Referência da API: Iniciar uma transferência Pix

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 o id 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.
Os filtros de listagem incluem 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:
O agendamento usa o destino da iniciação. 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.endToEndId para cash-outs e cash-ins, ou por metadata.originalEndToEndId / metadata.returnIdentification para devoluções. O code da 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_CASHIN para um Pix recebido, ou PIX_REFUND_CASHIN para uma devolução recebida.
  • approvalId: um UUID que identifica a verificação.
  • requestedAt e respondBy: timestamps em UTC. respondBy é requestedAt mais ANTIFRAUD_HOOK_TIMEOUT_MS.
  • cashin, em PIX_CASHIN: amount, endToEndId, transactionIdentification, transactionType, paymentType, initiationType, urgency, remittanceInformation, movementIds, debitParty, creditParty e account. Cada parte tem name, taxId, personType, bank, branch, account, accountType e key. cashin.account tem accountId, aliasId, holderId e document.
  • refundCashin, em PIX_REFUND_CASHIN: returnIdentification, originalEndToEndId, amount, reason, additionalInformation e originalTransaction. originalTransaction tem endToEndId, amount, createdAt e creditParty com name, taxId, bank, branch e account.
  • metadata: um objeto vazio.
O plugin omite 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 de v1:<timestamp>.<raw body> com ANTIFRAUD_HOOK_HMAC_SECRET como chave. <timestamp> é o valor de X-Webhook-Timestamp.
  • Idempotency-Key: o approvalId.
Para verificar uma requisição, calcule o mesmo valor sobre o corpo bruto da requisição e compare-o com 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:
  • APPROVE ou ALLOW aceita o Pix.
  • REJECT, DENY ou REVIEW recusa o Pix ao BTG com o código de motivo FRAD.
Quando o plugin não recebe uma decisão, ele aplica a sua política de fallback. Isso acontece em um timeout, um erro de conexão, um status fora de 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