Cash office clerk for a neighborhood fresh-food chain - the payment-stream matcher - paste the POS export and the channel statement, match on amount within a time window, and get back only what failed to pair
You are a coding agent building a single-file tool for a
neighborhood fresh-food chain. Build an HTML single file that
opens straight in a browser: a Payment Stream Matcher, for
the cash office clerk to reconcile POS records against a
payment channel's statement. All computation runs locally;
no external requests of any kind - financial data never
leaves this machine.
Data entry (two paste areas; accept CSV/table exports pasted
directly):
- Area A: the POS export for the day or month: time /
amount / payment method / order number
- Area B: the channel statement export (WeChat Pay /
Alipay / Meituan, one at a time): time / amount /
transaction status
- After pasting, run column mapping first: let the user
point out which column is time, amount, and payment
method - the two systems' headers never agree; assume
nothing
Matching rules:
- Key = amount + payment method; time window of plus/minus
[default 10 minutes], adjustable - POS transaction time
and channel booking time carry a systematic offset; the
window exists for exactly that
- Unique candidate inside the window: auto-match
- Multiple candidates inside the window (same amount, same
method - common on a busy afternoon): no auto-match; list
under "needs human eyes" - better a person looks than a
guess gets made
- Refunds (negative amounts) match in their own pool,
never mixed with positive flows
- Close in time but different in amount: a "possible" zone,
difference shown, no verdict (could be a partial refund
or a price edit - human decides)
Output, three tables plus one summary line:
1. POS-only: time / amount / order number - the question is
"where did the money go": not settled, reversed, channel
lag
2. Channel-only: time / amount - the question is "where did
it come from": off-register collection, a personal QR
code, a sale that never entered the system - this table
is the serious one
3. Needs-human + possible zone: merged, each with one line
of suggested follow-up
- Summary line: total count / total amount / unmatched rate
Engineering requirements:
- Export the unmatched list to CSV (next month, load last
month's open items first and auto-clear whatever has
since settled)
- Nothing persists in the page; refresh wipes - the default
posture for sensitive data is not to store it
Do not:
- Build any "decide which side is right" logic - the tool
matches, it does not adjudicate
- Guess a match: rules unmet means the human queue; zero
auto-filling of any kind
- Add a backend, cloud sync, or analytics tracking - any
one of the three counts as this tool failing
Why it is written this way
The labor structure of wallet reconciliation is ninety percent mechanical and ten percent judgment: the overwhelming majority of streams pair perfectly, and the human's real value lands on the handful that don't. Letting a rules engine eat the ninety percent and leaving people only what the machine cannot pair is the correct cut of the division of labor - the true risk of eyeballing is not slowness but the moment a tired person waves through something that "looks about right," and that waived-through line is the hole.
"No auto-match on multiple candidates" is the most important engineering constraint in the prompt. Two same-amount transactions inside a window are an afternoon constant in a neighborhood store (two consecutive baskets both 18.80); auto-matching necessarily mispairs sometimes, and a mispaired reconciliation reads as "balanced" - more dangerous than an imbalance, because nobody ever looks at it again. Pinning the rule to "unique candidate only" pushes all ambiguity explicitly to a person, which is what makes the tool's conclusions trustworthy.
The directionality of the two unmatched tables is designed, not accidental: POS-only points at "money didn't arrive" - chase the channel; channel-only points at "sale never entered the system" - look inside the store, and far more serious, because a personal QR code or a skipped entry means an internal-control gap. Separate tables separate the urgency; merged into one, all you can do is sort by amount and lose the direction entirely.
Running locally is the financial bottom line and this tool's survival precondition: pasting a store's complete takings into any online tool hands the detail to a third party. Single file, pure browser, wiped on refresh - this constraint is not a feature, it is the boundary; a more convenient "cloud-synced edition" that crosses it must never be built.
Variables
This prompt has no blanks to fill in; the [time window, default ±10 minutes] is adjustable in the tool's settings, set to your store's network and channel reality.