Skip to main content
Intra-PSP transfers (also called P2P) are Pix transfers where the payer and payee belong to the same participant — the source and destination ISPB are identical. Because the money never leaves the institution, these transfers are settled internally instead of being routed to BTG for settlement. They must still be reported to BACEN for regulatory compliance.
Earlier plugin versions rejected intra-PSP transfers with error PIX-0406: Intra PSP Not Supported. That error has been removed — intra-PSP transfers and refunds are now fully supported.

Detection


The plugin flags a transfer as intra-PSP when the destination ISPB equals your configured PIX_ISPB: When detected, the initiation response includes isIntraPSP: true:
The isIntraPSP flag is propagated to the Transfer, Cashout, Cashin, and Refund entities for querying and reconciliation.

Processing model


Intra-PSP transfers follow the same Midaz routing as external transfers (through the @external transit account), so the ledger behavior is identical. The only difference is that settlement happens synchronously inside the plugin instead of via BTG webhooks. Two Midaz transactions are created per transfer:
  1. Cashoutsource → @external (pending: false)
  2. Cashin@external → destination (pending: false)
The internal cash-in reuses the exact same CashinApprovalCommand and CashinSettlementCommand pipelines as external cash-ins, including CRM alias validation, balance checks, Pix key ownership, collection completion, and fee calculation.

Flow


The cashout responds with PROCESSING, exactly like an external cashout awaiting BTG. The final status (COMPLETED/FAILED) is delivered asynchronously via outbound webhook. The intra-PSP endpoint is fully idempotent, so worker retries never duplicate transactions.

TRCK002 regulatory reporting


Every successful intra-PSP transaction is reported to BACEN through BTG’s TRCK002 abstraction endpoint, within the regulatory SLA of P99 ≤ 300 seconds.
  • TRCK002 reporting is non-blocking — a reporting failure never rolls back the Midaz transaction or transfer completion. Failed reports are retried with exponential backoff.
  • BTG returns a PixInternalTransactionsReport entity with a pactualId and an initial status of PROCESSING.
  • Report status updates arrive via a CAMT025 webhook (PixInternalTransactionsReport) on the BTG events endpoint, transitioning the report to CONFIRMED or ERROR.
  • As a fallback when webhooks are missed, report status is queryable by end-to-end ID or return identification.

Intra-PSP refunds


A refund (devolução) for a transfer whose original cash-in was intra-PSP is also processed internally:
  • The plugin detects intra-PSP when the original cash-in has isIntraPSP = true.
  • It debits the refund requester (requester → @external), then orchestrates the refund cash-in to the original sender through the same queue + endpoint pattern.
  • The refund is reported to TRCK002 with a returnIdentification.
  • Outbound webhooks: refund.completed/refund.failed to the requester and cashin.completed to the original sender.
Unblock is not supported for intra-PSP transfers. The unblock flow queries BTG for status, which does not apply to internal transactions, so calling it returns error PIX-0418. See Refund operations.

Failure reasons


Cash-in validation failures are delivered asynchronously via the cashout.failed webhook. Common intra-PSP failure reasons:

Next steps