Skip to main content
P2P transfers move funds between accounts within your institution instantly, 24 hours a day. A P2P transfer can carry a fee. See Fee configuration below. The transfer never leaves your system, so it settles synchronously and needs no BACEN network.

When to use P2P


P2P is the right transfer type whenever both the sender and recipient hold accounts at your institution. Common scenarios include:
  • Moving money between a customer’s own accounts: a customer transferring from their checking account to their savings account, or between two accounts they manage.
  • Paying another customer at the same institution: a customer sending money to a friend, family member, or business that also banks with you.
  • Internal treasury movements: splitting balances between corporate accounts held within the same organization.
  • Payment splitting: distributing amounts across multiple accounts for payroll, expense sharing, or cashback.
The plugin detects P2P automatically. When the recipient’s ISPB matches your institution’s ISPB, the plugin routes the transfer internally. Your API integration is identical to TED OUT, so you need no separate endpoint or logic. Both accounts must be in the same Midaz organization. For accounts in two ledgers, see Transfers between ledgers.

Key advantages


How it works


P2P reuses the same API as TED OUT, so your integration stays consistent across transfer types. The process is two steps from the customer’s perspective: P2P flow diagram
  1. Initiate: The customer submits the transfer details. The plugin validates the recipient and calculates the fee. The customer sees the transfer summary before committing.
  2. Confirm: The customer confirms. The plugin creates an atomic debit + credit in Midaz. The transfer completes immediately.
The two-step flow gives you a natural moment to show the customer a confirmation screen with the full transfer summary before any funds move.

Transfer states


P2P state machine diagram
The PENDING state does not apply to P2P transfers. TED OUT uses PENDING while the plugin prepares the message for JD. The hold is already in place from CREATED. P2P settles entirely within Midaz, so the transfer moves from CREATED through PROCESSING to COMPLETED. A P2P transfer cannot be cancelled.

Fee configuration


The fee mode, MIDAZ_FEE_MODE, decides who charges the fee of a P2P transfer. See TED configuration.

Recipient validation


The recipient must have an account at the same institution. When you submit a transfer, the plugin looks up the recipient in CRM. It matches the bank details you provide: ISPB, branch, account, and holder document. If the plugin does not find the recipient, it rejects the transfer and moves no funds. The customer must check the account details and try again. If the two accounts are in different Midaz organizations, the plugin refuses the transfer with 422 BTF-0004. It refuses two different ledgers the same way, unless the tenant allows transfers between ledgers.

Transfers between ledgers


A P2P can move funds between two ledgers of the same Midaz organization. This is off by default. To turn it on for a tenant, set the tenant policy p2p.cross_ledger_enabled to true through the Admin API. The plugin reads this setting only when you initiate a transfer. A transfer between two ledgers needs all of these: The plugin posts the transfer as one Midaz ledger group: both ledgers move, or neither moves. The transfer keeps the payer’s ledger in ledgerId, the recipient’s ledger in recipientLedgerId, and the group in ledgerGroupId.

Technical integration


P2P uses the same endpoints as TED OUT. You need no extra integration work beyond the outbound transfer flow you already built.
The type field in the transfer response is P2P. P2P transfers have no controlNumber, because they do not go through JD SPB.

Error handling


P2P transfers are atomic. If any part fails, Midaz applies neither leg. No intermediate state moves funds partially or leaves an account short. If a transfer fails, the customer keeps the same balance and can retry. If /process answers 500 BTF-9014, the money moved, but the plugin did not record the transfer as completed. Read the transfer, then send the same /process request again under a new X-Idempotency key. Do not initiate a new transfer. See the full error list for error codes and recovery guidance.