When is the Scan Credit Card option available on iOS8 Safari?

So Safari offers Scan Credit Card feature on iOS8 with some credit card forms.

My question is, how does Safari determine when to offer this option?

So far I found that this option is available on Amazon and PayPal, but none of my credit card input forms were able to reproduce this behaviour.

Scan credit card option activation on a form


Solution 1:

After a bit of research with an iOS8 browser and Chrome emulation I figured it out partially. I know of some solutions, but I don't know for sure if there are other ways to do it. You'll have to thank Apple for the amazing lack of documentation around this.

Currently Netflix/Amazon have credit card scanning working properly. So I emulated an iOS8 user agent in my Chrome browser and inspected the markup of their credit card number field. Here's Netflix's:

<input name="cardNumber" smopname="num" id="cardNumber-CC" class="cardNumber" type="text" value="************0891" pattern="[0-9]*">

And here's Amazon's:

<input name="addCreditCardNumber" size="20" maxlength="20">

At that point I played around with a form served over HTTPS that I had control over and started setting attributes to see what would happen. Below, "works" means "successfully triggered card scan" and "doesn't work" means "did not trigger card scan":

  • name="addCreditCardNumber" => works
  • name="cardNumber" => works
  • name="cardnumber" => works
  • class="cardNumber" => does not work
  • type="cardNumber" => does not work
  • id="cardNumber", id="creditCardNumber", id="creditCardMonth", id="creditCardYear" => works

Since the name attribute drives form data and might impact the way server-side form processing works I highly recommend triggering credit card scan by setting your input id to cardNumber.

I would link to the relevant documentation...but hey! There's none (at least, not that I know of)

Solution 2:

I think your better bet is to use HTML5 Autocomplete Types on your inputs.

Stick to the credit card related types, and most modern browsers will auto recognize these fields for you, including Mobile Safari and the "Scan Credit Card" feature. Bonus is that you'll always get the correct keyboard on mobile devices too.

Example (note autocomplete, x-autocompletetype, and pattern attributes):

<input type="text" id="cc-num" autocomplete="cc-number" x-autocompletetype="cc-number" pattern="\d*">

<input type="text" id="cc-name" autocomplete="cc-name" x-autocompletetype="cc-full-name">

I also wrote a related blog post on this topic and built an HTML5 Autocomplete Cheatsheet.

Solution 3:

In addition to Arnaud Brousseau's answer, a search for "card number" in the iOS simulator files yields this file:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/SafariShared.framework/SafariShared

A quick run of strings on it reveals these strings which are certainly used for matching potential fields:

card number
cardnumber
cardnum
ccnum
ccnumber
cc num
creditcardnumber
credit card number
newcreditcardnumber
new credit card
creditcardno
credit card no
card#
card #
cvc2
cvv2
ccv2
security code
card verification
name on credit card
name on card
nameoncard
cardholder
card holder
name des karteninhabers
card type
cardtype
cc type
cctype
payment type
expiration date
expirationdate
expdate

and a bit further:

month
date m
date mo
year
date y
date yr

Can't quite see (with this naïve approach) any references to which attributes (id, name, placeholder...) or other metadata (label maybe?) are actually compared against this list. Also, with the exception of "name des karteninhabers", this is really very english-oriented, that's quite unusual for Apple IMHO.

Solution 4:

Thanks to @barbazoo, the Scan Credit Card option will be available over https with a valid (not self signed) certificate.

Solution 5:

For the expiration fields, based on Arnaud's answer, I found that the expiration fields would be recognized from cardExpirationYear and cardExpirationMonth being in the id attribute.

This worked when the year and month are regular text inputs with the appropriate IDs. The month is populated as a 2-digit number and the year as a 4-digit number.

In a quick test using <select> tags, I found that it also populated the correct month and year.

<input type="text" id="cardNumber" placeholder="CC number">

<select id="cardExpirationMonth">
  <option value="01">01</option>
  <option value="02">02</option>
  ...
  <option value="11">11</option>
  <option value="12">12</option>
</select>

<select id="cardExpirationYear">
  <option value="2014">2014</option>
  <option value="2015">2015</option>
  ...
  <option value="2024">2024</option>
  <option value="2025">2025</option>
</select>

I don't know what other values will work in the option tags.