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
Fig 1. What happens after approval. The payment is written once, the monthly total moves under a condition, and the claim joins the next payroll export.
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.
Fig 2. A month of mileage in five numbers. The interesting one is the last: how many claims actually needed a manager, out of everything that was claimed.
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.