

How to Correctly Detect Credit Card Type - davekt
http://creditcardjs.com/credit-card-type-detection

======
eduardordm
Hi, my credit card company is not listed there, yet it exists: my IIN is 6371.

I'm afraid this is not completely accurate at all. There are many credit card
IINs and those are just a very few and will not work with some international
cards (including international visa cards). Those numbers are issued by the
American Bankers Association - in accordance to ISO 7812. They are not
attached to a credit card flag, but to a company and a single company can have
only one IIN. What happens is that Visa is composed of many companies in many
countries, that's why they have many IINs which may or may not start with the
same numbers, there are no strict rules about that.

The number this website calls 'prefix' is actually named IIN and it's composed
of 6 characters, not 4 (nor 2 or 3). They are disposed in groups of 4 for a
variety of reasons and no issuer owns whole lots of IINs.

The only completely correct way to detect a credit card is to just contact ABA
to obtain a list of issued IINs.

This is what an issued IIN looks like, we also have many:

[https://drive.google.com/file/d/0B-Sa2A0cesh4eDVMY3NwQ3ZEVlZ...](https://drive.google.com/file/d/0B-Sa2A0cesh4eDVMY3NwQ3ZEVlZfQllyNEdmdHliekdXenNV/edit?usp=sharing)

I also built a thing to help me parse those numbers (ruby):

[https://github.com/eduardordm/iso7812](https://github.com/eduardordm/iso7812)

~~~
nandemo
I suppose the idea is to determine the so called "card scheme" (Visa, Master,
etc), not necessarily the IIN. E.g. for some payment processors, the merchant
service charges are different according to the card scheme (it does't depend
on the issuer). I undertand this is a simplification and it might not work for
cards that don't belong to major networks, but it's good enough for a lot of
businesses.

For example, if I have a business here in Japan, I doubt I could easily charge
a card issued by your company (I'll be happy to be proven wrong).

Ps: brasileiro aqui.

~~~
eduardordm
Oi!!

The general idea is this: IIN is issued to visa branches around the world each
branch can only have one IIN. Problem is, visa is not the only issuer of visa
cards. Many banks and financial institutions can also issue in lieu of visa
and have their own IINs as they please. My visa credit card starts with 2
because it was issued by an airline under a mileage program. I never had
problem using it online but most websites won't show the correct card type.

Merchants are not charged according to a card type, the charges applied to
merchants have nothing to do with visa. Visa is only doing processing service
for a bank. Banks are the ones who charges merchants and pay visa a percentage
of the fee the bank charges you. Because banks can't handle the volume of
merchants, they usually have gateways or other companies to do that for them.

My company also issue visa cards and we use the same IIN: 6371.

~~~
nandemo
Thank you for the clarification. However, my point is that some gateways _do_
charge according to the card type.

------
pkteison
Please don't rely on this.

For example of the extra detail that is really involved, see:
[http://en.wikipedia.org/wiki/List_of_Issuer_Identification_N...](http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers)
\- e.g. 504837 is ATM only despite looking like a MasterCard.

Card identification also occasionally changes - Diners was bought by
MasterCard, Visa used to be 13 digits, etc.

I'd be really wary of hard-coding this anywhere. If it passes the Luhn
algorithm and the first digit is ok, consider just passing it on to your
processor and seeing if it gets approved. Add a black list of known-not-to-be-
valid prefixes if you'd like. But a whitelist of valid prefixes will break one
day without warning while also not really being the full list of valid
prefixes you think it is.

If you really need to be doing this, you can pay for a regular feed from a
processor, but the only use case I've ever seen for truly needing that was to
identify debit cards by number.

I've had cashiers force through faked manual auths on 19 digit private bank
debit cards, which I assume is fraud disguised as incompetence. But I think
dealing with a few weird cases (with proper auditing in place) is better than
declining a legit card because they expanded the valid prefixes and your code
wasn't updated.

~~~
dlubarov
> Diners was bought by MasterCard

MasterCard didn't acquire Diners, it was just a partnership where Diners cards
were branded as MasterCard and processed through MasterCard's network. Later
Discover acquired Diners, and now they're processed through Discover's
network.

But fair point - brand prefixes occasionally change, and if you hardcode them
they'll eventually become out of date.

------
birken
Another usability tip on credit card forms: Don't use drop-downs for the
expiration date.

People are just typing them directly off the card, let them type them. Don't
force them to deal with large and annoying select boxes. Stripe checkout[1] is
a good example of how to do it (though by no means were they the first to do
this, just a popular example).

1: [https://stripe.com/docs/checkout](https://stripe.com/docs/checkout)

~~~
danielweber
I can type right into a drop down, and 99 times out of 100 it will do the
right thing.

(Sometimes it's weird with a list of states, where it might be sorted by the
state abbreviation while showing the state name or vice versa.)

~~~
mrobins
agreed but on mobile I find spinning through the drop-down more annoying than
typing the exp date.

~~~
kalleboo
I really hate the spinner for all the date selectors on iOS - it's cute, but a
keypad is way faster.

------
mrweasel
Why is detecting credit cards even useful?

I know what card I have, you telling me "Yep that's a VISA card" isn't really
that helpful. Yes, I might enter the first four digits wrong and see the wrong
card icon light up may help me a little, but aren't I just as likely to enter
the last 12 digits wrong. In the case of VISA you're pretty much just telling
me "Yep, that first one is a 4".

~~~
medell
Wouldn't it save the user one click to select what card they've got?

~~~
thefreeman
I think the GP is questioning whether that piece of information is even
necessary to process the transaction.

~~~
neohaven
"We can't take American Express".

It's a valid thing to say, and a valid thing for you to detect and notify the
user about. You know, before they finish typing everything else they have to
type in.

------
steven2012
Why does it even matter if you show the credit card type when the user is
typing it in? If the first 6 numbers determine the card type, then handling
card type can be done on the backend. Why make the effort to show users
information that they already know, ie. card type?

~~~
ry0ohki
I'd say in part because you want to give people a UX they are comfortable
with. Sites for years have been asking for "Card type", and so a user may
suspect something is wrong if they don't need to enter it and show no
indication you know what it is.

~~~
eli
That seems unlikely, but I've certainly been wrong about UI questions before.
I'd be very curious if anyone has any data supporting this idea.

~~~
qq66
No data, but as a user I do expect to see a card type selector or indicator,
even though I rationally know its superfluous.

------
NathanKP
The root lesson here is pretty simple but important: you should usually avoid
using regular expressions in places where readability and ease of update is a
concern.

Using a complicated one line regular expression to do all the magic is fun,
but its a nightmare to maintain and figure out how it works later on.

------
zaroth
The data structure they mention using is an 'inversion map' which in their
case is a mapping of numeric ranges to values.

I did some quick searching and didn't find it... I wonder how they implement a
key search in the inversion map. I assume you do something like populate a
tree with the range transition points and then you can search in O(log n).

A search on the tree would have to find the node with the highest value that
was <= the requested value, or the lowest value that was >= the requested
value.

I assume the work of constructing the tree would have to be amortized over
multiple searches to make it worth the effort. Could you do better than O(n)
_without_ building a tree?

In creditcardjs.com's case, they have overlapping ranges, which means you can
possibly return multiple values for a given key.

------
pathikrit
Would be nice to combine this with
[skeuocard]([http://kenkeiter.com/skeuocard/](http://kenkeiter.com/skeuocard/))

------
lamby
I'm using jquery-payment from Stripe. Should I switch?

~~~
cschmidt
You should be fine. I use it along with the technique in this blog post to
make a nice stripe form that dynamically displays the card logo....

[https://yoast.com/checkout-field-validation/](https://yoast.com/checkout-
field-validation/)

------
nogridbag
There's a small bug with the security code tooltip. Click the ? to open the
tooltip (shows AMEX), focus the card number field, select-all (cntrl-a/cmd-a),
then type "4". It still shows AMEX in the tooltip instead of visa. Closing it
and opening it will still show AMEX.

------
jonalmeida
Relevant to the post.

Gizmodo (strangely) posted an interesting article on how on credit card
numbers work: [http://gizmodo.com/how-credit-card-numbers-
work-1493331190](http://gizmodo.com/how-credit-card-numbers-work-1493331190)

------
gwintrob
Interesting to read about inversion maps. I'm a bit confused - why would I
want to purchase a license vs. using something open source like
[https://github.com/wangjohn/creditly](https://github.com/wangjohn/creditly)?

------
fyresite
Visa starts its 16 digit string with "4" Mastercard starts with "5" Amex
starts with "3" and only has 15 digits Discover starts with "6"

------
nickjamespdx
worth noting:
[https://github.com/kenkeiter/skeuocard](https://github.com/kenkeiter/skeuocard)

~~~
Joshu42
4147 20XX XXXX XXXX broke the design.

------
nly
This seems hopeless all the time the prefixes actually overlap. e.g. according
to this, both Laser and Maestro use 6304

------
joshfraser
I'd rather have one clean regex than dozens of lines of code to do the same
thing.

------
zaroth
I think the correct answer is: "Don't bother"

------
Flenser
previous discussion:
[https://news.ycombinator.com/item?id=6692075](https://news.ycombinator.com/item?id=6692075)

------
xarien
Or you could just use stripe. Just saying ;).

------
sandieman
Does this integrate with Recurly?

------
untilHellbanned
$299!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

~~~
Theodores
How many develop hours do you think it takes to get a full feature checkout
working?

From the comments here I believe that some more work is needed for the card
detection, however, to 'roll your own' with your employer paying? Could cost
more than $299.

Personally I think there is a lot to be said for basic checking and having a
drop-down for the card type with the accepted card types spelt out for people.
Oh, and with a Paypal option for those that don't like putting their card
details into random websites.

~~~
acorkery
It's hardly a full feature checkout..

Correct me if I'm wrong, but it just seems like a user-friendly form with
client side validation. You still need to integrate it with a payment
processor, hook it into your checkout process where you capture delivery,
billing and order information.

I also think it's not worth $299, especially when each license is per-website
only.

------
fyresite
Amex starts with "3" Visa starts with "4" Mastercard starts with "5" Discover
starts with "6"

