Case 01 · Cactus · Foodtech
How Much Is Left
A prepaid table balance that the waiter and the guest read at the same time, mid-service. I designed both sides of one shared account.
Company
Role
Product designer, end to end
Team
[confirm: PM + engineers]
Surfaces
Waiter app (Flutter) · Guest web (Next.js)
Status
Live since 2024

My contribution
Defined how the balance behaves across the table’s life: fund, spend, settle.
Designed the waiter flow in the POS app and the guest flow in Order and Pay.
Designed the balance bar and every table state, handed off with its edge cases.
Not mine: [confirm] payment processing and backend, built by engineering.
The problem
Most restaurant software treats a table as a list of items with a total at the bottom. It works until the money stops arriving at the end.
A party buys a table package before they order anything. From that moment the table is carrying a balance, and two people are tracking it for opposite reasons: the guest wants to know how far it goes, the waiter needs to answer that mid-service without stopping. If neither of them knows, the argument happens with everyone still sitting there.
At Cactus I designed the surfaces where that money moves: the waiter’s phone and the guest’s phone, working on the same account at the same time.
01 — Fund
The money is decided before anyone reads a menu.
Whether the party can spend past their balance is set once, at the table, in front of them, and it governs the rest of the night.



Covers, service, and one switch
Limit to credits, yes or no. It decides whether the party can spend past their balance, and it can only be set here.
The button changes with the money
Choosing a service turns open table into charge service, because money now moves before anything is ordered.
02 — Spend
From here the table carries a balance.
Two people watch it for opposite reasons. The guest wants to know how far it goes. The waiter wants to know when to stop suggesting.



The balance is always on screen
A bar under the menu and above the primary action counts down live as items go in. Green, amber, red. Nobody has to ask how much is left.
The account, not the list
The table detail leads with what was ordered and closes with what it means: credits available, credits applied, and the one number the waiter says out loud.
The label carries the state
When credits cover everything the action is close table. Past the balance, the same screen says charge table and the difference moves to checkout.
03 — Settle
The last three minutes of a table happen with an audience.
Someone is standing there waiting. Every screen in this act is read with the guest watching.





Paying with more than one method
The system takes partial payments until the balance reaches zero. A first payment of 25,000 leaves 24,550 pending, and the next method picks it up.
The interface does the arithmetic
Every cash option carries its own change: the exact amount, then the bills a person actually hands over.
Confirmation runs in the background
Card processing takes as long as it takes. Continue in background releases the waiter to the next table, with a recap underneath.
Closing has a guard
A table with unspent credit can’t be closed quietly. The confirmation names the amount and offers to stay on the table.
Decisions
Five calls, and what I said no to.
Each one traded a familiar pattern for something the waiter can do without stopping.
01
Credit limit
Chose
Set once, when the table opens, in front of the party.
Rejected
Editable at any point during service.
Why
The rule governs the whole night. Changing it mid-service reopens a conversation nobody wants at the table.
02
Over the balance
Chose
The action label carries the state: close table or charge table.
Rejected
A blocking warning when consumption passes the credit.
Why
The waiter is mid-service. A state they can read beats an alert they have to dismiss.
03
Splitting the bill
Chose
Partial payments until the balance reaches zero.
Rejected
A dedicated split-bill mode.
Why
Splitting stops being a feature to learn and becomes a consequence of how payments work.
04
Slow card processing
Chose
Continue in background, with the recap on screen.
Rejected
A full-screen spinner until the processor answers.
Why
The waiter shouldn’t be held hostage by the slowest step. The next table is waiting.
05
Unspent credit on close
Chose
A guard that names the amount and offers to stay.
Rejected
A generic “Are you sure?”.
Why
This is the dispute that would otherwise arrive tomorrow. The number is the warning.
States & edge cases
A funded table has more states than open and closed.
Each one changes what the waiter can do next, and what they have to say to the person in front of them.

S1

S2

S3

S4

S5

S6
Two readers
The same number, two framings.
The guest joins through a QR code or an invitation the table admin approves, and orders against the same account the waiter is working on. The balance bar behaves identically. What changes is who reads it.

Waiter
“This table still has 1,300 unspent. Are you sure you want to close it?”

Guest
“You have 1,300 in credit left.” An invitation to order again.
One number, one point in the lifecycle, two opposite readings. The system doesn’t have a single voice. It has one per role.
Where it stands
Live in production since 2024.
It runs inside the Cactus platform, the same one the rest of the merchants work on every shift.
2024
In production since
150
Merchants on the platform
46,000
People who use it
[metric pending]
Tables opened with credit
What I’d still fix
Two gaps I’d close next.
The balance belongs to the table, not the people at it.
When a group splits the bill there’s no record of who consumed what. It works because someone at the table keeps track, which is a person doing the system’s job.
There’s no offline behaviour.
Background confirmation covers a slow processor, not a dead connection. If the network drops mid-service the waiter is stuck, and venues with bad wifi aren’t a rare case.
Keep reading
4 pieces · 3 cases, 1 concept
If your product got complicated, let’s talk.
Copy email
All contact details
