Skip to main content
SPI manages Pix transfers, refunds, asynchronous outcomes, and the MED 2.0 Block Balancer. It calls Midaz for the ledger action that corresponds to the operation.
Cash-in and cash-out callback routes are adapter-only. A client application must not post a callback or claim a provider settlement result.

Send a cash-out in two stages

A cash-out is intentionally split into initiation and processing.
  1. Call Initiate transfer with a new X-Idempotency value. The plugin validates the request and creates a transfer initiation. It refuses a manual destination of type SLRY (salary account).
  2. Call Process transfer for that initiation. The plugin performs the required Midaz debit and submits work to the connectivity adapter.
  3. Read the transfer with Get transfer. Processing acceptance is not a final payment result.
  4. Let the connectivity adapter deliver the terminal callback. Read again until the transfer reaches a completed, rejected, or other terminal state under the response contract.
If the plugin cannot prove that it did not send the payment, it keeps the debit and answers 201 with status PROCESSING. A 502 with PIX-0325 means that the plugin did not send the payment and attempted to revert the debit. Keep the same idempotency value only for a retry of the same call. A new business payment needs a new value.

Receive a cash-in through the adapter boundary

The adapter receives the external-side event, calls the plugin’s internal approval and settlement callbacks, and the plugin validates and credits the destination through Midaz. Your application observes this flow through public transfer reads: use direction=in to list the transfers an account received. It does not invoke approval or settlement callbacks. A cash-in that cannot be approved or settled is not a client-side retry decision. Inspect the public operation state before taking another action.

Create and observe a refund

Use Create refund against an eligible transfer, then read it through Get refund. reasonCode accepts only MD06, SL02, FR01, and BE08. A refund that the rail refuses answers 422 (PIX-0013). A refund follows its own asynchronous lifecycle. Do not mark it complete until the plugin records the terminal provider outcome and the matching Midaz effect. A retry with the same X-Idempotency value within one hour of the first 2xx answer returns the existing refund with 200. After a 5xx or a 409 (PIX-0406), the first attempt can still be PROCESSING with its debit. Call List refunds with transferId before you retry.

Use the MED 2.0 Block Balancer

The Block Balancer holds funds for a contested transaction before a refund decision. It is a controlled operational flow, not a shortcut for ordinary transfers.
  1. Create a hold for the contested transaction. The plugin places a pending Midaz hold from the available balance into the configured blocking account. A replay of the same request_ref returns the existing hold.
  2. If the case ends before settlement, release a PENDING hold. You cannot release a hold that is already in settlement.
  3. Start Phase 1 settlement for one hold or an eligible group. The hold becomes SETTLING. The branch either returns the pending hold and submits a refund, or commits the hold, handles any surplus, and submits the required payment.
  4. Complete Phase 2 only from the linked operation’s observed outcome. A success makes the hold SETTLED. A failure compensates it to PENDING.
  5. Use manual close, surplus return, and audit functions only through authorized operational controls. They are not normal application endpoints.
The Block Balancer enforces a ceiling across its own settlements and regular outbound refunds for the same original transaction. Do not try to calculate around that protection in the client. For the DICT-side infraction and funds-recovery workflow, see DICT.