PeakVoucher · Research

A voucher code is cash. Here is how a wallet app should treat it

Gift cards are bearer instruments: whoever reads the code spends it. The FTC has ranked them among the most reported fraud payment methods for years. Five rules for an app that stores them.

By the upeak team4 min read2 sources
Gift card · ₪150 ₪150 EXPIRES IN 12 D CODE•••••••• FETCH The list carries names and values. The code is fetchedonly when this one is opened

Key takeaways

  • A voucher code is spendable by whoever reads it; store it like cash, not like a note.
  • Fetch codes one at a time, keep keys out of URLs, enforce roles on the server, fail closed.
  • An assistant over the wallet should have read-only tools and a transcript that is never written to disk.

Nobody would keep a stack of banknotes in a note-taking app. A gift-card code is the same thing in fewer bytes, and most voucher apps store it as if it were a shopping list.

Bearer instruments

A voucher code has no owner. The till does not check who is presenting it; it checks that the code is valid and has balance. That is why gift cards are the payment method scammers ask for: the FTC's data spotlight on gift-card fraud found them the most reported payment method for scams for several years running, precisely because a code read over the phone is money gone. An app that holds your codes holds a stack of cash, and it should be designed by people who believe that.

Rule one: never list codes in bulk

The obvious design fetches the whole wallet, codes included, in one request, because it is simpler. It also means one intercepted response, one screenshot of a debug log, or one leaked cache is the whole wallet. The list should carry names, values and expiry dates. A code should be fetched only when you open that one voucher, and only that code.

Rule two: keys in headers, never in the address

Anything in a URL's query string ends up in server logs, proxy logs, browser history and the Referer header of the next page you visit. An access key belongs in a request header. When a share link has to carry a key, it belongs in the fragment after the #, which RFC 3986 says browsers never transmit; the app reads it once and rewrites the address bar.

Rule three: roles decided on the server

Sharing a wallet with a partner is the whole point of a household wallet, and a viewer should be able to read codes and mark a voucher used without being able to add, delete or share on. Hiding the buttons in the app is not enforcement. The server has to know which key it was given and refuse the write, so that a modified client gets a 403 rather than a new voucher.

Rule four: fail closed

If the server is misconfigured, if the secret is missing, if a request arrives with no key, the answer is a refusal, not a best effort. An API that returns the wallet when it cannot tell who is asking has one failure mode, and it is the expensive one.

Rule five: an assistant gets read-only tools

An assistant that can answer which of these can I use for lunch? is useful. To be safe it needs the wallet as context without the codes, a single tool that fetches a code only when a code is actually asked for, capped to a handful of vouchers per call, and no tools that write. Its transcript should live in memory and nowhere else.

How PeakVoucher does it

Every rule above is a description of PeakVoucher's server. The list endpoint withholds codes, a code is fetched one voucher at a time, the key travels in a header, share links carry theirs in the fragment, owner and viewer are separate keys enforced before any read or write, a missing secret makes every route return 503, and the assistant has one read-only tool. The barcode is drawn on the device from the code you just fetched, and on the watch the screen goes to full brightness while it is showing, then back.

PeakVoucher is built for this

A wallet for the vouchers buried in your messages. Coming soon, in private beta.

Explore PeakVoucher

Questions

Is a photo of the card in my gallery a bad idea?
It is the bulk-list problem in a different form: the gallery syncs, backs up and is readable by any app with the photos permission. A wallet that fetches codes on demand is safer.
Can PeakVoucher's assistant spend or delete a voucher?
No. It has no write tools. It can read the list and, when asked, fetch a code for up to a few vouchers at a time.
What does a viewer see?
Everything an owner sees, including codes, and they can mark a voucher used. They cannot add vouchers or share the wallet further.

Sources

  1. Federal Trade Commission (2021). Data Spotlight: Scammers prefer gift cards, but not just any card will do. https://www.ftc.gov/news-events/data-visualizations/data-spotlight/2021/12/scammers-prefer-gift-cards-not-just-any-card-will-do
  2. Berners-Lee T., Fielding R., Masinter L. (2005). RFC 3986, Uniform Resource Identifier: Generic Syntax, section 3.5, Fragment. https://www.rfc-editor.org/rfc/rfc3986#section-3.5