This is the tenth post in the FastMail 2015 Advent Calendar. Stay tuned for another post tomorrow.

At FastMail, we offer a simple proposition. Our customers pay us directly, and in return we offer them a great service. As such, it's vitally important to make the whole payment process as smooth as possible. And while there will always be strange issues with banks from time to time that are beyond our control, one thing that we can get right is to make the simple process of filling in your credit card details as frictionless as possible.

In this post, I'm going to share the thoughts and details that went into the construction of our credit card form (note: this form is currently only used in the UI for personal accounts; it's coming for business/family accounts soon too we promise!). We really sweat the details when it comes to UI, and this form is no exception. Go ahead, try it out. It's not connected to any server; everything you type will only stay in your local browser:

If you're reading this in an email or RSS reader, you'll probably need to go to the original blog post to try the demo.

Although it seems simple at first, there's a lot of deep thought and small touches that go into making it simple and pleasant to use:

First of all, the shape is suggestive of a card without being overly skeuomorphic. The inputs are spatially similar to the layout of the relevant information on the card: number on top, spreading across the whole width; name and expiry date below. I can't count the number of times sites have put "name" first, and I've accidentally typed in my credit card number there as I automatically copied the data off the card. The spatial layout also makes it much easier to visually verify at the end that everything is correct.

Placeholders show the expected data format for an input field, so you don't even need to read the labels to know what to put in there. Labels are used too to avoid any doubt; most of these are straight forward, but for the name field we remind people to type it as it appears on the card, not whatever form they use day to day.

The form doesn't ask for information it doesn't need. Many sites want to know if the card is Visa, MasterCard or Amex. You can tell this from the credit card number, so why ask the user to tell you separately? Rule 1 of UI design: don't make the user do work the computer can do for them!

As we gain information, the form can adapt. Unlike with Visa and MasterCard, Amex cards have their security code (CVV) on the front of the card, and it's 4 digits long. If you type in an Amex card number, the CVV placeholder changes to XXXX, and the little infographic changes to show the new location to look for it.

So, the design and labelling is focussed on making it as clear as possible what data the form requires and where to find it. The other part to a successful form is making the data entry itself simple and error-free. The easiest way to fill in a form is to get the computer to do it for you, so we made sure that all the inputs have the appropriate autocomplete attributes (cc-number, cc-name etc.) to make it easy for browsers which support this.

But most people will have to type the details in manually, and to make life easier we try to apply the following general rules:

  1. Be as flexible as possible in the input form the user may type.
  2. Make errors we can detect obvious as soon as possible.
  3. Make it easy to visually compare to the card to verify.

The user can type the credit card number with spaces (as it appears on the card), or without. Our form will automatically insert spaces to match the format shown on the card if you don't do it yourself, but it only inserts a space after you type the first number of the next section. This means backspace will always work to delete the last character you typed if you make a mistake, not some automatically inserted space. Non-number keys are ignored (except space and -, which we treat as a space), so if you accidentally hit "O" instead of "0", it won't enter a hard to spot error.

As soon as focus leaves the card number field, we run all the validations that we can locally and immediately show if there's an error. We check the first few digits match the prefix for one of our accepted card types, the length is correct (16 digits for Visa/MasterCard, 15 for Amex), and that luhn validation passes. If there is an error, we highlight the field and the automatic formatting makes it easier to compare to your card and find the mistake.

The name field is much simpler; the one thing we do is automatically convert letters to upper case to match the format shown on the card. In terms of validation, there's really not much we can do other than check a name was entered. (Although even this violates assumption 40 in the list of Falsehoods Programmers Believe About Names, we have yet to see a credit card with no name. We have however seen a credit card with only one name, which one of our payment providers erroneously rejected as an error. Sigh.)

The expiry field is made up of 2 two-digit text inputs, so it again matches the format of the card, and the user doesn't need to switch context and use a mouse. Following the philosophy of being liberal with what the user can type, the month field will accept a single digit, and if you type "/" or a 3rd digit, it will automatically focus the expiry year field (and insert the digit if that's what you typed).

On blur, we prefix "0" to the month if necessary to match the format on the card, and validate that it is a valid month and year, not in the past, and not more than 20 years in the future.

The CVV field restricts input to numbers only and validates that it's the correct length for the card type (3 for Visa/MasterCard, 4 for Amex).

And that's it, really. Sometimes it takes a lot of effort to make something appear simple! Given the number of frustrating credit card forms we've had to deal with, we hope some of these insights can help improve the situation across the web.