Skip to main content
Plugin SISBAJUD runs judicial orders on the client’s Midaz ledger. The orders come from the Mensageria or, on the direct channel, from the institution’s own system. This page describes how the plugin receives an order, what each operation writes, and how the plugin reports the result. Operating Plugin SISBAJUD describes the setup. How Lerian SISBAJUD works shows how an order moves from the Mensageria to Plugin SISBAJUD.

Order lifecycle


  1. Notice. The Streaming Hub posts an execution notice to the webhook listener of the plugin. The notice carries the order ID and the order revision, not the order.
  2. Verification. The plugin verifies the HMAC signature of the delivery. It stores each signed notice before it answers.
  3. Fetch. The plugin gets the order with GET /v1/sisbajud/execution/orders/{orderId} on the execution API of the Mensageria.
  4. Owner check. Before its first write, the plugin checks that it owns the institution of the order.
  5. Execution. On its next cycle, the plugin runs the operation on Midaz.
  6. Result. The plugin posts the result with POST /v1/sisbajud/execution/orders/{orderId}/execution-results.

Webhook answers

The plugin accepts a delivery with a timestamp outside EXECUTOR_HUB_WEBHOOK_MAX_SKEW_SEC, and logs a warning.

Fetch answers

Owner check

The plugin writes on the ledger only for the institutions that it owns. When it creates an institution, it records its own M2M subject (EXECUTOR_M2M_SUBJECT) as the owner.
  • If another identity owns the institution, the plugin writes nothing and raises an alarm.
  • If the institution has no configuration on this plugin, the order goes to a human decision.

Execution cycle

The plugin runs one cycle every EXECUTOR_TICK_EVERY. The default is 30s. Each cycle runs three steps in this order:
  1. Ingest. Runs the accepted notices.
  2. Orphan check. Looks for operations on the block accounts that the plugin did not write.
  3. Monitor. Sends a heartbeat for each write that has no known outcome.
A failed step does not stop the other steps. The plugin drains the results that wait in the outbox in a separate loop for each channel, so a slow channel does not hold the cycle or another channel.

Results

The plugin stores each result in an outbox before it posts it. Each post carries the X-Idempotency header. When a post fails with a transient error, the plugin posts the same result again after a wait, up to EXECUTOR_RESULT_MAX_ATTEMPTS attempts. The default is 12. After the last attempt, the plugin parks the result, records a human decision, and raises an alarm. It does not post a parked result again, and the subsequent versions of the same order wait behind it. A platform administrator re-arms the result. Operating Plugin SISBAJUD describes the route. The reasonCode of each operation is in the sections below.

Operations


The block and the unblock write on Midaz. The information request only reads.

Block (BLOQUEIO)

  1. The plugin reads the active accounts of the subject. A subject with no active account gets NONE with NO_CLIENT.
  2. It applies the branch and account restriction of the order. Branch and account restriction gives the rules.
  3. It blocks a salary account only when the order allows salary accounts.
  4. It blocks own funds only. An account in overdraft counts as 0.
  5. It sends one write to Midaz. The write has one leg for each source account, and all legs go into the block account of the order.
A block order can carry a minimum amount. When the total that the plugin can block is below that minimum, it writes nothing and hands the order to a human decision.

Branch and account restriction

The plugin reads the branch and the account number of each account from the CRM instruments of the subject. With crmMode embedded, the branch is bankingDetails.branch and the account number is bankingDetails.account. With crmMode legacy, the CRM gives neither.
  • An order that names a branch goes to a human decision when an account that can be the named one has an unknown or ambiguous branch.
  • An order that names an account number blocks the accounts whose number matches. It also blocks an account whose number is unknown or ambiguous, up to the order amount, because that account can be the one that the court named. The accounts whose number matches come first. With crmMode legacy, no number is known, so every account that passes the branch rule can be blocked.
  • An order with an account number and no branch goes to a human decision when two or more accounts match.
  • With an account number, the result is NONE when every account number is known and none matches.

Unblock (DESBLOQUEIO)

The unblock releases funds of a parent block order, identified by parentOrderId. The plugin uses the parent block’s recorded origin account as the release destination. If it cannot safely determine one destination, it requires a human decision rather than guessing.
  • Without a parent, the result is NONE with PARENT_UNRESOLVED, and the plugin writes nothing.
  • When the parent has no known effect yet, the plugin waits. At the order deadline minus RESPONSE_DEADLINE_MARGIN, the order goes to a human decision. If the order has no deadline, it goes to a human decision at once.
  • The plugin reads the block account of the parent when it runs the order. It releases the smallest of three amounts: the amount that the order asks, the remaining balance of the parent, and the balance of the block account.
  • When the release amount is 0, the result is NOTHING_TO_RELEASE.
  • When a subject account is a salary account, the order goes to a human decision.

Information request (REQUISICAO_INFORMACAO)

The plugin reads the balances of the subject and writes nothing on the ledger. If the subject is a client but does not own the specified account, the plugin requires a human decision rather than reporting that the subject is not a client.
  • A subject with at least one active account gets FULL with INFO_FULFILLED.
  • A subject with no active account gets NONE with INFO_NON_CLIENT.
  • An order that names a branch goes to a human decision.
When the order asks for the balance (searchBalance), the result carries two totals: the blockable total and the blockable total of salary accounts. A subject with no active account gets 0.00 in both.

Direct channel


On the direct channel, the institution’s own system sends judicial orders to the plugin, and the Mensageria is not involved. The plugin stores each order, runs it on Midaz, and keeps the results. The institution reads the results and answers the court itself. The plugin serves the direct channel only when it runs in executor mode, with one tenant, and PLUGIN_AUTH_ENABLED on. Otherwise the five direct routes answer 501. A platform administrator switches an institution to the direct channel with PUT /v1/institutions/{institutionId}/channel. The switch needs all of these:
  • The plugin owns the institution.
  • The stored institution code is the 8-character CNPJ root of the responsible grouping.
  • The institution has no open order, and no block of the institution still holds money.
The same route switches the institution back to the Mensageria. An institution that is not on the direct channel gets 422 SBJ-0025 on a direct order. The results feed delivers each result at least once. Deduplicate by orderId, orderRevision, and executionVersion. Submit an unblock or a transfer only after the 202 of its parent block. The direct channel takes BLOCK, UNBLOCK, TRANSFER, INFO, and INTERRUPT. A transfer moves funds from the block account of its parent to the judicial deposit account of the institution. An interruption stops a permanent block and keeps what the block already holds. DIRECT_PERMANENT_BLOCK_ENABLED decides whether the channel takes a new permanent block. With the default, it refuses one with 422 SBJ-0027. A permanent block keeps blocking new credits of the subject, up to the order amount. The plugin reads those credits from the Midaz ledger events. It lasts one year from receipt, or until the court date when the order gives one, and never more than one year. When the term ends, the block stops taking new credits and keeps what it already holds. An interruption, a transfer or an unblock of the remainder, or a cancellation closes it. When a later block of a permanent block keeps failing, the plugin parks the attempt, raises an alarm, and stops taking new credits for that block until a platform administrator resolves the attempt. A direct order that fails on every attempt, or reaches its cut while the ledger fails, is parked too. Its read shows parked true. The machine roles order-submitter and result-reader call these routes. Operating Plugin SISBAJUD describes them.

Erase a direct-channel order

A platform administrator erases one concluded direct-channel order with POST /v1/admin/direct/orders/{orderId}/erase, for an LGPD request from the data subject or at the end of retention. POST /v1/admin/direct/purge lists the orders that can be erased now and changes nothing. Both operations need a user token with no tenant, and they answer only on a single-tenant installation. After the erase, nobody can read the content submitted with the order again: the order body and the document number of the person or company that the order targets. The erase cannot be undone. Your clientOrderId and externalReference become tokens. A lookup by the original externalReference still finds the erased order, with its content hidden. The erase does not remove:
  • the court protocol and the sequence numbers of the order;
  • the plugin’s ledger journal, with its amounts, and the Midaz transactions;
  • the results already in the results feed, and what your system already read from it;
  • the audit entry of the erase;
  • backups taken before the erase. After you restore one, erase the order again.
The plugin never erases an order by itself. The erase refuses an order that is still open, still holds money, or has an open child order. It also refuses a block order less than one year after its first ledger posting, and a permanent block before its end date. When an order stays eligible longer than EXECUTOR_DIRECT_PURGE_ELIGIBLE_ALARM_AFTER (default 168h), the plugin logs an error so that an administrator reviews it.

Ledger semantics


Block account

The alias of the block account has the prefix @block_sisbajud_ and then the 32 lowercase hexadecimal digits of the block order ID. An unblock finds the account through its parentOrderId. The account type of a block account is sisbajud_block. If your ledger validates account types, register sisbajud_block as an account type.

Directions

  • A block decreases the subject accounts and increases the block account.
  • A transfer decreases the block account of its parent and increases the judicial deposit account.
  • An unblock decreases the block account. Its write has one source leg: the block account. It releases funds to the recorded origin account, or requires a human decision when one safe destination cannot be determined.
A block moves the amount from the available balance of each subject account to the available balance of the block account.

Idempotency

Each write carries the X-Idempotency header and X-TTL: 604800, which is seven days. Midaz keeps the idempotency key of a write for that time. The key is orderId:orderRevision, so a redelivery of the same order revision sends the same key.

Uncertain writes


When Midaz answers a write without proof of its effect, the outcome is INDETERMINATE. The plugin reads the ledger again before each heartbeat. It sends a heartbeat result to the Mensageria every EXECUTOR_HEARTBEAT_EVERY, until the Mensageria answers that the order revision is superseded. The order goes to a human decision at the first of two limits:
  • EXECUTOR_HUMAN_DECISION_AFTER_BEATS heartbeats without a change. The default is 3.
  • The order deadline minus RESPONSE_DEADLINE_MARGIN.
The plugin then records a human decision. In the human-decisions list it has humanDisposition HELD_MONEY_MOVED. The heartbeats continue, with executionState and effect both INDETERMINATE.

Ledger down at the cut

The cut of an order is its deadline minus RESPONSE_DEADLINE_MARGIN. When Midaz fails for an order of the Mensageria at or after the cut, and no court result of that revision waits in the outbox, the plugin stops its retries. It records a human decision and sends no result. Check the ledger and answer the court yourself before the deadline. Otherwise the Mensageria records a non-response.

After a person answers

Take a revision that was handed to a person at its cut, or that a person resolved as effect-acknowledged or proven-no-effect. When its write lands on Midaz afterwards, the plugin sends no FULL or PARTIAL result for it. It records the effect and raises an alarm. The court gets only the answer of the person, so reconcile a late effect on the ledger yourself.

Operations that the plugin did not write

The orphan check reads the operations of each block account over EXECUTOR_ORPHAN_RECONCILE_WINDOW. The default is 48h. The plugin reports an operation as an orphan when its transaction has no metadata.code, or has a code that the plugin did not record. This step only detects. It changes nothing on the ledger.

Accounting routes


Accounting routes are optional, per organization. The plugin reads them from the tenant documents routing.organizations and routing.ledger_bindings in the Systemplane. With SYSTEMPLANE_ENABLED off, the plugin writes without routes. With routing.organizations at schemaVersion 2, each organization carries its own routes for each flow and the list of ledgers that post with them. The plugin then does not read routing.ledger_bindings. A write to a ledger that is not on the list of its organization goes out without routes. When a write cannot go out because of its configuration, the plugin defers it. Midaz has applied nothing, so the order waits, and a later delivery sends the same write with the same idempotency key. These conditions defer a write:
  • The plugin cannot resolve the accounting routes of the write.
  • Midaz refuses the accounting routes of the write: 422 with code 0113, 0114, 0116, 0117, 0118, 0119, 0152, or 0157, or 404 with code 0105.
Fix the configuration before the order deadline. GET /v1/admin/ledger-routing/preflight checks the configuration before you turn on routes.

Midaz calls


The plugin calls the Midaz ledger at the baseUrl of each institution, with the token of that institution. Give the credentials of the institution access to these operations: The plugin finds the accounts of a subject through the Midaz CRM. With crmMode legacy, it calls GET /v1/aliases?document= at crmBaseUrl. With crmMode embedded, it calls GET /v2/organizations/{organizationId}/instruments?document= at baseUrl.