Yes, my credit card number *does* have spaces!

Credit CardOkay, so here’s a little rant (by a fellow developer) about web forms that accept credit card numbers. Or rather, web forms that don’t accept them very well.

Many card number input boxes are limited to 16 characters, meaning when I get up to “1234 5678 1234 5” and then try to type the last three digits … BANG, input box full, no more typie. I have to go back and delete the spaces, making it harder to read and check. I had this just today when paying for my Highrise account (though I’m not really picking on 37signals — it happens on many payment sites).

The other one that I get fairly often is when a site lets me enter the number with spaces, but then the server-side check comes back and says “invalid credit card number”. Um, no it’s not invalid — I’m typing it exactly as it appears on my card.

C’mon, folks, we’re programmers! Stripping out non-digits is the kind of thing computers can do in nano- or micro-seconds. What exactly is so hard about adding one line of code?

    card_number = ''.join(c for c in card_number if c.isdigit())

If you’re taking money that I want to give you, please at least let me enter my card number as it appears on my card — digit groups separated by spaces. Stripping really isn’t that hard! :-)

12 July 2013 by Ben    28 comments

28 comments and pings (oldest first)

Berwyn 13 Jul 2013, 09:53 link

My related pet peeve is websites that can’t accept phone numbers with spaces nor in international format: +64 3 741 1204

Berwyn 13 Jul 2013, 10:24 link

What’s even worse is when they have four different fields where you can enter your card number (4 digits in each field) and it doesn’t move automatically between the boxes, so you can’t copy’n’paste.

Ben 13 Jul 2013, 10:31 link

True true. Like the “IP address entry boxes” on older versions of Windows. Someone thought separating them into four separate boxes was a good idea, but it makes copy’n’paste a nightmare.

Leonid Volnitsky 13 Jul 2013, 13:29 link

I used to work on mainframes in 80’s. And I remember that ALL application would accept phone numbers with spaces and (). And when I moved to PC (and later Web), to my surprise, no application would understand common separators in phones, IPs, CC numbers.

Darryl 13 Jul 2013, 15:35 link

The other annoyance is that you have to select the credit card type. This can be determined programatically (eg: Visas are 16 digits with a leading 4 — 4012 8888 8888 1881).

Ariven 13 Jul 2013, 15:40 link

Visa can be 13 or 16 digits though the 13 digit ones are supposed to be migrated to 16, and are not the only card that starts with 4.

http://en.wikipedia.org/wiki/Bank_card_number

Though I agree, determining what type of card it is can usually be handled server side or by a query to your processor.

Zack Bloom 13 Jul 2013, 16:33 link

Other filtering options include:

filter(lambda d: d.isdigit(), card_number)

and

card_number.replace(' ', '')

Matt Tew 13 Jul 2013, 16:48 link

Joke’s on you, Mr Surname. Now I have your credit card number.

Explo Derator 13 Jul 2013, 18:11 link

You are a whiner.

Aren’t semi-transparent user interface elements and animations good enough for you? What kind of wizardry do you expect anyways? Capable, well thought out ergonomics? Bah!

Get over yourself, the world needs more bling and bedazzle and vagazzle, not things that work reliably and eloquently and efficiently and naturally. What you need is an app for your pissy attitude.

Brock 13 Jul 2013, 19:38 link

“Stripping isn’t that hard” That’s what I tell the ladies.

Kenny 13 Jul 2013, 19:55 link

Your code doesn’t remove white space. It reconstructs the exact same string.

Nathan 13 Jul 2013, 20:03 link

No need for the lambda in Zack Bloom’s answer! :)

filter(str.isdigit, card_number) will work fine.

Stu 13 Jul 2013, 22:04 link

Or just use an incredibly simple regular expression.

s/\D//g

Henry H. Thomas 13 Jul 2013, 22:07 link

Not joking; would this be considered an indication that the OP is a little higher up on the aspergers spectrum than “normal”? I mean, he is a programmer after all.

William Gannon 13 Jul 2013, 22:51 link

Why not just put the onus on the client in the first place? How hard is it for javascript to strip out non-digits using a simple regex?

Seri 13 Jul 2013, 22:53 link

@Ariven One reason why payment sites like to make the user select their card type is that it adds another (albeit minor) level of security.

Especially where a VISA Debit card is quite different to a VISA credit card in the way it’s processed.

Jon 14 Jul 2013, 01:02 link

Websites should all perform client side validation for CC number. No need for a round-trip to the server to know a digit is off.

http://en.wikipedia.org/wiki/Luhn_algorithm

Benn 14 Jul 2013, 01:38 link

I’d use an algorithm that replaces spaces rather than one that removes everything but digits. Including spaces because “that’s how it appears on the card” is reasonable, but including anything other than digits and spaces should throw an error.

Andres S 14 Jul 2013, 02:28 link

Wouldn’t it be better to have 4 input boxes, and autofocusing the next one when the current’s length is already 4?

George 14 Jul 2013, 02:37 link

4 input boxes would take a little finagling to not muck up cut & pasting. I use a virtual credit card # tool, so that makes a big difference to me.

me 14 Jul 2013, 02:43 link

I’ve even seen a special “you must remove spaces from your input” error message. I suspect a horrible top-down development environment, probably with screwy regulations like “may not programatically alter customer input” is to blame.

Philo 14 Jul 2013, 03:30 link

The credit card thing seems to be a new trend. I don’t think I saw it at all before 1-2 years ago. On the other hand – phone number fields. Holy crap, how hard is it to just store the whole string? Or strip out parens, hyphens, dots, and spaces.

And why do sites try to validate it? I’ve even seen a site that wouldn’t accept a 555- number. Take the hint, you moron – I don’t want you to call me.

When I see sites that only accept digits in a phone number field, I always have this sneaking suspicion that they’re storing it as an actual number.

Joker_vD 14 Jul 2013, 04:45 link

@Philo: Yep. Sometimes programmers think they know everything about the data they are validating, but usually it’s not so. For example, Ukrainian mobile phone numbers have 11 digits when in international format—yes, not 10, but 11! Good luck trying to enter it.

Really, just store the string as entered. If you need to show it on a screen, it will show up nicely. If you need to dial it programmatically, strip all separators.

And what about making it “necessary field”? What if I really don’t have a phone? That’s discrimination!

Athox 14 Jul 2013, 21:06 link

cc.split(' ').join('')

est 14 Jul 2013, 21:43 link

@Zack Bloom

card_number = filter(str.isdigit, card_number)

Ben 15 Jul 2013, 07:45 link

@Athox, is that the new AlmostPython language? :-) I think in Python you’d say ''.join(cc.split()).

@est and @Zack: true, you can use filter(). But as far as I’m concerned, filter, lambda, and co are the LispPython equivalents of Python’s more flexible list and generator comprehensions.

Mike 16 Jul 2013, 00:22 link

Shouldn’t this be up to w3c to make a standard?

[…] over at Brush Technology, has a splendid rant on something that I’ve written about before on my old blog. Why, in 2013, are we still […]