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. A received Pix never pays a fee. Pix Lerian asks Midaz to skip fees on every credit of a received Pix and of a return, and Midaz honors that only when the setting overrides.allowFeeSkip is on for the Pix ledger. A fee package for cash-out must be additional: see error PIX-0330. Lerian enables overrides.allowFeeSkip on the Pix ledger when it provisions the service.
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 reversed the debit. A 500 (PIX-0000) means that the reversal is not recorded: read the transfer before you act. A transfer or refund that stays in PROCESSING for 90 minutes or more can be resolved with Unblock transfer or Unblock refund. The plugin asks the SPI for the outcome and applies it. 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. Every Pix leg posts against @external/BRL by default. When the SPI setting settlement_account_alias names an ordinary account, that account replaces it: a cash-out credits it and a received Pix debits it. An immediate cash-out whose credit that account cannot take answers 422 with PIX-0332. Change the setting only while no Pix Agendado hold stands.

Credit a received Pix that is parked

When Midaz does not confirm the credit of a received Pix, or of a return, Pix Lerian does not drop it. It parks the credit and emits inbound_transfer.credit_parked or refund.credit_parked (see Events). The event names the reason: For LEDGER_OUTCOME_UNKNOWN and SETTLE_INTERRUPTED, call at once. For ACCOUNT_BLOCKED and LEDGER_REFUSED, fix the cause first and do not call automatically. Call Credit a received Pix whose ledger credit is parked or Credit a received Pix refund whose ledger credit is parked to credit it. The call never credits twice: it asks Midaz first, and it answers 409 with PIX-0474 when Midaz cannot confirm the credit; reconcile it by hand. The caller needs the permission to post transfers, or refunds for the refund route.

Fraud check on incoming Pix

Your institution can check an incoming Pix with its own fraud system before Pix Lerian approves it. The check is off by default. Each tenant turns it on in the SPI runtime configuration. Pix Lerian checks the destination account first. A Pix that the account check refuses does not reach your endpoint. Pix Automático settlements and incoming returns are not checked.

The request

Pix Lerian sends one POST request with a JSON body:
  • contractVersion: 1.0.
  • eventType: PIX_CASHIN.
  • approvalId: a UUID. Every request about the same Pix carries the same value.
  • requestedAt and respondBy: UTC timestamps. respondBy is the time by which Pix Lerian expects your answer.
  • cashin: the amount, the endToEndId, the payer (debitParty), the payee (creditParty), and the account that receives the credit (account).
Each request carries these headers:
  • X-Webhook-Timestamp: the Unix time, in seconds, of the signature.
  • X-Webhook-Signature: v1,sha256=<hex>, where <hex> is the lowercase HMAC-SHA256 of v1:<timestamp>.<raw body> with antifraud_hook_secret as the key.
  • Idempotency-Key: the approvalId.
  • Your header, when you set one.
Verify the signature over the raw body before you decide.

The answer

Answer with a 2xx status and a JSON object with a decision field:
  • APPROVE or ALLOW: Pix Lerian approves the Pix.
  • REJECT, DENY, or REVIEW: Pix Lerian refuses the Pix with the reason code FRAD, and nothing is credited. When the answer carries the reason AG01, the refusal goes out with AG01 instead, and the operation reports PIX-0458.
Pix Lerian can ask again about the same Pix with the same Idempotency-Key. Give the same decision each time.

When your endpoint does not answer

Pix Lerian applies the fallback decision when it gets no decision: on a timeout, a connection error, a status outside 2xx, a redirect, an answer it cannot read, or an incomplete configuration. After repeated failures, Pix Lerian stops calling your endpoint for a short time and applies the fallback. A refusal by the fallback goes out with the reason code DS04.
The default fallback is APPROVE. With this default, while your endpoint does not answer, Pix Lerian approves incoming Pix without your check, up to antifraud_hook_fallback_max_approve_amount when you set it.

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 original response with the header X-Idempotency-Replayed: true. The value stays bound to the refund until the refund is FAILED. A retry that changes the transfer, the amount, the reasonCode or the reason answers 412 (PIX-0031). 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. The API reference calls each hold a cautionary block: see Create a cautionary block, Settle a cautionary block and Release a cautionary block to the account holder. The DICT refund routes settle the holds of a MED refund: see DICT.
  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. Close a hold after a manual return, return a settlement surplus to the account holder, and read the audit records with the routes in the API reference under Cautionary blocks.
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.