Banking & Reconciliation
Import bank statements, match transactions, and reconcile multiple accounts in Anchor, including ZAR and foreign-currency accounts for SA books.
Bank Accounts
Create bank accounts linked to your chart of accounts. Each account owns its own statement imports, transactions, and reconciliation workflow.
Fields
| Field | Description |
|---|---|
| Account Name | Display name (e.g., "Business Checking") |
| Account Number | Masked number for display |
| Bank Name | Name of the bank |
| Currency | Account currency |
| Country | Country or region of the account |
| Account Type | Checking, savings, credit card, cash, loan, investment, or other |
| Accent Color | Visual identity used across the banking UI |
| GL Account | Chart of accounts link |
Statement balance
The balance on Accounting → Banking is the statement balance: what your bank says is in the account. A new account starts at 0.
If that figure does not match your bank, open the account, go to Settings, and enter the balance from your latest statement or banking app under Statement balance. Use a negative amount for an overdrawn account or a credit card balance owed.
Changing the statement balance does not post anything to your books. The balance of the linked account in your books comes from opening balances and the transactions you record, and the reconciliation report shows any difference between the two.
List totals
At the top of Accounting → Banking:
| Figure | What it adds up |
|---|---|
| Total Balance | The statement balances of all accounts |
| Positive balances | Accounts with a balance above zero |
| Negative balances | Accounts below zero (overdrawn accounts, credit cards owed), shown as a positive amount |
These split the total by sign. They are not money received and money paid. Open an account to see Money In and Money Out, which add up that account's transactions.
Add a transaction manually
If a statement import skipped a few lines (parse error, incomplete file, etc.), you do not need to re-import everything:
- Open the bank or credit-card account.
- Click Add transaction (header, or on the Transactions tab).
- Enter date, type (Money out for purchases/charges, Money in for payments/refunds), description, and amount. Add more rows if needed.
- Save — lines appear under Transactions → To do.
- Categorize (or match invoice/bill) as usual — pick the category, VAT/tax, and optional customer/supplier there (same as for imported lines), then tick them on the statement check if you use Reconcile.
Duplicates of existing lines (same date, amount, description) are not added again.
Importing Transactions
Import bank statements into a specific bank account:
- Navigate to your bank account
- Click Import Statement
- Upload a file or paste raw statement data
- Preview detected rows, duplicates, warnings, and date ranges
- Confirm the import
Supported formats:
- CSV
- TSV
- QIF
- OFX / QFX / QBO
- CAMT.052 / CAMT.053 / CAMT.054
- MT940 / MT942
- BAI2
- PDF statements from Capitec Business, FNB, Nedbank, Absa and Standard Bank, after a balance check (see PDF statements)
- JSON lines (
json_lines) — structured API import (POST …/transactions/import-lines). Amounts are integer cents; lines stay unreconciled (no bank-rule auto-reconcile on ingest).
Every imported transaction stores provenance such as the import batch and source format.
How an import changes the account balance
- The file has a closing balance (OFX, CAMT, MT940 usually do): the account balance becomes that closing balance, including zero.
- The file has a running balance column (a CSV with a Balance column): the account balance follows the last imported running balance.
- The file has no balance at all (many CSV and TSV exports): the imported amounts are added to the balance already stored, and a new account starts at 0. That figure is not a balance printed by the bank, and the preview and the import message say so. Importing several files adds each one's new lines; lines already imported are skipped and not added again.
- BAI2 files do not change the account balance.
When the file has no closing balance, you can type the closing balance printed on the statement after Preview, under Closing balance on this statement. The account balance is then set to that figure, and a warning shows if it does not match the previous balance plus the imported amounts. Leave it blank to add the amounts instead. BAI2 files and files that already include a closing balance do not show the field. After an import without a closing balance, the message offers Set statement balance, which opens the account's settings.
An opening balance entered under Accounting → Opening balances updates the books. It does not by itself change the balance on Accounting → Banking.
The banking UI loads all transactions for an account (paginated API, max 100 per request, walked client-side) so credit-card months with 50+ lines are fully visible — filters and counts apply to the complete set.
Apply bank rules after import
Structured API imports intentionally do not auto-categorise on ingest. After lines appear under Transactions:
- Configure patterns under Settings → Bank Rules:
- Get Suggestions — mines descriptions you already categorised the same way at least twice and proposes “description contains … → account” rules. Create rule saves immediately; Review opens the editor first. Patterns already covered by an active rule are omitted. Generic words (
payment,transfer,service, etc.) are never suggested — prefer merchant names. - Categorise to account — fee/interest/merchant → chart account.
- Settle open invoice/bill — pin a contact; create a payment when the bank amount matches open documents (exact amount, document number in the narrative, or optional FIFO). Choose review first to queue proposals, or post immediately on Apply. Leave the contact empty to pay the customer or supplier whose account code (e.g.
ACM001) appears in the bank description or reference; lines without a code, or with codes of more than one contact, are left for you to match. The first matching rule wins, so give such a rule a low priority or a narrow condition.
- Get Suggestions — mines descriptions you already categorised the same way at least twice and proposes “description contains … → account” rules. Create rule saves immediately; Review opens the editor first. Patterns already covered by an active rule are omitted. Generic words (
- Open the bank account → Transactions → Apply bank rules.
- Matching to-do lines use the first matching rule (by priority). Settle proposals appear in a review panel (Confirm / Dismiss). Optional auto-settle on classic statement import requires both the rule’s “Settle on import” and the org flag
bankRuleAutoSettleEnabled(API import-lines never auto-settle).
Use Assign in bulk or the bank line Match invoice / Match bill button for one-offs. Tick one or more open invoices (or bills) for the same customer/supplier, set how much of the deposit applies to each. For Match invoice, allocated may be less than the bank amount — the remainder is held on account as a customer credit (overpayment) and can be applied later from the invoice. Match bill still requires allocated = bank amount. Use Fill FIFO to auto-fill oldest-due first. ⋯ → Find & match links existing payments/journals or a single open document. The document lists show the contact's account code and can be searched by it. When a customer or supplier's account code appears in the bank description or reference, all their open documents are listed first and rank higher in the suggestions (reason Contact code in bank reference). While ARIA is on, open documents whose amount due equals the bank amount exactly also rank by how closely the bank text resembles the document or its contact, when the text clearly points to one customer or supplier (reason Bank text closest to this contact or document), so a cut-off line such as PLUMB* can still find the plumber's bill. Bank rules settle design: docs/design/bank-rules-settlement.md; multi-doc match: docs/design/multi-invoice-bank-match.md.
Category default tax
When you Assign to a category, Record as expense, Split, or Assign in bulk, picking a chart account applies that account’s default tax (if set under Chart of Accounts → Settings). Bank rules use rule-level tax when set; otherwise they inherit the account default at apply time.
Bank notification email
Each organisation has a stable bank notification address:
{your-organisation-id}@anchorapp.co.zaShown on Accounting → Banking (copy button). Forward bank alerts and statement emails to that address. Anchor matches the local-part to your organisation and stores the message. Supported one-transaction alerts (currently Absa NotifyMe labelled emails: Account / Date / Amount / Transaction) are parsed into unreconciled bank lines when the account can be identified (e.g. CHEQ8381 → an Absa account ending 8381). They do not post to the general ledger; categorise or match them like a statement import. Welcome and other non-transaction mail is marked ignored. Statement files attached to the email (CSV, OFX, QIF, CAMT, MT940, BAI2, or a PDF from a supported bank) can be imported from the Banking panel.
Card purchases: Absa sends a card purchase alert when the card is authorised, with the amount as Reserved and the shop as Merchant. Anchor imports it as money out at the reserved amount, described by the merchant name. Absa sends no second alert when the purchase clears, so if the final amount differs (tips, fuel, hotel deposits), edit the line. If you also import a bank statement for the same period, the statement describes these purchases differently and they may appear twice; delete the duplicate lines, or import statements only for months without alerts.
PDF statements
Anchor reads computer-generated PDF statements from Capitec Business, FNB, Nedbank, Absa and Standard Bank, forwarded to the notification address or uploaded on Banking → account → Import statement. Scanned or photographed statements and other banks are not supported: download a CSV or OFX statement from your bank's online banking instead.
Password-protected PDFs: some banks email statements that need a password to open. Anchor asks for it: in the Banking panel, choose the bank account, type the password and click Open; on Import statement, a password field appears after Preview. Anchor uses the password only to open that file for that preview and import, and does not keep it, so you type it again for each statement. After ten wrong passwords Anchor stops trying for 15 minutes. Once the PDF is open, the usual rules apply: it must be from a supported bank and pass the balance check.
Every PDF must pass a balance check before anything is imported: each line follows from the previous balance, the opening balance plus all lines equals the closing balance, and the lines add up to the bank's own totals (Capitec's Money In / Money Out / Fee summaries; FNB's credit and debit transaction counts and totals; Nedbank's Funds received/Credits and Funds used/Debits; Absa's Account Summary; Standard Bank prints no totals, so its statement is checked by the balance brought forward on every page and the Balance at date of statement). If any check fails, nothing is imported and Anchor shows which line or total did not agree.
For a forwarded PDF, the Banking panel shows the bank, period, number of lines and the balance check. Choose the bank account (Anchor preselects the one whose number ends in the statement's last four digits), click Preview to see the balances, the first and last lines and any warnings, then Import. Nothing is imported automatically.
- Capitec fees printed on the same line as a payment become their own line (
Fee: …), so bank rules can categorise them. - FNB prints some descriptions as pictures, which Anchor cannot read. Those lines import as FNB transaction (description not readable in the PDF); rename or categorise them after import. FNB's accrued bank charges column is not imported (FNB debits those charges later as their own line).
- Nedbank emails statements as password-protected PDFs; Anchor asks for the password (see above). The Fees column is not imported: it does not change the statement's running balance, and the fees Nedbank actually charges appear as their own lines (for example SERVICE FEE, Instant payment fee), which are imported. The monthly VAT … = R… note, printed with 0.00, is skipped.
- Absa emails statements as password-protected PDFs; the password is usually your account number. The Charge column (with its A, C, M, S or T type) is not imported: it does not change the running balance, and Absa charges the month's fees as their own lines (for example Monthly Acc Fee, Transaction Charge), which are imported. Lines with no amount, such as Notific Fee Sms, are skipped.
- Standard Bank emails statements as password-protected PDFs; the password is usually your account number. Each line's description is its type and the detail printed below it (for example IB PAYMENT TO followed by the payee). Fees such as MONTHLY MANAGEMENT FEE are their own lines and are imported. Statements print dates without a year; Anchor takes the year from the statement period. A PDF that holds more than one account is refused.
- Duplicates: lines already imported from the same or an overlapping statement are skipped. Lines from bank alerts or a CSV for the same period are described differently and are not skipped; the preview warns how many such lines the account already has in the period.
When Anchor can't read a message
If Anchor couldn't read an alert, didn't recognise an email, or had to refuse a PDF, the Banking panel says why under the message. Click Let support know: Anchor emails the support team the message details and the reason (not your transactions), and the panel shows Support notified. We reply by email, and add support for new alert and statement layouts where we can.
| Status | Meaning |
|---|---|
| received | Captured; not imported yet (a statement waiting for Import or a password, or an unrecognised email) |
| parsed | Body or attachment landed as bank transactions (or matched duplicates) |
| partial | Transaction extracted; pick a bank account in the Banking panel |
| ignored | Not a transaction (e.g. NotifyMe welcome) |
| failed | Anchor couldn't read the alert, or refused the PDF; the panel shows why |
Live open-banking feeds are separate and not enabled yet. Design: docs/design/platform-email-and-bank-notification-ingest.md.
MCP: get_bank_notification_email, list_bank_notifications, parse_bank_notification, preview_bank_notification_attachment, import_bank_notification, report_bank_notification_to_support; statement files: preview_bank_statement_file, import_bank_statement_file (PDF as base64).
Live Connections
Live bank connections are not enabled yet.
- The banking UI shows No bank connected
- Statement imports and email notification ingest are the active automated paths today
- Salt Edge / partner bank feeds are planned for a future release
Reconciliation
Reconciliation matches bank transactions to your accounting records.
Transaction list
Each row shows the statement date (bank day). After a line is posted to the books (categorise, match, transfer, etc.), the list also shows when it was recorded (In books date/time).
Edit details (until period close)
On a bank line, use Edit details / Details to correct:
- Statement date
- Description
- Reference and payee
- Amount (and money in / money out) — only while the line is still unreconciled and not yet in the books (not categorised, matched, or part of a transfer / finished statement check)
Allowed while the date is not period-locked (Settings → period lock / closed fiscal year). If the line is already in the books, use Undo first to change the amount, then edit and re-categorise or re-match. When a linked journal is still posted, its date and description update with the bank line (no void/recreate). Locked periods return an error until unlocked.
API: PATCH /api/v1/bank-transactions/:id (optional amount in integer cents). MCP: update_bank_transaction.
Search
On Transactions and Reconcile, the search box matches:
- Description, reference, and payee (substring, case-insensitive)
- Amount when the whole query looks like money (e.g.
5.50,R5.50,5,50,201,201.00)
Amounts are stored as integer cents. A decimal query is major units (5.50 → R5.50). A digits-only query matches both as cents and as whole rands (550 finds R5.50 and R550.00). Sign is ignored (money in and money out both match). Reconcile also matches the statement date string.
Transaction Statuses
- Unreconciled — Not yet matched to your books / statement workflow
- Reconciled (status) — In your books (categorised or matched); may still need to be ticked on a statement check
- On a statement check —
reconciliationIdset: ticked on an open check, or closed into a completed check - Excluded — Intentionally ignored
Statement check workflow
- Navigate to the bank account → Reconcile
- Check a statement — enter the statement period (start and end dates, e.g. 1 Mar–23 Mar 2025) and opening/closing balances (session stays In progress)
- The tick list shows only bank lines dated in that period (plus any already ticked on this check)
- If you chose the wrong dates (e.g. wrong year), use Edit period on the in-progress banner — ticks outside the new range are cleared automatically
- If the dates overlap another statement check (for example a period you have already reconciled), a warning lists the checks it overlaps. Choose Change dates to go back, or Continue anyway for a re-issued or corrected statement. Lines already on another check do not appear on the new one.
- Tick lines that appear on the statement — ticks save immediately and survive page refresh
- Untick to remove a line from the open check
- Finish statement check when done (or Mark N on statement & finish for an explicit final set)
Lines must already be in your books (categorised or matched to an invoice/bill) before they can be ticked.
Design detail: docs/design/statement-check-draft-ticks.md.
The fuzzy matcher on the bank account page still suggests matches based on amount, date, reference, and description.