alejah
← back to works

Cashpop

Cashpop


Alejah Sardiniola

available for work

> get in touch

Cashpop — screen 1

The problem

Walk into any GCash outlet and ask to see the books.

You'll get a paper logbook. Smudged. A running total in the margin that's been wrong since Tuesday.

But the logbook isn't the real problem. The real problem is the float.

A GCash agent holds money in two buckets that move in opposite directions on almost every transaction — physical cash in the drawer, and e-money in the GCash wallet. Cash-in drains the wallet. Cash-out drains the drawer.

You can be profitable on paper and still turn a customer away because your GCash hit zero while the drawer is stuffed with cash.

The logbook tells you what happened yesterday. It never tells you the one thing that matters: what you can do right now.

The solution

CashPop replaces the logbook with a ledger that's actually alive.

Two live balances, always on screen. Low-balance warnings that are central, not decorative — the cashier sees the wall before they hit it.

Fees compute themselves — flat ₱5 under ₱1,000, 1% above, rounded to the peso — and stay editable down to ₱0 when it's family. Every entry posts to an append-only ledger, backdatable, reconciled at close.

And credit gets handled the way real outlets actually run it. Not as an afterthought. As a first-class thing that never poisons the drawer balance.

What was built

  • Fast transaction entry — cash-in, cash-out, load, and float adjustments with auto-fee, a live before/after balance preview, optional 4-digit reference, and backdating.
  • Two live balances — cash on hand and GCash wallet, tracked in opposite directions on every posting, with low-balance guardrails that warn and allow.
  • Per-customer utang — credit tracked by name with partial payments, receivables and payables, and a derived unpaid → partial → paid status allocated oldest-first.
  • Honest reconciliation — an end-of-day close that counts only cash that physically moved, so the drawer reconciles against reality instead of a shoebox.
  • Real receipts — thermal-style, branded, exportable PDFs: daily summaries, per-customer utang tickets, multi-customer runs.
  • Offline by design — no accounts, no login, no cloud. A salted-SHA-256 PIN gate and manual JSON backup. The outlet's data lives on the outlet's phone.

Tech stack

FlutterDrift over SQLiteRiverpod

Impact

This is the difference between a ledger you trust and one you audit against a shoebox every night.

The drawer only ever reflects cash that has physically moved — point-of-sale transactions plus actual utang payments, never an outstanding tab. So reconciliation stops being theater. At close, the number on screen is the number in the drawer, or you know exactly which entry to look at.

The cashier enters faster than they wrote in the logbook, and sees a live wall coming before the GCash wallet runs dry. That's not a nicer record. That's fewer customers turned away, and fewer pesos lost to a total that drifted.

Reflections

The hardest part of this build wasn't the features.

It was the math nobody sees. The spec defined the cash balance one way — and read literally, it double-counted every settled utang. The same peso, counted twice. I didn't build the spec. I built what the spec meant: cash movement keyed on whether a customer is attached, not on a status label that flips underneath you.

That's the whole job. Anyone can render a form and a running total. The work is in the rules that keep the number honest when credit, partial payments, and backdated entries all hit the same drawer.

One person owned every layer of it — the fee logic, the float engine, the credit rules, the receipt renderer, the design language. Most people would split that across a team of five and still ship something that lies about the balance. I shipped one app that doesn't.

Interested in building something similar?

alejah.t.sardiniola@gmail.com