Batch payment and payroll file processing¶
| ID | MOD-135 |
| System | SD04 |
| Repo | bank-payments |
| Build status | Deployed |
| Deployed | Yes |
| Last commit | 7d0a97fa62d6890adcddc1b1f579549a73d236ef |
Purpose¶
Batch payment and payroll file processing allows business and SME customers to upload a structured payment file and initiate multiple outbound payments in a single operation. The source account is debited for the total settled amount; each individual beneficiary receives a separate credit. This is the primary mechanism for payroll runs, creditor payment runs, and supplier disbursements.
Supported file formats¶
ABA (Australian Bankers Association)¶
The ABA format is the standard for Australian payroll and creditor payment files. The file structure is fixed-width with a descriptive header record (Type 0), detail records (Type 1), and a file total record (Type 7).
Key validation requirements:
- BSB must be in the format NNN-NNN and must exist in the BSB directory
- Account numbers are 1–9 digits, right-justified, zero-padded
- Transaction codes must be within the permitted set (13, 50, 51, 52, 53, 54, 55, 56, 57)
- The Type 7 hash total must equal the sum of all BSB digits from detail records (standard ABA hash); mismatch is a hard rejection
- Amounts are in cents (integer); no decimal point in the file
CSV (NZ and AU)¶
A CSV format is accepted for both NZ and AU customers. The column specification is fixed and must be present in the header row in this order:
| Column | Description | Format |
|---|---|---|
beneficiary_account |
Account number or IBAN (AU: BSB+account, NZ: full 16-digit) | TEXT |
beneficiary_name |
Name of receiving party | TEXT ≤ 32 chars |
amount |
Payment amount | DECIMAL(12,2) |
reference |
Payment reference visible to beneficiary | TEXT ≤ 12 chars |
particulars |
Additional detail (NZ only; ignored for AU) | TEXT ≤ 12 chars |
Files with a missing or mis-ordered header row are rejected at format validation.
Validation rules¶
Format validation is applied before the file is accepted into the processing queue. Any file that fails format validation is rejected in full with a structured error response identifying the failing row number and field name. Partial processing of a format-invalid file is not permitted.
Validation checks, in order:
- File format detection — file extension and header row determine format (ABA or CSV); ambiguous files are rejected
- Encoding — UTF-8 required; BOM is accepted and stripped
- Row count — must be at least 1 detail record; files with zero payment rows are rejected
- Account number format — per-jurisdiction: AU BSB+account validated against the BSB directory; NZ 16-digit format validated against the bank/branch prefix list
- Amount range — each item amount must be greater than zero and within the per-transaction limit set on the source account; items exceeding the per-transaction limit are flagged as validation errors, not quarantined
- ABA hash total — checked for ABA files (see above)
- CSV item count — row count in the body must match the value declared in the CSV header (if present)
Processing model¶
The platform uses a best-efforts model, not all-or-nothing. This matches the behaviour of the BECS clearing system in AU and the direct credit interchange in NZ.
- The source account is debited for the total amount of items that pass validation and are successfully submitted
- Items that fail validation are rejected before submission and are not charged
- Items that generate an AML screening alert are quarantined after submission; the amount for quarantined items is not debited until the alert is resolved
- Items where the credit cannot be posted (account closed, invalid account number) generate a return; the return credit is applied to the source account within the same business day
The customer sees a clear distinction between: items rejected at validation (never charged), items quarantined at screening (charged pending resolution), and items returned after submission (credited back).
Data model¶
-- One record per uploaded batch file
CREATE TABLE payments.batch_files (
batch_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID NOT NULL REFERENCES core.accounts(account_id),
file_format TEXT NOT NULL CHECK (file_format IN ('aba', 'csv')),
item_count INTEGER NOT NULL,
total_amount NUMERIC(15, 2) NOT NULL,
status TEXT NOT NULL CHECK (status IN (
'uploaded',
'validating',
'pending_approval',
'processing',
'settled',
'failed'
)),
submitted_at TIMESTAMPTZ,
settled_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- One record per payment item within a batch
CREATE TABLE payments.batch_items (
item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
batch_id UUID NOT NULL REFERENCES payments.batch_files(batch_id),
beneficiary_account TEXT NOT NULL,
beneficiary_name TEXT NOT NULL,
amount NUMERIC(12, 2) NOT NULL,
reference TEXT,
status TEXT NOT NULL CHECK (status IN (
'pending',
'submitted',
'settled',
'failed',
'quarantined'
)),
failure_reason TEXT, -- populated for failed and quarantined items
posting_id UUID, -- references the MOD-001 posting once settled
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
status on batch_files follows the lifecycle: uploaded → validating → pending_approval (customer confirmation step) → processing → settled or failed. Individual batch_items have their own status that progresses independently after the batch moves to processing.
Key operations¶
Upload and validate¶
The customer uploads a file via the app or API. The module detects the format, runs the full validation sequence, and either accepts the file (status: pending_approval) or rejects it with a structured error list. Validation errors are returned with row numbers and field names so the customer can correct and re-upload.
Customer confirmation¶
Before any payment is processed, the customer is presented with a confirmation screen showing: total number of items, total amount, source account, and — where format validation identified any issues — a summary of rejected items. The customer must explicitly confirm before the batch moves to processing. No batch is processed silently.
AML screening pass¶
Once the customer confirms, each item is passed through the transaction screening engine (MOD-023) and the AML transaction screening engine individually. Items that generate no alert move to submitted. Items that generate an alert move to quarantined with the reason recorded in failure_reason. The remaining non-alerted items continue to submission without waiting for quarantined items to be resolved. The customer is notified of quarantined items within 60 seconds of submission via MOD-063.
Submission and settlement¶
Validated, non-quarantined items are submitted to the clearing system. The source account is debited for the total of submitted items via MOD-001. Each credit is posted as a separate atomic transaction. The batch status moves to settled when all non-quarantined items have a final status (settled, failed, or returned).
Failure handling¶
Items that cannot be credited (account closed, account number not found, returned by the receiving bank) generate a return. The return triggers a re-credit to the source account via MOD-001 within the same business day. The batch_items record is updated to failed with the return reason in failure_reason. The customer is notified of returns via MOD-063.
Batch-level failures (e.g. source account closed mid-batch, system error during processing) move the batch to failed. Items not yet submitted at the point of batch failure are not charged.
Settlement reconciliation¶
End-of-day reconciliation for batch files runs via the payment reconciliation engine (MOD-081). The reconciliation confirms that the sum of settled batch_items amounts matches the clearing settlement file and that the source account debit matches the total of posted credits plus any outstanding returns.
Requirements¶
FR-601 — System shall validate each batch file against the declared format specification (ABA field positions and hash total for AU; CSV column spec and row count for NZ/AU) before accepting the file, rejecting files that fail format validation with a structured error identifying the failing row or field, and must not partially process a file that fails format validation.
FR-602 — System shall check the source account's available balance against the total batch amount via MOD-020 before processing any items; if funds are insufficient for the full batch, the system must present the shortfall to the customer and must not process the batch until the customer confirms they want to proceed with partial funding or until sufficient funds are available.
FR-603 — System shall screen each batch item through the transaction fraud scorer (MOD-023) and the AML transaction screening engine independently; items that generate a screening alert must be quarantined with status quarantined and reason recorded; quarantined items must not block non-alerted items from being submitted; the customer must be notified of any quarantined items within 60 seconds of the batch being submitted.
FR-604 — System shall post the source account debit and each individual beneficiary credit via MOD-001 as separate atomic transactions — the source debit for the total settled amount and each credit must both succeed or both fail; a credit that cannot be posted (account closed, invalid account) must be returned and the corresponding source account amount re-credited within the same business day.
Module dependencies¶
Depends on¶
| Module | Title | Required? | Contract | Reason |
|---|---|---|---|---|
| MOD-001 | Double-entry posting engine | Required | — | The source account debit and each individual beneficiary credit are posted as atomic pairs via the double-entry posting engine. |
| MOD-020 | Pre-payment validation suite | Required | — | One aggregate balance gate (FR-602) plus one per-item validate-payment invoke (FR-603) — MOD-020 invokes MOD-023 fraud scoring and MOD-013 sanctions screening transitively on each per-item call. No direct MOD-023 or MOD-013 invocations from MOD-135. |
| MOD-081 | Payment reconciliation engine | Optional | — | Batch-level reconciliation is owned by MOD-135 in v1. MOD-081 will add the BATCH rail to its V1_MATCH_RAILS in v2. |
| MOD-063 | Notification orchestration | Required | — | Quarantine alerts (FR-603 within 60 s), return notifications (FR-604), and batch settlement confirmation dispatched via bank.payments.* events; MOD-063 catch-all rule covers all six new event types. |
| MOD-103 | Neon database platform bootstrap | Required | — | Neon database and schema provisioned by MOD-103 must exist before this module can read or write Postgres. |
| MOD-104 | AWS shared infrastructure bootstrap | Required | — | AWS shared infrastructure provisioned by MOD-104 (IAM role, EventBridge bus, SNS, KMS, S3) is required before this module can be deployed. |
Required by¶
(No modules in this wiki currently declare a dependency on this module.)
Policies satisfied¶
| Policy | Title | Mode | How |
|---|---|---|---|
| PAY-001 | Payment Operations Policy | GATE |
Source account available balance is checked against the total batch amount before any item is processed; if funds are insufficient the batch is held and the customer notified. |
| AML-007 | Sanctions Screening Policy | AUTO |
Each payment item in the batch passes through the transaction screening engine before being submitted; items that generate a screening alert are quarantined and the batch continues with remaining items. |
| PAY-002 | Settlement Risk Policy | LOG |
Every batch file, every item within it, and every submission outcome is logged to the payment audit trail. |
| CON-005 | Fee & Pricing Transparency Policy | AUTO |
Customers uploading a batch must confirm the total amount and payment count before submission — no silent batch processing. |
Capabilities satisfied¶
(No capabilities mapped)
Part of SD04 — Payments Processing Platform
Compiled 2026-05-22 from source/entities/modules/MOD-135.yaml