Part 4 of 7 · Loyalty tracker series ~5 min read

How a reward gets redeemed

A customer comes back and wants to claim their free coffee. A staff member looks them up, taps the reward, and the points come off. That has to be fast — nobody wants to fiddle with a screen while a queue forms — but it also has to be safe, because the points are worth real money. Give a reward away by mistake, redeem the same one twice, or let a balance go negative, and the program quietly leaks money. Four small guardrails sit between the staff tap and the points actually coming off.

Key takeaways

  • Staff look the customer up by phone; the screen shows the balance and the rewards they can claim.
  • The balance is checked first, so a reward can never be redeemed on too few points.
  • A confirm step sits between the tap and the points coming off — nothing happens by accident.
  • A one-at-a-time lock stops the same reward being redeemed twice in two seconds.
  • Every redemption is logged with the staff member and is reversible in one tap.

Four guardrails on every redemption

Four guardrails between a staff tap and the points coming off A horizontal flow diagram. On the far left, a "Reward tapped" box: a staff member looked the customer up, saw a claimable reward, and tapped it — a free coffee, a free lunch, or money off. Four guardrail gates sit in a row to the right, each drawn as a vertical bar. Gate 1: Look up customer — find the member in DynamoDB by phone number, show the current balance and the list of rewards their balance allows, so staff are always acting on the live total, not a stale screen. Gate 2: Balance check — confirm the balance is at least the points the reward costs; if it's short, the redeem is blocked and the screen says how many points are still needed. Gate 3: Confirm — show the reward name and its point cost and wait for the staff member to press Confirm; this single deliberate tap is what stops a reward going out by accident, and it can be cancelled with no change. Gate 4: Take points + log — subtract the cost from the balance with a safe one-at-a-time write that only succeeds if the balance is still high enough, which also stops the same reward being redeemed twice in two seconds, then write a redemption row to the loy-ledger table. After all four gates pass, the points are off, a receipt note can print, and the customer keeps their drink. A note at the bottom: every redemption is logged to the ledger so a wrong one can be reversed in one tap. Reward tapped free coffee, free lunch, or money off Gate 1 Look up customer find by phone in DynamoDB show live balance and claimable rewards Gate 2 Balance check balance at least the reward cost? if short, block and show points needed Gate 3 Confirm the reward show reward and its cost staff press Confirm; can cancel freely Gate 4 Take points + log one-at-a-time subtract stops double redeem; write ledger row Done — points off, receipt note prints, customer keeps the drink subtract only succeeds if the balance is still high enough every redemption logged to loy-ledger — reversible in one tap Every gate is a deterministic check — no model calls, no reward given away by accident.
Fig 4. Four guardrails between the tap and the points coming off. Look the customer up. Check the balance. Confirm the reward. Take the points with a safe write and log it. Then the points are off and the redemption is reversible.

Gate 1: look up the customer

Staff open the redeem page and type the customer’s phone number. The page calls a Lambda Function URL that reads the member from DynamoDB and returns the live balance plus the list of rewards that balance currently allows. The key word is live — the screen always shows the balance as it is this second, not a number that was right when the page loaded five minutes ago. If the customer just earned points on the sale they’re paying for right now, those points are already counted.

The page shows only rewards the customer can actually claim. If their balance is 108 and the tiers are 100 and 250, they see the free coffee but not the free lunch. There’s no way to tap a reward they can’t afford, which removes a whole class of mistake before it can happen.

Gate 2: balance check

Even though the screen only offers affordable rewards, the function checks the balance again on the server before doing anything. This matters because two things could have happened between the screen loading and the tap — another till could have redeemed a reward, or a refund could have lowered the balance. So the redeem function re-reads the balance and confirms it’s at least the reward’s cost. If it’s short, the redeem is blocked and the screen says exactly how many more points are needed. The customer is never told “done” for a reward they couldn’t afford.

Gate 3: confirm the reward

This is the human guardrail. The screen shows the reward name and its point cost in plain text — “Free coffee — 100 points” — and a single Confirm button. Nothing comes off the balance until the staff member presses it. They can cancel with no change at all. It sounds small, but this one deliberate tap is the difference between “I meant to do that” and “oops.” Speed comes from the lookup being instant; safety comes from the redeem itself never being a single accidental tap.

The confirm screen is also where a manager override would live if you want one — for example, letting a manager redeem a reward the customer is a few points short of, as a goodwill gesture. That override is itself logged with the manager’s name, so a kindness is recorded just like everything else.

Gate 4: take the points with a safe write, then log

On Confirm, the function subtracts the reward’s cost from the balance with a one-at-a-time write that only succeeds if the balance is still at least that high. This does two jobs at once. It makes the final balance check airtight — the subtraction can’t run on a balance that dropped in the last instant. And it stops a double redeem: if two staff somehow tap Confirm for the same reward at the same moment, only the first subtraction succeeds and the second is rejected, so the reward is given once and the points come off once.

Then the function writes a redemption row to loy-ledger: (member, reward, points_spent, by_staff, timestamp). The balance is the running total; the ledger is the history. Because the cost is recorded as a negative points change, reversing a wrong redemption is just adding the same points back and writing a matching “reversed” row — one tap on an admin screen, fully logged. The customer who was charged for a reward they didn’t get can be made whole in seconds, and the trail shows exactly what happened.

Why the guardrails exist

None of these gates are clever. They’re the care a careful person would take if they were doing this by hand — check who this is, make sure they’ve actually got the points, say out loud what you’re about to do before you do it, and write it down so you can undo it if you got it wrong. Putting them in code as four small steps makes them part of the design, not something you’re trusting a busy barista to remember at the height of the morning rush.

Next post: how a lapsing regular gets nudged — how a weekly sweep finds the regulars who’ve gone quiet, and the three things the shop can do about each one.

All posts