56

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

James Fenwick
  • 2,190
  • 1
  • 20
  • 30
Dávid Kaszás
  • 1,877
  • 1
  • 16
  • 20
  • 1
    Did you serve up your test page over https:// with proper, not self signed certificate? That might help, please let us know. – barbazoo Sep 01 '14 at 02:24
  • I tried it over https but with a self signed certificate. I'll let you know if I manage to test it with a proper cert. – Dávid Kaszás Sep 01 '14 at 11:12

9 Answers9

98

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)

Arnaud Brousseau
  • 1,384
  • 10
  • 12
  • 2
    Thanks. I went for id='cardNumber' which seems to works fine. I was hoping to find documentation in the Safari developer center but there wasn't any mention of this feature that I could find – Simon_Weaver Sep 19 '14 at 02:57
  • Thank you, this fills the cardNumber. But what about the other fields? How do you call the card expire or card owner name fields? – gklka Nov 02 '14 at 14:06
  • 1
    Sorry, but i tried your answer and it does not work. I have build a form with an inputfield like the one you wrote here. I use it within a https page which is not selfsigned. But the scan function does not appear within my iphone... Could you please describe it a bit more? – Niels Jan 09 '15 at 11:02
  • @gklka: See Eric's answer: IDs of "cardExpirationMonth" and "cardExpirationYear" (for expiration month and year, respectively) seem to do the trick. I haven't verified this myself yet. As soon as I do I'll edit my answer. – Arnaud Brousseau Jan 14 '15 at 17:25
  • @Niels can you provide a pastebin of your markup and your testing methodology? Here's a pastebin of a simple form to trigger scan/autofill which should work: http://pastebin.com/EwZGBgG3 – Arnaud Brousseau Jan 14 '15 at 17:26
  • @albemuth – this is a Mobile Safari only feature. It won't work outside of Mobile Safari eg. in a webview. Instead try looking at something like card.io. – jb. Apr 16 '15 at 23:04
  • Here is a test page I created to show how to activate, capture and detect Mobile Safari credit card auto fills: https://mobifyjohn.s3.amazonaws.com/test-ios8-cc/index.html – jb. Apr 16 '15 at 23:05
  • @jb. Your test page works great on iOS 8.1.2, but it doesn't seem to be working on iOS 8.2+. Does anyone know how to make this code work for the more recent releases of iOS 8? – Alexander Apr 23 '15 at 17:56
  • 1
    Just did a bit of playing, it seems in Safari, the `placeholder` also works. The pattern "card number" somewhere in the placeholder seems to trigger the auto-fill as well. – metahamza Jun 02 '15 at 22:19
  • Is this applicable for UIWebView? – Ahd Radwan Sep 15 '15 at 10:20
  • @AhdRadwan: unfortunately, no. This credit card scanning feature is something added to Safari so it's not available in UIWebView as far as I know. I'd love to be able to confirm with a pointer to some documentation, but Apple has done an incredibly poor job documenting this feature. – Arnaud Brousseau Sep 16 '15 at 18:00
  • Is there any way to test this on a local server? – daGUY Nov 06 '15 at 22:42
  • @daGUY: probably, but very hard if you're starting from scratch. Most of the difficulty comes from the need for a real HTTPS domain. I have easy access to this thanks to my corporate network (we have our own DNS servers and cert infrastructure). If you have a small/medium site/infrastructure I'd advise building a standalone, static page served from production restricted to only you, and toy with it from your phone to see if it triggers scanning correctly. – Arnaud Brousseau Nov 10 '15 at 21:23
  • I can confirm that the IDs `#creditCardNumber`, `#creditCardMonth`, and `#creditCardYear` work to trigger the autofill behavior on Safari 9 and iOS 9. As long as you have those IDs and the page is served over HTTPS, it should work. Still no documentation of this that I can find anywhere on Apple's developer site... – daGUY Dec 07 '15 at 20:45
  • @jb. I am trying to do the above and have done it using the fields. But i need to do by clicking a button and triggering the scanner - pls see my question: http://stackoverflow.com/questions/38528494/ios-safari-trigger-scan-credit-card-by-clicking-button – user2906420 Jul 22 '16 at 14:54
  • I am using input name `cc_number` and id `cc_number` also working. why? – huykon225 Jun 06 '19 at 08:45
24

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.

Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104
18

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.

Community
  • 1
  • 1
jcaron
  • 17,302
  • 6
  • 32
  • 46
11

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

Dávid Kaszás
  • 1,877
  • 1
  • 16
  • 20
  • this I'm sure will save people some headaches - but what does it need to have in the HTML to be detected as a credit card field? my credit card field isn't detected as being a credit card field – Simon_Weaver Sep 18 '14 at 06:08
7

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.

Eric
  • 96
  • 1
  • 2
1

It's not about when, it's about how we can enable this feature in Safari browser.

Let's just talk about what happens when a form is submitted:

  1. Some browsers stores all input values with it's name attribute. And it will offer to autocomplete those fields when it encounters same named input elements.

  2. Some browsers scan for just autocomplete attribute for offering auto-completion and,

  3. Some others scan for an attribute like label or name for input elements too.

Now, autocomplete attribute can have a larger set of values including cc-name (Card name), cc-number, cc-exp, cc-csc (Security number - CVV) etc. (full list here)

For example, we could say to a browser that, this is card number field and it should offer autocomplete when possible and it should enable scan credit card feature as:

<label>Credit card number: 
  <input type=text autocomplete="cc-number">
</label>

In general:

<input type="text" autocomplete="[section-](optional) [shipping|billing](optional) 
[home|work|mobile|fax|pager](optional) [autofill field name]">

more detailed ex:

<input type="text" name="foo" id="foo" autocomplete="section-red shipping mobile tel">

And each autocomplete values goes like this:

section-red : wrapping as a section. (named red)
shipping : shopping/billing
mobile   : home|work|mobile|fax|pager (For telephone)
tel      : [Tokens][2]

When we code it like this browser know exactly what kind of value should be populated in that field.

But browser like safari need name or id or label values should also be set right.

Support so far for autocomplete, id and name attributes for auto-completing values.

Browse  Ver OS              ID      Name    Autocomplete
Chrome  50  OS X 10.11.4    No      Yes     Yes
Opera   35  OS X 10.11.4    No      Yes     Yes
Firefox 46  OS X 10.11.4    Yes     Yes     No
Edge    25  Windows 10      No      Yes     No
Safari  9.1 OS X 10.11.4    Partial Partial Partial
Safari  9   iOS  9.3.1      Partial Partial Partial

There are more things at play here. I strongly recommend this blog I referred.

Asim K T
  • 16,864
  • 10
  • 77
  • 99
0

I've found that something like this works, but I consider this a very ugly solution, since it depends on the actual displayed text between the label tags:

<html>
  <head>
    <title>AutoFill test</title>
  </head>
  <body>
    <h1>AutoFill test</h1>
    <h2>revision 4</h2>

    <form action="#">
      <input type="text" name="cardNumber" id="id1"> <label for="id1">Number</label><br>
      <input type="text" name="cardName" id="id2"> <label for="id2">Name on card</label><br>
      <label>Expiration date</label>
      <input type="text" name="expirationMonth" id="id3" maxlength="2">
      <input type="text" name="expirationYear" id="id4" maxlength="2"><br>
      <input type="text" name="csc" id="5"> <label for="id5">CSC</label><br>
    </form>
  </body>
</html>

I am not entirely sure, but I think, that name parameters are not important.

gklka
  • 2,459
  • 1
  • 26
  • 53
  • 1
    Yeah you are on the right track, but the name parameters are important, though there are more right variation. I think the key here is that the form have to be accessed over https with a valid not self signed certificate. – Dávid Kaszás Nov 03 '14 at 08:55
  • HTTPS is important, indeed. But I tried to change `cardName` to `yyy`, and it worked. (Did not try to manipulate the others.) – gklka Nov 03 '14 at 14:49
0

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>
  • Interestingly, it should be noted that the SSL certificate I have on my domain is a 128bit TLS 1.2 and does not have a public audit records. I wonder if between iOS 8.1.2 and iOS 8.1.3 Apple of increased the SSL cert encryption threshold? e.g. to 256bit? – user2528675 Feb 20 '15 at 10:21
  • 1
    Problem resolved. It looks like between iOS 8.1 and 8.1.3 the valid input type for a form field has changed from "number", as I had it before, to "tel" which is what I've changed it to now. With type set to "tel" the scan credit option now appears again. When I change the field type back to number the scan option doesn't appear. – user2528675 Feb 20 '15 at 11:58
0

Even after using the autocomplete and ID methods described above, I had a label at the top of my page with the value Credit / Debit / Gift Card that prevented iOS from offering the Scan CC option. I ended up adding this label above my CC number field to trick iOS into offering the Scan CC option:

<label style="opacity:0.01;color:#FFF;font-size:2pt;">Card Number</label>

Opacity of 0, or a font-size of 1pt prevents iOS from offering the option.

Chewmieser
  • 131
  • 1
  • 7