How a mileage payment gets recorded
This system does not move money. It decides what is owed and writes it down, and then hands a file to whatever already pays people. That boundary is deliberate: payroll is a solved problem with regulatory weight attached to it, and the fastest way to make a small useful system into a large frightening one is to have it touch a bank account.
Key takeaways
- The system decides what is owed. Payroll pays it. That boundary never moves.
- Every payment record stores the numbers the decision was made against, not just the outcome.
- The monthly total is a conditional increment, so two claims landing together cannot both win.
- The payroll export is one CSV per period, regenerable, and identical every time.
- The month-end report is three numbers and a list, and it is the reason to run any of this.
What a paid claim leaves behind
- Database
- App integration
- Machine learning
- Security & identity
- Analytics
Why the rate is stamped, not looked up
Mileage rates change, usually in April, usually with a week’s notice. A system that computes the amount at export time by reading today’s rate will quietly restate every unpaid claim from before the change, and the first anyone knows about it is a claimant who is nine pounds short. So the rate is read once, at approval, and written into the payment record next to the miles.
The same reasoning applies to the tolerance band and the caps. The basis field stores what the rules were when the decision was made. It is three extra fields and it is the difference between an audit trail and a list of outcomes.
The payment record
| Field | Example | Why it is there |
|---|---|---|
claim_id | clm_2026_07_09_a3d1 | Links to the submission and any question asked |
claimant | sam@example.com | Who is owed |
trip_date | 2026-07-07 | Not the claim date; the driving date |
miles | 84.0 | As finally agreed, after any correction |
rate | 0.45 | Stamped at approval, never re-read |
amount | 37.80 | miles x rate, computed once |
basis | expected 41, band +50%, return trip | Why this was allowed |
resolved_by | claimant / auto / manager | Who closed it, if anyone had to |
period | 2026-07 | Which export it belongs to |
state | payable | payable, exported, or reversed |
The export
One CSV per period, with one row per payable claim and a column layout your payroll software already accepts. It is generated on demand rather than on a schedule, and generating it twice produces a byte-identical file, because the period boundary is a date and not “everything since I last ran this”.
Once a period is exported, its claims move to exported and become read-only. A claim that arrives late for a closed period does not reopen it; it lands in the current period with its true trip date, which is what every payroll system expects anyway.
The report that justifies the whole thing
Everything above is plumbing. This is the output that makes it worth building.
- App integration
- Machine learning
- Analytics
- People
Four numbers describe the money and one describes your time. A month where eleven claims were queried, four were corrected by the person who made them, and exactly one reached a manager is a system doing its job. A month where thirty were queried is a band that is too tight, and the fix is an edit in a sheet rather than a conversation with anybody.
Next: what all of this costs to run.
All posts