If you import a bank statement twice and get two different results, your close process is not stable.
The fix is not “be careful”.
The fix is idempotency.
If you want the product overview first:
What idempotency means in reconciliation
Idempotent import means:
importing the same statement file again does not create duplicates
Instead, the system should:
- detect it is the same file
- return the existing imported statement
- keep the matching/audit trail intact
This matters because retries are normal:
- mapping was wrong, you fix it and try again
- the import failed mid-way
- you need to re-run in a new environment
If retries require manual cleanup, you do not have an enterprise-grade workflow.
Why a file hash is the simplest, most robust key
A file hash (e.g., SHA-256 over the file contents) gives you a deterministic identifier:
- identical file contents → identical hash
- different file contents → different hash
That makes it a clean idempotency key.
Alternative keys are weaker:
- filename is not reliable (files get renamed)
- statement dates are not unique (banks reissue exports)
- row counts are not unique
What to do when the bank re-exports “the same statement” differently
Banks often re-export the same period with:
- reordered rows
- extra header rows
- formatting changes
Those changes will alter the hash.
Operationally, treat this as a different file import:
- import it as a new statement
- compare the resulting lines/matches explicitly
- finalize the “authoritative” statement for the close
The key is: the decision is explicit and reviewable, not hidden in a spreadsheet.
The 3 controls that make idempotent import safe
- Fail fast on invalid parsing
- don’t import garbage and clean up later
- Return the existing statement when idempotent
- “already imported” is a valid outcome
- Keep a stable audit trail
- store import filename, hash, and timestamps
What to do next
If your reconciliation process is fragile, start by making imports safe to re-run: