Pular para o conteúdo principal
Transferências intra-PSP (também chamadas de P2P) são transferências Pix em que o pagador e o recebedor pertencem ao mesmo participante — o ISPB de origem e o de destino são idênticos. Como o dinheiro nunca sai da instituição, essas transferências são liquidadas internamente em vez de serem roteadas ao BTG para liquidação. Elas ainda devem ser reportadas ao BACEN para conformidade regulatória.
Versões anteriores do plugin rejeitavam transferências intra-PSP com o erro PIX-0406: Intra PSP Not Supported. Esse erro foi removido — transferências e devoluções intra-PSP agora têm suporte completo.

Detecção


O plugin marca uma transferência como intra-PSP quando o ISPB de destino é igual ao seu PIX_ISPB configurado:
Tipo de iniciaçãoOrigem do ISPB de destino
KEY / QR_CODEResposta da consulta ao DICT (account.participant)
MANUALdestination.ispb no payload da requisição
Quando detectada, a resposta de iniciação inclui isIntraPSP: true:
POST /v1/transfers/cashout/initiate
201 Created
{
  "id": "uuid",
  "status": "PENDING",
  "isIntraPSP": true,
  "expiresAt": "2026-02-25T12:05:00Z"
}
A flag isIntraPSP é propagada para as entidades Transfer, Cashout, Cashin e Refund para consulta e conciliação.

Modelo de processamento


Transferências intra-PSP seguem o mesmo roteamento Midaz das transferências externas (por meio da conta de trânsito @external), de modo que o comportamento do ledger é idêntico. A única diferença é que a liquidação ocorre de forma síncrona dentro do plugin, em vez de via webhooks do BTG. Duas transações Midaz são criadas por transferência:
  1. Cashoutsource → @external (pending: false)
  2. Cashin@external → destination (pending: false)
O cashin interno reutiliza exatamente os mesmos pipelines CashinApprovalCommand e CashinSettlementCommand dos cash-ins externos, incluindo validação de alias do CRM, verificações de saldo, propriedade da chave PIX, conclusão da cobrança e cálculo de tarifa.

Fluxo


Process Cashout (isIntraPSP = true)
  → Midaz debit: source → @external
  → Write inbound record to the webhook queue
  → Cashout status → PROCESSING (intermediary)
  → Return PROCESSING to client

Inbound worker (existing)
  → Picks up the record and delivers it (HTTP + HMAC)
    to POST /v1/payment/webhooks/intra-psp/events

Intra-PSP endpoint (orchestrates the full lifecycle)
  → CashinApprovalCommand → ACCEPTED / DENIED
  → ACCEPTED  → CashinSettlementCommand → Midaz credit → Cashout COMPLETED
  → DENIED / settlement fails → revert Midaz debit → Cashout FAILED
  → Report to BTG TRCK002 (async, non-blocking)
  → Outbound webhooks: cashout.completed/failed + cashin.completed
O cashout responde com PROCESSING, exatamente como um cashout externo aguardando o BTG. O status final (COMPLETED/FAILED) é entregue de forma assíncrona via webhook de saída. O endpoint intra-PSP é totalmente idempotente, então as retentativas do worker nunca duplicam transações.

Reporte regulatório TRCK002


Toda transação intra-PSP bem-sucedida é reportada ao BACEN por meio do endpoint de abstração TRCK002 do BTG, dentro do SLA regulatório de P99 ≤ 300 segundos.
  • O reporte TRCK002 é não bloqueante — uma falha de reporte nunca reverte a transação Midaz nem a conclusão da transferência. Reportes que falham são reprocessados com backoff exponencial.
  • O BTG retorna uma entidade PixInternalTransactionsReport com um pactualId e um status inicial PROCESSING.
  • Atualizações de status do reporte chegam via webhook CAMT025 (PixInternalTransactionsReport) no endpoint de eventos do BTG, transicionando o reporte para CONFIRMED ou ERROR.
  • Como fallback quando webhooks são perdidos, o status do reporte pode ser consultado por identificador end-to-end ou identificação de retorno.

Devoluções intra-PSP


Uma devolução para uma transferência cujo cash-in original foi intra-PSP também é processada internamente:
  • O plugin detecta o caso intra-PSP quando o cashin original tem isIntraPSP = true.
  • Ele debita o solicitante da devolução (requester → @external), depois orquestra o cash-in da devolução ao remetente original por meio do mesmo padrão de fila + endpoint.
  • A devolução é reportada ao TRCK002 com um returnIdentification.
  • Webhooks de saída: refund.completed/refund.failed para o solicitante e cashin.completed para o remetente original.
O desbloqueio não tem suporte para transferências intra-PSP. O fluxo de desbloqueio consulta o BTG pelo status, o que não se aplica a transações internas, então chamá-lo retorna o erro PIX-0418. Consulte Operações de devolução.

Motivos de falha


Falhas de validação do cash-in são entregues de forma assíncrona via o webhook cashout.failed. Motivos comuns de falha intra-PSP:
CódigoDescrição
RECIPIENT_ACCOUNT_INVALIDValidação de alias do CRM falhou (conta não encontrada, encerrada, bloqueada)
RECIPIENT_CANNOT_RECEIVEValidação de saldo no ledger falhou
PIX_KEY_OWNERSHIP_INVALIDA chave PIX não pertence à conta de destino
COLLECTION_INVALIDValidação da cobrança de QR code dinâmico falhou
INTERNAL_CREDIT_FAILEDTransação de crédito no ledger falhou
INTERNAL_DEBIT_REVERT_FAILEDCrítico — reversão do débito falhou; requer conciliação manual

Próximos passos