Skip to main content
An intra-PSP transfer (also called P2P) is a Pix transfer between a payer and a payee at the same participant. The source and destination ISPB are identical. The money never leaves the institution, so the plugin settles the transfer internally and does not route it to BTG. The plugin still reports the transfer to BACEN for regulatory compliance.
The plugin supports intra-PSP transfers and refunds. It settles them internally and reports each one to BACEN through TRCK002.

Detection


The plugin marks a transfer as intra-PSP when the destination ISPB matches your configured PIX_ISPB: Detection is internal. The initiation response and the cashout status match an external transfer. The plugin routes an intra-PSP transfer through the internal settlement path instead of BTG.

Processing model


An intra-PSP transfer uses the same Midaz routing as an external transfer, through the @external transit account. The ledger behavior is identical. The plugin settles the transfer synchronously and does not wait for BTG webhooks. The plugin creates two Midaz transactions per transfer:
  1. Cashoutsource → @external (pending: false)
  2. Cashin@external → destination (pending: false)
The internal cash-in reuses the same CashinApprovalCommand and CashinSettlementCommand pipelines as an external cash-in. These pipelines run CRM alias validation, balance checks, Pix key ownership, collection completion, and fee calculation.

Flow


The cashout responds with PROCESSING, like an external cashout that waits for BTG. The plugin delivers the final status (COMPLETED or FAILED) asynchronously through an outbound webhook. The intra-PSP endpoint is idempotent, so worker retries never duplicate transactions.

TRCK002 regulatory reporting


The plugin reports every successful intra-PSP transaction to BACEN through BTG’s TRCK002 endpoint.
  • TRCK002 reporting is non-blocking. A report failure never rolls back the Midaz transaction or the transfer completion. The plugin retries a failed report.
  • The plugin creates a TransactionReport for each transaction. After BTG accepts the submission, the report status becomes PROCESSING and carries a pactualId.
  • BTG sends report status updates through a CAMT025 webhook, typed PIX_INTERNAL_TRANSACTIONS_REPORT. The webhook moves the report to CONFIRMED (terminal) or ERROR (recoverable).
  • You can also query a report by end-to-end ID or return identification when a webhook does not arrive.

Intra-PSP refunds


The plugin also processes a refund internally when the original cash-in was intra-PSP:
  • The plugin detects intra-PSP from the original transfer, when its source and destination ISPB match.
  • It debits the refund requester (requester → @external). It then delivers the refund cash-in to the original sender through the same queue and endpoint pattern.
  • The plugin reports the refund to TRCK002 with a returnIdentification.
  • The plugin persists a REFUND outbound webhook (DICT flow) to notify the requester, and the intra-PSP cash-in settlement queues cashin.completed for the original sender.
Do not call unblock for an intra-PSP transfer. The unblock flow queries BTG for the transfer status. BTG never processes an internal transaction, so the query does not apply. See Refund operations.

Failure reasons


The plugin delivers a cash-in validation failure asynchronously through the cashout.failed webhook. For an intra-PSP failure, the webhook carries the reason INTRA_PSP_REJECTED and a sanitized message. Common messages:

Next steps