> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Use SPI with Pix Lerian

> Run Pix Lerian cash-out, cash-in callback, refund, and MED 2.0 balance-hold flows with Midaz and a connectivity adapter.

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.

> [!NOTE]
>
> 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](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/initiate-transfer.md) 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](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/process-transfer.md) for that initiation. The plugin performs the required Midaz debit and submits work to the connectivity adapter.
3. Read the transfer with [Get transfer](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/get-transfer.md). 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.

## 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.

| Setting | Default | What it does |
| - | - | - |
| `antifraud_hook_enabled` | Off | `true` turns the check on. |
| `antifraud_hook_url` | None | The address of your decision endpoint. It must use `https` and resolve to a public address, unless `ANTIFRAUD_HOOK_ALLOW_PRIVATE_NETWORK` is `true`. |
| `antifraud_hook_secret` | None | The key that signs each request. At least 16 characters. |
| `antifraud_hook_timeout_ms` | `500` | How long Pix Lerian waits for a decision, from `100` to `5000` milliseconds. |
| `antifraud_hook_fallback_decision` | `APPROVE` | `APPROVE` or `REJECT`: the decision Pix Lerian applies when it gets no decision from your endpoint. |
| `antifraud_hook_fallback_max_approve_amount` | None | With the `APPROVE` fallback, Pix Lerian approves an amount up to this value and refuses a higher amount. |
| `antifraud_hook_auth_header_name`, `antifraud_hook_auth_header_value` | None | One header that Pix Lerian adds to each request, for example for an API gateway. Set both or neither. |

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.

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`.

> [!WARNING]
>
> 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](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/create-refund.md) against an eligible transfer, then read it through [Get refund](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/get-refund.md). `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](https://docs.lerian.studio/en/reference/interfaces/pix-lerian/spi/list-refunds.md) 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](https://docs.lerian.studio/en/interfaces/pix-lerian/pix-lerian-dict.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.