Stripe launched a new version of Checkout, a payments page designed and maintained by Stripe that online businesses can leverage to start accepting payments quickly and easily.
Given Stripe is a hot name in the payments world I thought I’d compare the UX of the Checkout card capture form to the UX of the same form that we’ve built at my company. I have heavily modified my original post to leave out info about the company I work for but I’ve kept the commentary about Stripe’s flow. The focus on any particular point is likely because it differs to the way things are at my work.
Stripe Card form
Here’s an image of the Stripe card capture form on desktop. You can check out a live demo here.
Expiry date UX
There is no explicit label for the card expiry date. It is only signalled with the ‘MM/YY’ inline label. In Australia it’s common for cards to have both the card issue date and expiry date printed on the front. I’m not sure of the norm in the USA but I wonder if the lack of labelling on expiry date confuses older or less tech-savvy customers.
Stripe have good UX for the entry of the expiry date. They provide flexibility around data entry in this field. They allow the customer to enter the
/ separator and/or the leading zero in the expiry month, but don’t force them to enter either in most cases.
Stripe’s expiry date field, which expects data in the
MM/YY format, has the following functionality:
- If the first digit entered is a 0 then the customer isn’t allowed to enter
/or another zero. The customer can only enter a digit, 1-9. Once they’ve entered the second digit the
/separator is automatically displayed after the two digits that have been entered. This seems pretty standard but some sites don’t let you enter the
/and instead force you to enter the leading zero before the
/is displayed after entering two digits.
- If the first digit entered is a 1 then the form waits to see if the customer enters another digit or the
- If the character entered after the 1 is
/then the leading zero is added so the input shows
01/, ready for the customer to enter the value for
- If the character entered after the 1 is the digit 1 or 2 (i.e. the customer has entered 11 or 12) then Stripe takes that value as the month and the / separator is added.
- If the customer meant to enter
01/2Xbut they didn’t enter the leading zero so it’s showing
12/XX, then they can fix it by either navigating to the start of the field and entering a zero or by clearing the field and entering 1 then
- If the customer meant to enter
- If the character entered after the 1 is a digit 3-9, Stripe takes that to mean the 1 indicates the month of January and the card expiry
YYstarts with the second number entered e.g. it’s in the range 30-39 if the second digit was 3.
- Given most card expiry years are in the 2020-2029 range (at least in the countries I’ve worked with) I don’t think this functionality is particularly useful at the moment but it will become more useful in the future. The functionality still makes sense as the alternative would be to allow a month >= 13 to be entered.
- If the character entered after the 1 is
- If the first digit entered is 2-9 then the leading zero and the
/are added automatically so the display shows e.g.
02/, when 2 is entered. This leaves the customer to enter the expiry year.
If you’re using a single field to capture month and year of card expiry, the implementation above seems to work well. I wonder if splitting the expiry date into two separate fields of MM and YY would be better for customers.
The Stripe checkout page autofills properly with saved cards from the Chrome browser and Lastpass password manager, fitting the MM/YY format automatically.
On the Stripe form the ‘CVC’ field doesn’t have a field label, and is just a placeholder with a very small illustration highlighting the 3 numbers on the back of the card. I think the highlighting of the three digits is quite subtle and may not help many customers who don’t already know what the CVC is.
ZIP/Postal code for some countries
Stripe requires Zip/postal code for US, Canadian and UK card payments. I know this isn’t necessary to process but I understand it can reduce fraud. I’d love to know the fraud/acceptance tradeoff being made.
Could Stripe show the ZIP/postal code fields only when they detect the card is a US/CA/UK issued card? I know card issuing country does not necessarily equal billing country, but I guess it is the same in >99.9% of Stripe’s cases. My guess is that assuming they are the same leads to better conversion.
Stripe is using native select for the country dropdown. I think native select is particularly gross on iOS with the ‘spinner’ selector and isn’t particularly nice on web. Interesting they haven’t implemented a custom select with filter functionality.
If a customer pastes a card number with non-numeric values, Stripe strips them and preserves the digits.
If a customer pastes e.g. 4242-4242-4242-4242 into the card number field Stripe converts strips the hyphens, converting it to 4242 4242 4242 4242
Field labels and placeholders
The section labels, field labels and placeholders on Stripe’s card entry form are interesting in their own right. There isn’t a clear usage pattern for section labels, field labels and placeholders on the page. In some cases the field label is above the field, sometimes it’s inline, and in the case of the ‘card number’ field there is no field label, just placeholder text.
In the screenshot above there are four fields that don’t have an out-of-field label (they either have an inline label or no label at all). These fields are card number, card expiry date, CVC and ZIP. Relying on an inline label or placeholder can be an issue when the placeholder disappears on field focus and then the customer is unsure about what to enter in the field, or the format in which to enter it. This is more of an issue when the field formatting is complex or ambiguous, or the customer has to shift attention away from the form, gather the details for input, then navigate back to the form. Customers often have to break focus to get their card details if they haven’t memorised them.
Stripe don’t dismiss the placeholder on field focus. Check out the example below – the MM/YY persists on focus and isn’t dismissed until the first character is entered. This is good UX.
The card number field doesn’t have a label and instead is signalled with a placeholder value for the card number along with the card scheme logos in the field. The card scheme logos indicate the types of cards accepted. There are three main scheme logos (Visa, Mastercard and Amex) and in the fourth spot they display a logo that slowly rotates between the other schemes they accept (see GIF below). I’d be interested to understand if this is useful for customers from one of the smaller schemes.
Watch the ‘total due’ in the bottom right of the GIF below for the transition/animation of the price going down when a promo code is applied. It’s a fast animation, but it’s quite nice.
I pressed ‘enter’ after entering my discount code, but that didn’t work. Instead I had to select the ‘Apply’ button which only appeared after entering the a character in the input field. Would have been nice to be able to just use the keyboard.
Weird promo code functionality
I was surprised to see that when I went to put the discount code in to record the GIF above, it tried to use the code I’d used previously as autocomplete. I can’t think of a reason to save coupons in your autofill variables so I assume it’s a small bug, perhaps only on the demo page. It seems the autocomplete token for the promotion-code field is set to
fake which isn’t part of the recognised list of tokens.