The fraud rule was simple.
Look at the first six digits
of the card.
That is the issuer.
Check the issuer's country,
compare it with the billing address,
and flag the order
if the two disagree.
The same six digits
went into the database
next to the last four,
so support could see
which bank a customer used.
It worked for years.
Then the flags started drifting.
A customer of a small bank in Lisbon
was flagged as foreign.
A card from a big British issuer
came back labelled
as a fintech nobody had heard of.
No code had changed.
The cards had.
Here is the mechanism.
The leading digits of a card number
are the issuer identification number,
the BIN.
For decades it was six digits long.
Six digits
give you a million ranges,
and between banks,
fintechs,
prepaid programmes
and a virtual card
for every subscription,
the world ran out.
So the international standard
was revised to eight,
and the big card networks
moved over in April 2022.
Eight digits
give a hundred times the room.
New ranges are handed out
at eight digits now,
and two different issuers
can share the same first six.
Your lookup table
keyed on six
has collisions in it,
and every year
it gets a little more wrong.
Nothing breaks.
The answers just get worse,
which is the kind of failure
nobody files a ticket for.
So look for the number six
wherever cards are handled.
The column that stores the BIN.
The rules engine.
The lookup file
somebody downloads once a year.
The routing table
that picks a payment provider.
Store eight.
Look up the longest match first,
eight, then six,
so the old ranges still resolve.
Take the data from a feed
that knows about eight digit ranges,
and refresh it
like the dependency it is.
Check what you display, too.
The card industry's guidance
now lets you show the first eight
and the last four
on cards of sixteen digits or more,
and fewer on shorter ones,
so masking code
written around six
needs a second look.
Then make the length a setting,
not a number buried in the code.
Six digits lasted for decades.
Do not build as if eight will.
– Serguey Asael Shinder
Top comments (1)
the collisions point is the one that hurts in production: two issuers sharing the same first six means a fraud rule keyed on six can flag a legitimate card as foreign based on a different bank entirely, which matches the drift you describe. the longest-match-first lookup is the right migration shape since it keeps legacy six-digit rows resolving while the eight-digit feed catches up, and treating the BIN table as a refreshable dependency rather than a one-time import is the part most teams never set up.