Vouchers and entitlements
A coupon, a meal ticket, a drink token or a "one free coffee" card: something that can be used a limited number of times. The staff member scans it, and the green screen means it has just been used up; the red one says why it can't be.
How it works#
- Each voucher carries a QR code with a unique code.
- Staff scan it at the counter.
- Your API checks the voucher and, if it is still valid, uses it up and answers green.
What your API checks#
- The voucher exists and hasn't expired.
- It has uses left. For entitlements such as "one lunch per day", define what "a day" means (time zone, a shift that runs past midnight).
- Optionally, that it is valid at this counter (
deviceId).
Example answers#
{ "status": "ok", "title": "Redeemed", "message": "Lunch menu · 2 of 5 left this week" }{ "status": "failed", "title": "Already redeemed", "message": "Used today at 12:05, canteen 2" }Settings#
A generous timeout (8 seconds here) matters more than a fast one; see below.
{ "app": "scan2check.com", "settings": { "apiUrl": "https://api.example.com/vouchers/redeem", "symbols": [ "qr" ], "apiTimeout": 8000, "autoScanTimeout": 2000, "headers": { "X-API-KEY": "your-key" } }}Open in configurator — loads these settings so you can put in your own API URL and generate the QR code. Add the headers there yourself; they are left out of the link on purpose.
Watch out for#
- Timeouts are the classic trap. The phone gives up waiting and shows red, but your API has already used up the voucher. The customer scans again and gets "already redeemed". Keep the timeout generous, and answer green if the same device redeemed the same voucher a few seconds ago.
- Using a voucher twice at once. Check the remaining uses and take one away in a single database step, so two counters can't both get green.
- Guessable codes. Use long random codes. A readable code like
SUMMER10is a discount code, not a voucher. - Money stays elsewhere. Scan2Check only confirms the voucher. It does not take payments.