Skip to main content

Approval Workflow

Every financial transaction posted to SIL is checked against the account's SIL debit limit and SIL credit limit. A breach does not reject the transaction — it is held for supervisor approval.

When approval kicks in​

ConditionResult
Debit > SITDebitLimitHeld: Status = Pending, ApprovalStatus = PendingApproval
Credit > SITCreditLimitHeld: Status = Pending, ApprovalStatus = PendingApproval
Within limitsPosted: Status = Posted, ApprovalStatus = NotRequired

While held:

  • No balance impact is applied to the primary or counterparty accounts.
  • The double-entry rows are written but RunningBalance is null.
  • No SITSyncQueue row is created — the transaction is not visible to the replay worker.

Lifecycle​

SITApproveTransactionCommand​

Approve a held transaction. The handler:

  1. Re-loads the transaction and validates it is still Status = Pending / ApprovalStatus = PendingApproval.
  2. Re-validates the primary account is not currently Frozen, Closed or Dormant — the account state may have changed since the transaction was held.
  3. Recomputes the leg impact directly from the persisted SITTransactionEntry rows (deterministic, no re-derivation from TransactionType).
  4. Re-checks sufficient funds for debits at approval time.
  5. Applies balance to primary + counterparty; backfills RunningBalance on every entry.
  6. Sets Status = Posted, ApprovalStatus = Approved.
  7. Inserts the SITSyncQueue row so the hosted worker now replays it to core.

Cmd: SITApproveTransactionCommand

Request​

Provide one of:

{ "data": { "sitTransactionId": "<guid>" } }
{ "data": { "transactionReference": "WDR-20260427-0001" } }

Response​

{
"isSuccessful": true,
"message": "SIT transaction approved.",
"data": {
"sitTransactionId": "...",
"transactionReference": "WDR-20260427-0001",
"status": "Posted",
"approvalStatus": "Approved",
"newAvailableBalance": 149300.00,
"newLedgerBalance": 149300.00
}
}

Error cases​

StatusCause
400Neither sitTransactionId nor transactionReference supplied
404Transaction not found
409Transaction is not awaiting approval (already approved, rejected, or pending)
409Account is now Frozen, Closed or Dormant
409Insufficient SIT available balance at approval time

SITRejectTransactionCommand​

Reject a held transaction. Sets Status = Rejected, ApprovalStatus = Rejected. No balance impact, no replay queued.

Cmd: SITRejectTransactionCommand

Request​

{
"cmd": "SITRejectTransactionCommand",
"data": {
"transactionReference": "WDR-20260427-0001",
"reason": "Customer not at counter"
}
}

The optional reason is appended to the transaction narration for audit.

Response​

{
"isSuccessful": true,
"message": "SIT transaction rejected.",
"data": {
"sitTransactionId": "...",
"transactionReference": "WDR-20260427-0001",
"status": "Rejected",
"approvalStatus": "Rejected"
}
}

SITCancelTransactionCommand​

Cancel a held transaction. This is the initiator self-service action — only the teller who created the transaction may cancel it. A supervisor must use SITRejectTransactionCommand instead.

Sets Status = Cancelled, ApprovalStatus = Cancelled.
No balance impact, no replay queued.

Permission: bnk_sit_cancel_transaction
Cmd: SITCancelTransactionCommand

Request​

{
"cmd": "SITCancelTransactionCommand",
"data": {
"transactionReference": "WDR-20260427-0001",
"reason": "Customer changed mind"
}
}

Accepts sitTransactionId (GUID) or transactionReference. The optional reason is appended to the narration for audit.

Response​

{
"isSuccessful": true,
"message": "SIT transaction cancelled.",
"data": {
"sitTransactionId": "...",
"transactionReference": "WDR-20260427-0001",
"status": "Cancelled",
"approvalStatus": "Cancelled"
}
}

Error cases​

StatusCause
400Neither sitTransactionId nor transactionReference supplied
403Caller is not the teller who initiated the transaction
404Transaction not found
409Transaction is not awaiting approval (already approved, rejected, cancelled, or posted)
Reject vs Cancel

Use Cancel when the initiating teller wants to withdraw their own submission.
Use Reject when a supervisor declines a pending transaction.


Listing pending-approval transactions​

Use GetSITTransactionListQuery with a filter:

{
"cmd": "GetSITTransactionListQuery",
"data": {
"filters": [
{ "field": "ApprovalStatus", "operator": "equals", "value": "PendingApproval" }
]
}
}

This is the standard backing query for a "Pending SIL approvals" supervisor screen.