JamLoyalty
White-label digital loyalty platform for Caribbean merchants. Merchant dashboard, staff scanner, customer wallet.
Paper punch cards cost money to print, get lost, and tell the business nothing. JamLoyalty replaces them with three connected surfaces: a merchant dashboard for building campaigns and branding, a staff terminal that scans, and a customer wallet that saves to the phone's home screen and tracks stamps live over database subscriptions.
The problem worth solving was fraud. A loyalty stamp has cash value, so a static QR code is an open invitation — photograph it once and self-stamp forever. Codes are signed with HMAC-SHA256, rotate every fifteen seconds, and are checked server-side against replay, so a screenshot is worthless almost immediately. Staff reach the scanner through a per-location code issued from the merchant dashboard, so a leaked link doesn't become a leaked till.
Customers sign in by phone OTP through Twilio rather than email, because email isn't the default identity in this market. Passes can be added to Google Wallet, generated by a serverless function. Each merchant carries their own branding and is isolated from every other merchant by Postgres row-level security.
- PERIODJan — Mar 2026
- USERSMerchant, staff, customer
- STACKReact, Supabase, Firebase, Twilio
- NOTABLEHMAC-SHA256 rotating QR, anti-replay
Why rotating codes
The threat isn't a sophisticated attacker, it's an ordinary customer with a screenshot and a staff member who isn't watching closely. A signed, short-lived code makes both attacks expire faster than they can be executed, without asking staff to do anything differently.
Multi-tenancy
Merchant isolation is enforced in Postgres through row-level security rather than in application queries. A missing WHERE clause in a React component cannot leak one business's customer list to another, because the database refuses the rows regardless of what the query asks for.