{"id":2330,"date":"2016-08-02T12:08:27","date_gmt":"2016-08-02T11:08:27","guid":{"rendered":"https:\/\/marvel7077.wpengine.com\/?p=2330"},"modified":"2016-08-25T12:33:52","modified_gmt":"2016-08-25T11:33:52","slug":"the-anatomy-of-a-credit-card-form-2","status":"publish","type":"post","link":"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/","title":{"rendered":"The Anatomy of a Credit Card Form"},"content":{"rendered":"<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Paying for something online with a credit card is simple, right? Yes and no. Yes, because we\u2019ve been doing it since the early days of the Internet (e.g. Amazon), and no, because no two credit card forms are alike.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Over the past 20 years, we\u2019ve built a mental model of paying online: I pull out a credit card from my wallet, enter the card details into a web form, and click a submit button. But getting from A to Z can be a tricky journey, riddled with questions the user has to answer. And obviously, nobody wants an instruction manual.<\/p>\n<div id='gallery-1' class='gallery galleryid-2330 gallery-columns-1 gallery-size-full'><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw.png'><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"1259\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw.png\" class=\"attachment-full size-full\" alt=\"\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw.png 1600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw-600x472.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw-768x604.png 768w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-3ecCtDR1Lxa0nZFHUtpNWw-1500x1180.png 1500w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\" \/><\/a>\n\t\t\t<\/dt><\/dl><br style=\"clear: both\" \/>\n\t\t<\/div>\n\n<blockquote class=\"pageWrap pageWrap--s position-relative marginTopBottom-l breakPointM-marginTopBottom-xl\"><div class=\"blog-quote-before position-absolute bg-marvel\"><\/div><div class=\"tweet-quote blog-quote-after position-absolute bg-marvel cursor-pointer transitionDuration-l transitionProperty-all transitionTimingFunction-cv-easeOutCircular scaleUp--hover zi-weak\"><svg class=\"fill-white opacity-0 pointerEvents-none position-absolute pinCenter transitionProperty-all transitionTimingFunction-easeInOut\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"20\" viewBox=\"0 0 24 20\"><path d=\"M24,2.37a9.64,9.64,0,0,1-2.83.79A5,5,0,0,0,23.34.37a9.72,9.72,0,0,1-3.13,1.23A4.86,4.86,0,0,0,16.62,0a5,5,0,0,0-4.8,6.2A13.87,13.87,0,0,1,1.67.92,5.13,5.13,0,0,0,3.19,7.67,4.81,4.81,0,0,1,1,7a5,5,0,0,0,3.95,5,4.82,4.82,0,0,1-2.22.09,4.94,4.94,0,0,0,4.6,3.51A9.72,9.72,0,0,1,0,17.73,13.69,13.69,0,0,0,7.55,20c9.14,0,14.31-7.92,14-15A10.17,10.17,0,0,0,24,2.37Z\"\/><\/svg><\/div><p class=\"blog-quote position-relative textAlign-center c-marvel\"><span class=\"blog-quote-text transitionDuration-l transitionProperty-all transitionTimingFunction-easeInOut\">Paying for something online is still 2\u20133x clunkier than paying in-person.<\/p><\/span><\/blockquote>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Nothing beats tapping\/swiping your card at a physical terminal. Zero typing required. You don\u2019t even care about the information printed on your card. In a magical world, you could tap your card on your monitor to buy a swag new T-shirt from your favourite band. Or get rid of physical cards altogether, so you don\u2019t have to pull out a card from you wallet. We\u2019ve made significant progress in the physical world with Apple Pay.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Online, we\u2019re getting closer. Paying online will become easier, and faster. The latest HTML spec includes specifications for <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/html.spec.whatwg.org\/multipage\/forms.html#attr-fe-autocomplete-cc-number\" target=\"_blank\">credit card inputs<\/a>, and browsers are pushing the boundaries. Chrome 42+ <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/greenido.github.io\/Product-Site-101\/form-cc-example.html\" target=\"_blank\">supports autocomplete<\/a>. Safari supports <a class=\"link link--blue fontWeight-4\"href=\"http:\/\/www.cultofmac.com\/235409\/add-credit-card-info-to-safari-autofill-with-mavericks-beta-os-x-tips\/\" target=\"_blank\">credit card autofill<\/a>. But you still need a physical card to manually input your security code with every transaction.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><span class=\"long-quote\">Before credit card forms become a thing of the past, we still have the present-day task of adding clarity, simplicity, and security to the credit card form.<\/span><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">At <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/www.waveapps.com\/\" target=\"_blank\">Wave<\/a>, our Invoice product enables business owners to create and send invoices to their customers, and to have those invoices paid via credit card. My job was to design the credit card form, given a set of business requirements and constraints. This post is about the design considerations our team explored to arrive at the finished product.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-9FXNyPVwGQRwMQFkNkvzfw.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2373\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-9FXNyPVwGQRwMQFkNkvzfw.png\" alt=\"\" width=\"306\" height=\"586\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Our goal was to make sense of all the various inputs and questions a user may have, including:<\/p>\n<ol class=\"pageWrap pageWrap--s list list--ordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>What payment cards are accepted?<\/li>\n<li>Deciding how much to pay<\/li>\n<li>Name on card<\/li>\n<li>Card number<\/li>\n<li>Card type being used<\/li>\n<li>Expiry date<\/li>\n<li>Security code<\/li>\n<li>Why is there a ZIP code?<\/li>\n<li>Is this form safe and secure?<\/li>\n<li>What happens when I click submit?<\/li>\n<li>Handling card errors<\/li>\n<li>Designing for different screens<\/li>\n<\/ol>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">1. What payment cards are accepted?<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">When the customer is presented with the credit card form, one of their first questions is \u201cIs my credit card accepted\u201d? This behaviour is the virtual equivalent of the physical-world scenario. When you\u2019re at a physical counter ready to pay, you look for stickers to indicate the cards supported. So the common way to answer the question is by using credit card logos.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">But, where do you place the logos on a web form? At first we tried to place them above the card number field. This placement reduces the height of the form, but the cards are small and look squished. Another option was to place them inside the input. This almost worked, but because we have a narrow input field, the cards took up too much space, overpowering the input. We decided to place the credit card logos at the top of the form. This placement makes them immediately visible, because they are the first element a user has to parse visually. The user doesn\u2019t have to search for them. And they promptly call attention to themselves with a \u201cthis is where you pay\u201d message. We felt the logos alone were sufficient, so we did not add labels for \u201cCards accepted\u201d, or \u201cPay with\u201d.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-0Hp5j31Uzx2lcG3iqHLSoA.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2374\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-0Hp5j31Uzx2lcG3iqHLSoA.png\" alt=\"1-0Hp5j31Uzx2lcG3iqHLSoA\" width=\"975\" height=\"665\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-0Hp5j31Uzx2lcG3iqHLSoA.png 975w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-0Hp5j31Uzx2lcG3iqHLSoA-600x409.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-0Hp5j31Uzx2lcG3iqHLSoA-768x524.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/a><\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">2. Deciding how much to pay<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">One requirement we had to satisfy was allowing the user to decide how much to pay. For large invoices, a customer may need to make a partial payment (e.g. a deposit), or pay the invoice with multiple payments as the work is completed. By default, the payment amount equals the total unpaid invoice amount. In other words, if a partial payment has been made, the payment amount equals the balance owed.<\/p>\n<blockquote class=\"pageWrap pageWrap--s position-relative marginTopBottom-l breakPointM-marginTopBottom-xl\"><div class=\"blog-quote-before position-absolute bg-marvel\"><\/div><div class=\"tweet-quote blog-quote-after position-absolute bg-marvel cursor-pointer transitionDuration-l transitionProperty-all transitionTimingFunction-cv-easeOutCircular scaleUp--hover zi-weak\"><svg class=\"fill-white opacity-0 pointerEvents-none position-absolute pinCenter transitionProperty-all transitionTimingFunction-easeInOut\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"20\" viewBox=\"0 0 24 20\"><path d=\"M24,2.37a9.64,9.64,0,0,1-2.83.79A5,5,0,0,0,23.34.37a9.72,9.72,0,0,1-3.13,1.23A4.86,4.86,0,0,0,16.62,0a5,5,0,0,0-4.8,6.2A13.87,13.87,0,0,1,1.67.92,5.13,5.13,0,0,0,3.19,7.67,4.81,4.81,0,0,1,1,7a5,5,0,0,0,3.95,5,4.82,4.82,0,0,1-2.22.09,4.94,4.94,0,0,0,4.6,3.51A9.72,9.72,0,0,1,0,17.73,13.69,13.69,0,0,0,7.55,20c9.14,0,14.31-7.92,14-15A10.17,10.17,0,0,0,24,2.37Z\"\/><\/svg><\/div><p class=\"blog-quote position-relative textAlign-center c-marvel\"><span class=\"blog-quote-text transitionDuration-l transitionProperty-all transitionTimingFunction-easeInOut\">With web forms, we know that more inputs lead to lower completion rates, and higher bounce rates.<\/p><\/span><\/blockquote>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">To reduce the number of inputs, we show the payment amount in a read-only format, with a button to edit it, instead of displaying the text input by default. In edit mode, we considered having a Save or Done button, that would flip the input back to read-only. But we felt this was unnecessary, since the amount is already visible inside the input. Also, if the customer wanted to edit the amount again, they could simply change the input value, without having to deal with Edit\/Done buttons.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">We also wanted to confirm the payment amount when the user is ready to submit the form. A confirmation reassures the user of the amount that will be charged to their credit card. We display the payment amount inside the Pay button, at the bottom of the form. This amount updates synchronously with the amount entered in the payment amount input.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Deciding-How-Much-To-Pay.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2410\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Deciding-How-Much-To-Pay.png\" alt=\"Deciding How Much To Pay\" width=\"634\" height=\"590\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Deciding-How-Much-To-Pay.png 634w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Deciding-How-Much-To-Pay-600x558.png 600w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><\/a><\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">3. Name on card<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">The next thing we ask the user to provide is the name of the credit card owner. We considered several options for the label text:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Name of card holder<\/li>\n<li>Card holder name<\/li>\n<li>Name on card<\/li>\n<li>Name (as it appears on your card)<\/li>\n<li>Full name on card<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">We felt that Name on card was the shortest and clearest way to ask for this input. This asks the user to simply type exactly what\u2019s displayed on the card, instead of thinking about the card owner\u2019s full or abbreviated name.<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">4. Card number<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">When reaching the card number input, a common question that a user asks is: \u201cMy card number has spaces. Do I enter my card number with spaces, or without?\u201d To solve for this, we limit the input values to numbers only, so 0\u20139. So if a user types a space, it does not register and it does not affect the number format.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">At first, we wanted to mask the card number when the user leaves the input. This was an attempt to provide the user with a sense of security, similar to how password fields are masked. But we realized that the credit card number is not a \u201csecret\u201d. You can\u2019t do much with just a card number. Furthermore, when a user is ready to submit the form, they may want to double-check their inputs for accuracy. A masked field would break the visual review of the form because the user would have to put the focus back on the card input to reveal its value.<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">5. Card type being used<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">A helpful pattern we noticed in other payment forms is to indicate the card type being used in a visual way. This reassures the user that the card type input matches the card they are holding in their hand. We can determine the card type from the starting first number, as follows:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>3\u200a\u2014\u200aTravel\/entertainment cards (e.g. American Express and Diners Club)<\/li>\n<li>4\u200a\u2014\u200aVisa<\/li>\n<li>5\u200a\u2014\u200aMasterCard<\/li>\n<li>6\u200a\u2014\u200aDiscover Card<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">After the user enters the first two numbers, we display a card logo inside the input field, floated to the right.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Card-Type-Being-Used.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2412\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Card-Type-Being-Used.png\" alt=\"Card Type Being Used\" width=\"309\" height=\"592\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Of course, we could\u2019ve done this differently, based on our designs from question 1:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Dim out the credit card logos at the top of the form. But because the logos are placed away from the number input, the correlation would not be clear.<\/li>\n<li>Place all the credit card logos inside the number input by default, then as the user types in the first two numbers, all the card logos disappears except for the one that corresponds to the input.<\/li>\n<\/ul>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">6. Expiry date<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Most credit cards display their expiry dates in the format MM\/YY (month and year). Some may include the full year, in an YYYY format. When designing the expiry date input, we wanted to keep the user in typing mode to speed their input. The user does not have to reach for a mouse to pick a date and year from a select menu, or navigate the options via up\/down arrows. The user simply has to type in the numbers as they appear on the credit card. This also prevents the user from having to think of the actual month (e.g. 08 is August), so cognitive load is minimized.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Because this input requires a particular format for the date, we included placeholder text inside the input. Note that the placeholder text includes a \u201c\/\u201d, but this is not required to be typed by the user. We limit the input value to numbers only, so if a user does type a forward slash, it is not registered. After the month is entered, the slash is automatically appended.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Expiry-Date.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2413\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Expiry-Date.png\" alt=\"Expiry Date\" width=\"800\" height=\"564\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Expiry-Date.png 800w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Expiry-Date-600x423.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Expiry-Date-768x541.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">7. Security code<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">The card security code was invented to reduce credit card fraud. In other words, it\u2019s meant to make cards more secure. The problem is that this code suffers severely from non-standardized naming. What should we call it? Every card brand has its own naming convention:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>MasterCard\u200a\u2014\u200acard validation code (\u201cCVC2\u201d)<\/li>\n<li>Visa\u200a\u2014\u200acard verification value (\u201cCVV2\u201d)<\/li>\n<li>Discover\u200a\u2014\u200acard identification number (\u201cCID\u201d)<\/li>\n<li>American Express\u200a\u2014\u200a\u201cCID\u201d or \u201cunique card code\u201d<\/li>\n<li>Debit Card\u200a\u2014\u200a\u201cCSC\u201d or \u201ccard security code\u201d<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">And there are even more permutations:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Card verification data<\/li>\n<li>Card verification number<\/li>\n<li>Card verification code<\/li>\n<li>Card code verification<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><span class=\"long-quote\">Nuts, right? Acronyms create confusion. We wanted to stay away from them, but still indicate to the user that this code is all about security. So we decided to name this input \u201cSecurity code\u201d.<\/span><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Next, a security code can be 4 digits (American Express, on the front of the card) or 3 digits (every other brand, on the back of the card). To help the user determine which code they need to enter, and where to find it, we included a visual tooltip. The tooltip has 3 states:<\/p>\n<ol class=\"pageWrap pageWrap--s list list--ordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Dual code: If the user has not yet entered a card number, the tooltip shows both options available.<\/li>\n<li>4-digit code: If the user has entered an American Express card, the tooltip indicates a 4-digit code on the front.<\/li>\n<li>3-digit code: If the user has entered any other card, the tooltip indicates a 3-digit code on the back.<\/li>\n<\/ol>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-xwVm5p5vidUBXwdCanwnrA.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2375\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-xwVm5p5vidUBXwdCanwnrA.png\" alt=\"1-xwVm5p5vidUBXwdCanwnrA\" width=\"990\" height=\"650\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-xwVm5p5vidUBXwdCanwnrA.png 990w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-xwVm5p5vidUBXwdCanwnrA-600x394.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-xwVm5p5vidUBXwdCanwnrA-768x504.png 768w\" sizes=\"auto, (max-width: 990px) 100vw, 990px\" \/><\/a><\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">8. Zip code<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">As an extra security measure, we have to ask customers for the ZIP code associated with their card. There is a trade-off here: adding extra inputs to the form can increase bounce rates, but by adding it, our business is more secure and less prone to fraud.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Zip-Code.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2414\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Zip-Code.png\" alt=\"Zip Code\" width=\"307\" height=\"588\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">We realized that users may enter the ZIP code associated with their personal address, instead of the code associated with their cards. To add clarity, we added a note in a tooltip, which asks for the code from the credit\u2019s card billing address.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">US zip codes contain only numbers, up to a maximum of 10 (ZIP + 4 FTW). In Canada, zip codes contain letters, and spaces too. We restricted the input field to a max character count of 10.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">And because we had to satisfy naming conventions for both US and Canadian customers, the input label reads \u201cZIP\/Postal code\u201d.<\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">9. Is this form and secure?<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">When a user first skims a credit card form, they often ask themselves \u201cIs this form secure? How do I trust the website behind this form? Are they just spoofing my card details?\u201d. There are many ways you can reinforce security through design. Some options we considered included:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Place a lock icon inside the form header, next to \u201cPay Invoice\u201d, but this felt weak and disconnected from the form inputs.<\/li>\n<li>Place a lock icon inside the card number field, but the question became \u201cIs only this input secure, or is the entire form secure?\u201d.<\/li>\n<li>Label the Pay button with text \u201cPay $1.00 securely\u201d, but the text would not fit for large payment amounts.<\/li>\n<li>Add a security badge below the form, but we felt badges distract from a clean aesthetic, and from the overall brand of the page. Also, users can\u2019t tell two badges apart, so we scrapped the idea. Previous A\/B tests also indicated no difference in conversion.<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><span class=\"long-quote\">Given the existing mental model of paying with credit cards online, we felt the presence of one lock icon was sufficient. The design solution was to add a lock icon inside the Pay button. The position of the icon is key, because it reinforces security at the critical point: when you click Pay.<\/span><\/p>\n<div id='gallery-2' class='gallery galleryid-2330 gallery-columns-1 gallery-size-full'><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg.png'><img loading=\"lazy\" decoding=\"async\" width=\"1635\" height=\"735\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg.png\" class=\"attachment-full size-full\" alt=\"\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg.png 1635w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg-600x270.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg-768x345.png 768w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-TrMa4_An7Rh8QuC4v1LbUg-1500x674.png 1500w\" sizes=\"auto, (max-width: 1635px) 100vw, 1635px\" \/><\/a>\n\t\t\t<\/dt><\/dl><br style=\"clear: both\" \/>\n\t\t<\/div>\n\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">10. What happens when I click pay?<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Once the user is ready to pay, they click the Pay button. The button changes state to a pending\/loading state, and the text reads \u201cSending\u2026\u201d. We make a server request, and assuming an error-free state, we display a success message.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Payment-Complete.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2415\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Payment-Complete.png\" alt=\"Payment Complete\" width=\"636\" height=\"593\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Payment-Complete.png 636w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Payment-Complete-600x559.png 600w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/a><\/p>\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">11. Handling card errors<\/h2>\n<blockquote class=\"pageWrap pageWrap--s position-relative marginTopBottom-l breakPointM-marginTopBottom-xl\"><div class=\"blog-quote-before position-absolute bg-marvel\"><\/div><div class=\"tweet-quote blog-quote-after position-absolute bg-marvel cursor-pointer transitionDuration-l transitionProperty-all transitionTimingFunction-cv-easeOutCircular scaleUp--hover zi-weak\"><svg class=\"fill-white opacity-0 pointerEvents-none position-absolute pinCenter transitionProperty-all transitionTimingFunction-easeInOut\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"20\" viewBox=\"0 0 24 20\"><path d=\"M24,2.37a9.64,9.64,0,0,1-2.83.79A5,5,0,0,0,23.34.37a9.72,9.72,0,0,1-3.13,1.23A4.86,4.86,0,0,0,16.62,0a5,5,0,0,0-4.8,6.2A13.87,13.87,0,0,1,1.67.92,5.13,5.13,0,0,0,3.19,7.67,4.81,4.81,0,0,1,1,7a5,5,0,0,0,3.95,5,4.82,4.82,0,0,1-2.22.09,4.94,4.94,0,0,0,4.6,3.51A9.72,9.72,0,0,1,0,17.73,13.69,13.69,0,0,0,7.55,20c9.14,0,14.31-7.92,14-15A10.17,10.17,0,0,0,24,2.37Z\"\/><\/svg><\/div><p class=\"blog-quote position-relative textAlign-center c-marvel\"><span class=\"blog-quote-text transitionDuration-l transitionProperty-all transitionTimingFunction-easeInOut\">One of the most important, and often unloved parts of web form design, is error handling.<\/p><\/span><\/blockquote>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Yes, it can be tedious at times. Yes, there are endless ways to design errors. But when done right, error handling can turn an ambiguous interaction into a clear one.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">There are two general categories of error validation in Internet software: (1) client-side and (2) server-side.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><strong class=\"c-slate lineHeight-l fontSize-l fontWeight-5 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Client-side validation<\/strong><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Client-side errors are caught before a request is sent to to the server. These errors are typically caused by formatting errors in the data, or missing data.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">To make things interesting, you can validate client-side input in different ways. Luckily, Luke Wroblewski wrote a great article explaining the <a class=\"link link--blue fontWeight-4\"href=\"http:\/\/alistapart.com\/article\/inline-validation-in-web-forms\" target=\"_blank\">After, While, and Before and While<\/a> validation methods.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><span class=\"long-quote\">We chose the After method based on Luke\u2019s research, and our gut feelings. The After method displays an error message after the user has indicated that she is done answering a question by moving on to the next one. In other words, validating on \u201cblur\u201d. Also to keep in mind, the user is not \u201clocked\u201d into a field if there is an error. They can tab on their keyboard and move to the next input, and come back later to fix any errors shown.<\/span><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">These were our validation criteria for client-side errors:<\/p>\n<ul class=\"pageWrap pageWrap--s list list--unordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>All inputs, except Name on card and ZIP code, must contain numbers only (i.e. no letters or special characters)<\/li>\n<li>Payment amount: Must be minimum $1<\/li>\n<li>Card number: Length must be 16 numbers (15 for American Express), must begin with one of the four known card codes<\/li>\n<li>Expiry date: Length must be 2 numbers for month, and 2 for the year (i.e. MMYY). Month can only be 01 to 12, year must be minimum 15.<\/li>\n<li>Security code: Length must be 4 numbers if American Express, or 3 numbers for other card brands<\/li>\n<li>ZIP code: Length must be minimum 5 characters, maximum 10 characters<\/li>\n<\/ul>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">To visually indicate an error, we highlight the input field containing the error with red background and red border. We don\u2019t make the input text red. As for the error hint, we display it below the error field, in red text.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Card-Error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2416\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/Card-Error.png\" alt=\"Card Error\" width=\"308\" height=\"602\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Card-Error.png 308w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/Card-Error-307x600.png 307w\" sizes=\"auto, (max-width: 308px) 100vw, 308px\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><strong class=\"c-slate lineHeight-l fontSize-l fontWeight-5 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Server-side validation<\/strong><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Server-side errors are caught after a request is sent to the server. They can be system-specific, or specific to the object being validated. In our form, we had to account for three types of server errors:<\/p>\n<ol class=\"pageWrap pageWrap--s list list--ordered marginBottom-l lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">\n<li>Invalid data, including card number, expiry date, security code, or ZIP code (e.g. expired card, invalid postal code)<\/li>\n<li>System errors, for when there is a problem with the server (e.g. timeouts, lost connection)<\/li>\n<li>Card errors, for when the card being used has been declined by the payment network for some reason (and there are literally hundreds of reasons)<\/li>\n<\/ol>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">In the case of a system error, we leave the fields populated so that a user can retry the payment. When a card is declined (i.e. card error), this is usually a smell for fraud, so we clear the data entered by the user.<\/p>\n<div id='gallery-3' class='gallery galleryid-2330 gallery-columns-1 gallery-size-full'><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg.png'><img loading=\"lazy\" decoding=\"async\" width=\"1585\" height=\"776\" src=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg.png\" class=\"attachment-full size-full\" alt=\"\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg.png 1585w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg-600x294.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg-768x376.png 768w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-DuW2R9I0nXWAfsKD_YUjFg-1500x734.png 1500w\" sizes=\"auto, (max-width: 1585px) 100vw, 1585px\" \/><\/a>\n\t\t\t<\/dt><\/dl><br style=\"clear: both\" \/>\n\t\t<\/div>\n\n<h2 class=\"pageWrap pageWrap--s marginTop-xl marginBottom-l c-black lineHeight-xl fontSize-xl fontWeight-5 breakPointM-lineHeight-xxl breakPointM-fontSize-xxl\" style=\"margin-left: auto; margin-right: auto;\">12. Designing for different screens<\/h2>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">From the start, we knew that we wanted to build one form that could be used on different screen sizes (i.e. responsive), and different screens (i.e. inside the Wave iPhone app).<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><span class=\"long-quote\">By using a singular form object, we only have to make changes to the form in one place. We don\u2019t have to maintain multiple code bases.<\/span><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Inside the Invoice by Wave iPhone app, we initially implemented a native credit card form, that was based on the <a class=\"link link--blue fontWeight-4\"href=\"http:\/\/www.lukew.com\/ff\/entry.asp?1667\" target=\"_blank\">single line input<\/a> design pattern. The input was functional, but slightly buggy. More importantly, we perceived a poor experience with the way this input display labels, and the way a user has to navigate between inputs if there are errors present.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Now, using an HTML iFrame, we inject the new credit card form inside the app. Users have a near identical payment experience when entering their credit card details on a desktop browser, or inside the app. In the future, inside our iPhone app, we will style the form elements using CSS to match the design of other forms inside the app.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><a class=\"link link--blue fontWeight-4\"href=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-SfF6kPKWaD_tddIqjOfD2A.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2378\" src=\"https:\/\/marvel7077.wpengine.com\/wp-content\/uploads\/2016\/08\/1-SfF6kPKWaD_tddIqjOfD2A.png\" alt=\"\" width=\"1220\" height=\"700\" srcset=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-SfF6kPKWaD_tddIqjOfD2A.png 1220w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-SfF6kPKWaD_tddIqjOfD2A-600x344.png 600w, https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/1-SfF6kPKWaD_tddIqjOfD2A-768x441.png 768w\" sizes=\"auto, (max-width: 1220px) 100vw, 1220px\" \/><\/a><\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">And there you have it, the anatomy of a credit card form! We\u2019ve reviewed everything from copy, form input design, error handling, and mobile. Our credit card form will definitely evolve over time, so stay tuned for news. The payments space is not exactly sexy, but learning and understanding the user interactions behind accepting a credit card payment was really fun.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Now, time for a <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/s3.amazonaws.com\/gabe-cc-form\/index.html\" target=\"_blank\">demo<\/a>!<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\">Huge thanks to <a class=\"link link--blue fontWeight-4\"href=\"https:\/\/nickpresta.ca\/\" target=\"_blank\">Nick Presta<\/a>, who engineered the entire form in React (woot!), and the rest of the awesome Payments crew at Wave.<\/p>\n<p class=\"pageWrap pageWrap--s marginBottom-m paddingBottom-s c-slate lineHeight-l fontSize-l fontWeight-3 breakPointM-fontSize-xl breakPointM-lineHeight-xl\"><em>This post was originally published on Gabriel's <a class=\"link link--blue fontWeight-4\"href=\"http:\/\/gabrieltomescu.com\/\" target=\"_blank\">personal blog<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Paying for something online with a credit card is simple, right? Yes and no. Yes, because we\u2019ve been doing it since the early days of the Internet (e.g. Amazon), and no, because no two credit card forms are alike. Over the past 20 years, we\u2019ve built a mental model of paying online: I pull out a credit card from my&#8230; <a class=\"link link--blue fontWeight-4\" href=\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/\">Read More &#65515;<\/a><\/p>\n","protected":false},"author":16,"featured_media":2350,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-2330","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-viewpoint"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v15.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"description\" content=\"Paying for something online with a credit card is simple, right? Yes and no. Gabriel takes us through the process of designing a credit card form at Wave.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Anatomy of a Credit Card Form at Wave - Marvel\" \/>\n<meta property=\"og:description\" content=\"Paying for something online with a credit card is simple, right? Yes and no. Gabriel takes us through the process of designing a credit card form at Wave.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Marvel Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/marvelapp\" \/>\n<meta property=\"article:published_time\" content=\"2016-08-02T11:08:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-08-25T11:33:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/cc-background.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"700\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@marvelapp\" \/>\n<meta name=\"twitter:site\" content=\"@marvelapp\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"12 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\",\"name\":\"Marvel\",\"url\":\"https:\/\/marvelapp.com\/blog\/\",\"sameAs\":[\"https:\/\/www.facebook.com\/marvelapp\",\"https:\/\/www.instagram.com\/marvelapp\/\",\"https:\/\/www.linkedin.com\/company\/marvel-app\/\",\"https:\/\/twitter.com\/marvelapp\"],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#logo\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/marvelapp.com\/wp-content\/uploads\/2018\/06\/Logo-Light.png\",\"width\":1605,\"height\":1130,\"caption\":\"Marvel\"},\"image\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#website\",\"url\":\"https:\/\/marvelapp.com\/blog\/\",\"name\":\"Marvel Blog\",\"description\":\"Ideas and words on user experience, design, collaboration and more\",\"publisher\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/marvelapp.com\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#primaryimage\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/marvelapp.com\/wp-content\/uploads\/2016\/08\/cc-background.jpeg\",\"width\":1400,\"height\":700,\"caption\":\"Anatomy Of A Credit Card Form\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#webpage\",\"url\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/\",\"name\":\"The Anatomy of a Credit Card Form at Wave - Marvel\",\"isPartOf\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#primaryimage\"},\"datePublished\":\"2016-08-02T11:08:27+00:00\",\"dateModified\":\"2016-08-25T11:33:52+00:00\",\"description\":\"Paying for something online with a credit card is simple, right? Yes and no. Gabriel takes us through the process of designing a credit card form at Wave.\",\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#webpage\"},\"author\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#\/schema\/person\/94771d4c842bd2ade61f8bcd2cc2c64e\"},\"headline\":\"The Anatomy of a Credit Card Form\",\"datePublished\":\"2016-08-02T11:08:27+00:00\",\"dateModified\":\"2016-08-25T11:33:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#webpage\"},\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#primaryimage\"},\"articleSection\":\"Viewpoint\",\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/marvelapp.com\/blog\/the-anatomy-of-a-credit-card-form-2\/#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#\/schema\/person\/94771d4c842bd2ade61f8bcd2cc2c64e\",\"name\":\"Gabriel\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/marvelapp.com\/blog\/#personlogo\",\"inLanguage\":\"en-GB\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/44e4aab44351cb6db2f21b1396aa3454299d26f6581f1b0d75009bdcb4353e29?s=96&d=mm&r=g\",\"caption\":\"Gabriel\"},\"description\":\"Exploring Quality in design by bridging humanist values of reason and emotion. Currently building product at Wave. Follow me on Twitter.\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","_links":{"self":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts\/2330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/comments?post=2330"}],"version-history":[{"count":0,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/posts\/2330\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/media\/2350"}],"wp:attachment":[{"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/media?parent=2330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/categories?post=2330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marvelapp.com\/blog\/wp-json\/wp\/v2\/tags?post=2330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}