How an expense claim gets paid
An approval card lands in Dana’s chat at 8:03am. Sam’s client lunch, $36, in policy, receipt attached. There are three buttons: Approve, Reject, Ask. What happens when she taps one? The honest answer is “it depends on which one.” This post walks through the three things an approver can do — approve, reject, ask — and how the claim record, the payable sheet, and the audit trail all stay in sync. And the one thing that never happens: the system moving money on its own.
Key takeaways
- Three actions per card: approve (write to the payable sheet), reject (reason back to the claimant), ask (request more).
- Approve writes a row to a payable sheet that your bookkeeper or payroll run reads — the system never pays anyone.
- Reject sends a plain-English reason to the claimant so they know why and what to fix.
- Ask requests a missing receipt or a note, and parks the claim until the claimant replies.
- Every action writes a before-and-after snapshot to the audit table, so each decision is reversible.
Three actions on the card
Action 1: approve (the most common)
Dana reads the card — Sam’s $36 lunch, in policy, receipt attached — and taps Approve. The tap submits to a Function URL Lambda. Three things happen, in order. First, the claim’s row in ea-claims is marked approved with Dana’s identity and the timestamp. Second, a row is appended to the payable sheet in Drive via the Sheets API: employee, amount, category, approver, date, and a link to the receipt. Third, an action: approved row is written to ea-audit with the user, timestamp, and the claim snapshot. Sam gets a one-line note: “Your $36 lunch claim is approved.”
The payable sheet is the boundary the system never crosses. It does not call a bank. It does not trigger a transfer. It writes a clean, approved, audit-trailed row, and whoever runs payroll or the weekly reimbursement batch reads that sheet and pays from it. Keeping the system one step back from the money is the whole point — the riskiest action in the pipeline stays in human hands, and the system’s job is to make that human’s decision fast and well-grounded.
Action 2: reject (with a reason)
Sometimes the claim shouldn’t be paid. The $90 dinner that’s well over the meals cap with no business reason given. The personal item that slipped into the wrong category. The duplicate of a claim already submitted last week. Dana taps Reject. A small note field opens, pre-filled with the policy reason the checker already worked out (“$50 over the $40 meals cap”), which Dana can edit or add to. On send, a Function URL Lambda marks the claim rejected, sends the reason to Sam so he knows exactly why and what to do (“split the personal portion and resubmit,” say), and writes a rejected audit row.
The reason matters because a rejection without one just breeds a follow-up question and a grumble. “Rejected” on its own feels arbitrary; “rejected because it’s $50 over the meals cap, please resubmit the business portion” is a clear next step. The claimant is never left guessing.
Action 3: ask (the “I need more”)
Sometimes the approver can’t decide yet. The receipt photo is too blurry to read. The amount is fine but there’s no note about which client the dinner was for. The category looks off. Dana taps Ask, picks what she needs (“clearer receipt,” “which client?”), and the claim is parked in a waiting state. A message goes to Sam asking for exactly that.
When Sam replies — through the same submit lane he used in Part 2, by re-uploading the receipt or adding the note — the claim re-enters the checker, gets re-evaluated against policy, and comes back to the approver with the new information attached. The claim doesn’t leave the system or get lost; it just pauses until the missing piece arrives. Ask is the pressure valve that keeps a half-complete claim from being either wrongly approved or unfairly rejected.
Every action is logged, every action is reversible
The ea-audit table records every approve, reject, and ask with the user who took the action, the timestamp, and a snapshot of the claim before and after. If a claim was approved in error — wrong amount, wrong person, approved twice — an admin can run an “undo last action” that reads the previous-state snapshot, restores the claim, and removes the row from the payable sheet if it hasn’t been paid yet. The undo is itself an audit row, so the trail of edits stays clean.
This kind of reversibility matters because expenses get audited. When a year-end review asks “who approved this $400 software buy and why?”, the audit trail answers in one query: the approver, the time, the reason, and the policy that applied. The trail is the memory the business has when the people who made the call have moved on.
Next post: the cost breakdown. The whole pipeline above runs in coffee-money territory at SMB volume; Part 6 explains exactly where the dollars go and why the policy check itself is almost free.
All posts