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?<
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.
This is now all broken after upgrading to iOS 8.1.3 this morning. When on iOS 8.1.2 all of the above worked just fine - now the keyboard option to scan credit card simply does not appear. Here's my code, which did work yesterday on iOS 8.1.2 and does not work today on iOS 8.1.3:
<html>
<head>
<title>Scan credit card using iOS 8</title>
<style type="text/css">
input {height:1.5em;width:95%}
input[type="number"] {font-size: 2.5em}
body {background-color:lightgray;font-size: 3em;font-family: sans-serif;}
#purchase {font-size: 2em;font-weight: bold;height:1.2em}
</style>
</head>
<body>
<form action="https://yoursite.com/credit-card-purchase" method="POST">
Credit Card Number 1<br />
<input type="number" autocomplete="cc-number" name="cardNumber" id="cardNumber" value="" placeholder="*** **** *** ****" />
<br />
Expiry month <br />
<input type="number" name="expirationMonth" id="cardExpirationMonth" />
<br />
Expiry year <br />
<input type="number" name="expirationYear" id="cardExpirationYear" />
<br />
<br />
<input type="submit" value="Purchase" id="purchase">
</form>
</head>
</html>
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.