How Gift Card Codes Are Generated and Kept Secure
There's a story that made the rounds in retail security circles a few years back: researchers found they could guess valid gift card codes for a major retailer simply by trying enough combinations quickly, because the retailer's lookup system had no meaningful rate limit and the codes themselves weren't quite random enough. It's a good reminder that a gift card code isn't just a string of characters, it's a key to real money, and it needs to be treated with the same seriousness as a bank account number, because functionally that's exactly what it is.
A gift card code is a randomly generated string tied to a stored monetary value in a database, usually with a check digit to catch typos instantly and rate limiting to slow down guessing attacks. Security depends less on the code's length and more on how carefully the redemption system verifies and throttles attempts.
What actually happens when a gift card code is created?
Behind the scenes, a gift card code is a random identifier that gets tied to a row in a database recording a monetary balance. The code itself carries no value on its own, it's a key that unlocks a value stored elsewhere on the retailer's servers. This is a meaningful distinction: cloning the code format doesn't get you anything unless that exact code also exists in the retailer's system with a real balance attached. Generating a gift card code that merely looks correct proves nothing about whether it's actually redeemable.
Why do gift card codes usually include a check digit?
Most gift card formats end with a check digit, a final character mathematically calculated from everything before it, using a formula similar to the one that validates credit card numbers or barcodes. If someone mistypes a digit while entering a code, or if an attacker is guessing codes randomly, the check digit lets the system reject the overwhelming majority of invalid attempts instantly, without ever needing to query the database. It's a cheap first filter that catches typos and casual guessing before either reaches anything that actually matters.
Why does the length of a gift card code matter less than you'd think?
Intuition says a longer code is always safer, and that's true up to a point, but the length of the code matters less than how the redemption system behaves once a wrong guess comes in. A sixteen-character code protected by an endpoint with no rate limiting can still be brute-forced given enough time and enough automated requests. A ten-character code protected by an endpoint that locks out an IP address after five failed attempts is, in practice, far harder to break. The lesson retailers have learned the hard way is that the code is only half of the security model. The other half is how aggressively the system throttles and monitors failed redemption attempts.
Why do gift card systems avoid characters like O, 0, I and 1?
A code that's hard to read out loud or type correctly generates support tickets, refund requests and frustrated customers, none of which help a retailer's bottom line. Excluding visually ambiguous characters, the letter O versus the digit zero, the letter I versus the digit one, the letter l versus the digit one, removes an entire category of "I typed it correctly but it still didn't work" complaints without meaningfully shrinking the usable code space. It's a small design choice that pays for itself in reduced support load.
What can a small business learn from how big retailers do this?
The principles scale down cleanly even for a small shop issuing a few hundred gift cards a year: generate codes long enough that guessing isn't practical, exclude ambiguous characters to cut down on support friction, track redemption against a real stored balance rather than a simple valid or invalid flag, and never assume that the code format alone is what's protecting the money. The database and the rules around how often a code can be tried are doing at least as much of the security work as the code itself.
If you're setting up a gift card or voucher system and want to see what a properly formatted batch looks like, the gift card code generator on this site produces codes with configurable length, character sets and ambiguous-character exclusion, entirely client-side.
Frequently Asked Questions
Can someone guess a gift card code and steal the balance?
In theory yes, in practice rarely, because a properly issued gift card code draws from a space large enough that guessing it is impractical. The real risk historically has come from retailers checking codes too slowly, which let attackers try thousands of guesses before getting blocked, not from the code length itself.
Why do gift card codes usually have a check digit?
A check digit is a final character mathematically derived from the rest of the code. It lets a system instantly reject a mistyped or partially guessed code before even checking whether that code exists, which cuts down on wasted lookups and slows down brute-force attempts.
What's the difference between a gift card code and a voucher code?
Functionally very little. Both represent a stored value that gets redeemed against a purchase. The main difference is convention: gift card usually implies a physical or digital card product, while voucher code is the more general term for any code representing stored value.
Why do some gift card codes get rejected even though they look correct?
Most systems rate-limit how many attempts they allow before locking out further tries, specifically to stop scripted guessing attacks. A code that looks right but keeps failing may be locked out, expired, or already redeemed rather than mistyped.
Should gift card codes be case-sensitive?
It varies by system, but ambiguous characters like the letter O and the digit 0, or the letter I and the digit 1, cause more support tickets than security benefit. Many gift card systems exclude these characters from the code alphabet entirely rather than relying on case sensitivity to disambiguate them.
Can I generate my own gift card codes for a small business?
Yes. The pattern still applies at small scale: use a code long enough to resist guessing, avoid ambiguous characters, and track redemption against a stored value rather than treating the code as a simple yes or no flag.