Client
A Singapore e-commerce business
Role
Analyst, builder, tester
Discipline
Product · automation · productivity
Volume
4,000 orders a month
Status
PayProof · live on the merchant’s store

One person confirmed every bank transfer by hand

What was achieved

Process improved
3–7d → 12h
83–93% faster to resolve an order
Process improved
85%
Less staff time every month
Process improved
9 → 1
Steps on an order that pays itself

The proof of payment never arrived on the order

A human has to confirm every bank transfer. That is unavoidable. Where the proof landed was not.

Payment was requested on one WhatsApp number. Proof went to another. Neither was linked to the order, so one payment meant three surfaces in your head.

What I personally did

Owned
The problem definition. Mapped the workflow across three states, ran the per-step time study, put the numbers in front of the business.
Built
The product. Checkout prompt, QR, customer upload, staff dashboard, email channel. Shipped to a live store.
Tested
Verified on the real storefront, not in theory. Security assessment, three gaps closed, an automated checkout test left behind.

PayProof — watch it do the job

Both interfaces, playing themselves. The staff side is the product: the proof is already on the order, so the entire remaining job is looking at it and deciding.

The staff side · what an order actually takes now
PayProofVerify payments
OrderAmountStatus
#1042A. Customer 66.00 Pending
#1041M. Yusof 120.00 Pending
#1040K. Tan 88.00
Payment screenshot · #1042
9:41
Transfer
Transfer successful
SGD 66.00
ToTHE MERCHANT PTE LTD
UEN2024•••••D
FromMultiplier 029-029-12345
ReferenceOrder 1042
Date14 Aug 2026, 11:02
Transaction6A7E••••2F
receipt.jpg · uploaded by the customer
On the screenshot66.00
Order total66.00
Match

Recreated interface on invented orders. Nothing here is connected to a live store.

The customer side · the QR does the typing
Order #1042Pay by PayNow
SGD 66.00
Order 1042 · already inside the code
✓ Saved to Photos
Upload your payment screenshot
receipt.jpg
Screenshot received

It is already on your order. Nothing else to send.

Your banking appPayNow
Scan or upload a PayNow QR
ToTHE MERCHANT PTE LTDfilled in
UEN2024•••••Dfilled in
AmountSGD 66.00filled in
ReferenceOrder 1042filled in
9:41
Transfer
Transfer successful
SGD 66.00
ToTHE MERCHANT PTE LTD
UEN2024•••••D
ReferenceOrder 1042
Date14 Aug 2026, 11:02

Recreated interfaces on an invented order. The real page needs a live order and a signed link.

Where the four minutes actually went

Not into the payment. Into the lookup. The bottleneck was the search — the proof sat in a chat instead of on the order, and a chase with no deadline meant the order left the workflow and had to be found again from scratch.

Eight of the nine steps disappear. Not because anyone works faster, but because the proof arrives on the order, so there is nothing left to look for.

Only the human work, across all three states
Nine things a person does before, three today, one after the enhancements. The nine before are asking for payment, finding the phone number, searching two inboxes, chasing, parking it, finding it again and finally checking it. After, the machine shows the QR with the amount, files the proof on the right order, chases and closes.
What is already true today

Three surfaces became one. Two inboxes became zero. The customer is told the exact amount. On an order that pays itself, staff do one thing: open the screenshot and approve it.

And noticing stopped being a person's job. An unpaid order chases itself at six hours and closes at twelve, so nothing waits on somebody remembering it.

The full workflow across three states · colour says who does each step
Three columns. Before: nine numbered staff steps with three decision points, all of them searches, and one that loops back on itself. After, live today: the QR and the upload are automatic, the proof lands on the right order, and one staff step remains. After the enhancements: a dashed zone that runs by itself chases at six hours and cancels at twelve.

How the four minutes was established

The business knew the process was slow. Nobody had a number for it, and without one there is no case for building anything. So the old workflow was reconstructed step by step from how staff actually described it, and each step was given a duration.

Step a person doesBeforeAfter
1. Send the request from the first number35s
2. Open the store admin, find the order30s
3. Read the phone number off the order10s
4. Check the number it was meant to go to25s
5. Check the other number too30s
6. Chase them25s
7. Move on, nobody can wait5s
8. Days later, find the order again55s
Open the board10s
Open the screenshot15s
9. Check it and set the outcome25s10s
Per order240s · 4 minutes35s

What each question turned up

01Where does the time actually go?
The per-step study, above

Eight of the nine steps are lookup, not payment. Only step nine — reading the screenshot and deciding — is the actual job. Automating the payment would have saved nothing. The target was never the transaction, it was the search around it.

02What did the old workflow really look like?
The retired flow, drawn in full with both branches

Three decision points, and every one of them is a search. One loops back on itself: chase, park, return, and start the lookup again from nothing. That loop is why an order took 3 to 7 days rather than four minutes.

The retired manual workflow drawn in full: the request goes out with no amount, proof arrives at a different number, staff open the store admin, read the phone number, search the first inbox, then the second, chase, park the order, come back and find it again, and only then mark it paid.
The manual workflow, as staff described it. Three lanes: who does each step.
03What did it cost the person paying?
The same job mapped from the customer side

Eight moments where they start to doubt the shop, against none afterwards. Not inconveniences — reasons to abandon the order or to call.

The worst is the last one. Being chased for money you have already paid is the moment a customer stops trusting a shop, and it is caused entirely by the proof landing somewhere that is not the order. It is the one failure the new flow cannot produce, because there is nowhere else for the proof to go.

The customer journey before and after. Before carries eight friction moments: no amount given, working the total out by hand, finding the order number, being told to message a second number, and finally being chased for money already paid. After carries none.
Friction marked in red. Eight before, none after.
04Can the chase be automated with what already exists?
Checked in the code, not assumed

Mostly yes. The cancel action is already wired and staff fire it from the dashboard today, so automatic cancelling is the same call on a timer. The messaging channel already exists too.

What genuinely has to be built is the timer — there is no scheduler of any kind. That is the work, and it is small. Sizing it this way is the difference between a proposal that gets built and one that gets deferred.

The current workflow with the proposed automation boxed in a dashed zone marked runs by itself: chase at six hours, cancel at twelve, and a reject path that lets the customer upload a replacement.
Live today, with the designed automation boxed. Dashed means not built.
05Could we take the money before the order exists?
Ruled out, and worth recording why

It would remove the problem at source. It is not available: payment-step extensions on this platform are restricted to its top tier, and there is no supported theme workaround.

It also inverts the failure. Today a failure means an order with no money against it. That version would mean money with no order against it, which is worse for the customer and worse for the business.

06Is a customer’s payment link safe?
Security assessment on the live app

Three gaps, all closed the same day. The customer-facing pages shipped with no security headers, so the upload page could be framed by another site. A bad token returned a page instead of refusing. And the signed payment links never expired.

Fixed with a strict header policy scoped to the customer routes only, a proper refusal on a bad token, and a seven-day expiry that still honours links issued before it existed.

What the checks did not catch, and the lesson I keep

The post-deploy checks all passed while the app was refusing every real buyer. They tested that the lock worked — a bad token rejected, an unsigned request rejected, the public page loading. None of them tested that the key worked.

It was found by driving the real storefront in a browser and reading what the customer's own request actually returned. What ships with it now is a checkout test that places a real order, and an alarm that fires when a genuine buyer is refused. A check that only ever proves the negative case will pass on a completely broken system.

A week becomes half a day

BeforeToday, liveWith the automation
Time a person spends on one order~4 minutes~35 seconds~35 seconds
Across 4,000 orders a month~267 hours~39 hours~39 hours
People that much work needs1.70.250.25
Places to look311
Steps done by a person931
An order is resolved in3 to 7 daysDepends on staff noticing12 hours or less
Chases sent by a person800 a month800 a monthNone
Orders that can go unnoticedAnyAnyNone
The honest reading

Nothing about the payment itself got faster. What changed is that nobody has to remember it, so the waiting stopped being a function of whether one person got to it that day.

There is one member of staff on this. The work needed 1.7 people. That gap is the whole story, and it is why the delays and the cancellations looked like a people problem when they were a process problem.

What is not claimed here

One in five orders is cancelled unpaid — around 800 a month. That is the largest number in this project and it is deliberately left unpriced, because the average order value has not been supplied. One figure would turn it into money, and until it arrives this page states it as orders and nothing more.

It is also not yet confirmed whether that 20% is a share of all orders or only of the 20% that get chased. Read the conservative way, it is 800 a month. Read the other way, it is 160.

What the solution had to do

  • 01
    Tell the customer the exact amount, without them working it out
    The order total, the reference and the destination all baked into the QR at checkout.
    → A customer calculating their own total is a wrong amount waiting to happen, and every wrong amount is a manual reconciliation.
  • 02
    The proof must attach itself to the order
    Upload on the same page the customer is already on, filed against that order automatically.
    → Everything expensive in the old process — the searching, the wrong matches, the chasing of people who had already paid — came from proof living somewhere other than the order.
  • 03
    One place to look, not three
    A single board carrying every bank-transfer order, its proof and its status.
    → Three surfaces joined by a hand-typed phone number is not a process, it is a memory test that one person was failing 4,000 times a month.
  • 04
    Show nothing at all on orders this does not apply to
    Gated on the payment method and the currency. Card orders and foreign-currency orders see no prompt.
    → The overwhelming majority of orders are not bank transfers. A payment instruction on those is a support call, and a promise the system cannot keep.
  • 05
    A payment link must expire, and refuse a bad one
    Signed links time-boxed to seven days, a proper refusal on an invalid token, and a header policy on the customer pages.
    → The link carries order detail and reaches a customer over an untrusted channel. A permanent link is a permanent exposure, and it was permanent.

What produced each result

Produced the 3–7d → 12h

A clock instead of a memory

The designed chase fires at six hours and the close at twelve, so resolution stops depending on somebody noticing. The cancel action was already wired, so the work was the timer around it.

Produced the 85%

Proof filed at source

The upload attaches to the order automatically, so eight of the nine steps have nothing left to do. 267 hours of monthly demand becomes 39.

Produced the 9 → 1

The QR, the upload and the board

Asking, calculating, searching two inboxes and re-finding the order are all gone. What remains is opening the proof and deciding.

Trust

Headers, expiry and a real refusal

Three security gaps found on the live app and closed the same day, scoped so the merchant-facing side was untouched.

Detection

A real checkout test and an alarm

A test that places an actual order on the storefront, and an alarm that fires when a genuine buyer is refused rather than when a scanner is.

Resilience

A second channel

The payment section rides on the order confirmation email too, so a slow-loading prompt is no longer the only route to paying.

Part two of two

How it was actually done

The time study, five findings, the requirements, and two more diagrams.

!Before you open this

Everything above is the bottom line. If that is what you came for, you already have it.

What follows is the working: how the four minutes was established step by step, the five questions the analysis turned on, what got ruled out and why, the five requirements, and the security assessment. It is long on purpose. It is written to be checked, not skimmed.

Only wanted the result? Stop here. Every number is already above this line.