245 bookings in the refund queue and no one could open it
A hire business asked for a sign-off step before refunds. The refund screen had never completed one. Our first diagnosis was wrong, and the owner corrected it.
The owner of a hire business asks for a simple control: operations must sign off a booking before it passes to accounts for its refund. To add it, we read how refunds actually flowed through the system for GOI Car & Taxi, a self-drive and taxi hire business in Goa.
The refund screen listed 245 bookings holding 10,00,000 rupees of customers’ deposits. It showed zero invoices, zero recorded refunds, zero payout requests, and not one booking had ever reached Refund Done. Our first write-up said what that looks like: a pipeline that had never completed once, and ten lakh rupees of customers waiting.
That was wrong, and the owner told us so. Refunds were being paid by the office by hand, outside the system. What we had found was a gap in recording, not stuck money. We corrected the review to say so.
What was actually going on
Four payout roles existed and nobody held any of them. The refunds screen therefore answered “forbidden” to every user on production, which is why no refund row had ever been written. The system was not stuck; it had simply never been used for this.
Behind the locked screen, the queue was the raw list. A booking reached accounts automatically: a driver uploads a drop-off photo, the booking moves to Returned and on to Refund Issue Pending, and nothing else is checked. Real checks existed and were good, but they all fired at the moment of payment, one click at a time, so accounts met each booking’s problems only when trying to pay it. Among the 245: 99 had incomplete audits, 242 had no refund method chosen, and 177 had no bank details, of which 164 had never been asked.
The second finding was a wrong number. 27 fully paid bookings holding a 5,000 deposit displayed negative refunds, such as minus 16,283. The settlement summary set “Previous Dues” to the gross amount due at pickup instead of the unpaid balance, so payments received were never subtracted. The refund line disagreed with the ledger on 31 of 39 queued bookings.
A third was latent. When a payout completed, the code recorded who created it using a fallback user that does not exist. A finished bank transfer would have failed to record and the failure would have been swallowed. It had never fired, because no payout had ever run.
What we changed
The payout role was granted on the owner’s approval, and the refunds screen now opens on production. We read every refusal in the close path out of the code rather than the design. There are six, and three of them are skipped for cancellations, so a cancelled booking can be paid with no validation at all.
Then the owner asked whether closing a booking had been tested end to end. Honestly, no: every test had inserted a finished invoice directly, skipping the gates. We built tests that take real bookings through audits, documents, collection and invoice into each kind of close. On the first run the desk sent an amount of zero, the invoice finalised to 5,000 in the same call, and every real manual close was refused. That is now fixed. We also added the close the owner described for a booking with nothing to refund.
What it did not fix
The release-to-accounts gate, a named checklist that revokes if anything changes, was designed, not built as far as the log records. The wrong Previous Dues figure was traced to its line and written into the list of outstanding fixes; the log does not record it being corrected.
No money has moved through the system either. The bank’s test environment works up to creating and approving a payout, then stops, because the first access token has never been issued from the bank’s developer portal. That is a human onboarding step.
The pattern, for anyone with a queue nobody works
An empty table is a fact, not a verdict. Before you call a process stuck, find out whether it is being done elsewhere. We did not, and the review overstated the problem.
Two checks are cheap. List who holds each role a screen depends on; a role with no holders is a screen nobody can open. And ask of any test that said “closing works” whether it ran the real steps or inserted the result by hand.
Where this ends up
Refund checks that run when a booking is listed, not when someone tries to pay it, are what Sazinga Rentals is built around.