While various Android HCE (Host Card Emulation) examples have been popping up, until now there has been no simple examples that could be easily tested with live payment terminals. SwipeYours fills this space.
SwipeYours is a small, self contained app from which your card data never leaves the phone except to make NFC payments. It uses the Visa-MSD (Magnetic Stripe Data) protocol to make tap payments. While Visa-MSD is now deprecated, it is supported by most NFC payment terminals in North America and this is unlikely to change in the near future. In Austin, TX we’ve successfully used SwipeYours at all of the following:
- CVS drugstore
- Jack in the Box
- Taco Bell
- Jamba Juice
- Valero Gas Stations
What you need to use SwipeYours:
- A magnetic stripe reader to pull your card data. These can be purchased cheaply on both Amazon and Ebay in the US.
- An NFC phone running Android 4.4+ (KitKat or above).
- A non-chipped Visa credit or debit card. If the card already has a smart chip for native tap payments, the authorization processor is most likely expecting a different variation of Visa MSD than what we can provide.
- An issuing bank (or its outsourced processor) that does not check the delivery method: swipe, dip or tap.The processor has access to the delivery method of the card data and can reject a tap transaction if it wants to. All tested prepaid Visa cards have not had this issue and most major banks like Chase work fine. Capital One cards and the processor for some small credit unions, unfortunately, do have this issue.
Small Print Disclaimer:
SimplyTapp does not encourage the storage of payment credentials on your phone and provides secure cloud based solutions. I have provided the source code and Google play download via my personal Github and Google accounts respectively. Adding your own magnetic stripe data to SwipeYours may work, but it is not a supported payment method by Visa or your issuing bank.
Visa-MSD Payment example:
Applications implementing HCE send and receive data with a POS (Point Of Sale) terminal using a byte array abstraction called an APDU (Application Protocol Data Unit).
The MainActivity of SwipeYours logs these APDU exchanges to the screen so developers can better understand how the process works. Below I’ll show the data from a typical Visa-MSD transaction performed by SwipeYours. If you want to better understand the values in the hex strings below, the source code to the SwipeYours PaymentService has lots of detailed comments.
PaymentService Received PPSE select: 00A404000E325041592E5359532E444446303100
Here the POS sent our app a PPSE (Proximity Payment Service Environment) select. This is the first APDU sent in any payment transaction. It asks the payment device to send a list of supported payment types.
With HCE, there is no requirement to use JavaCard applets. The PaymentService entry in our Android manifest specifies a list of AID values that should be directed to our service.
Our PPSE response contains a single AID value letting the POS know that we only support Visa credit and debit transactions.
PaymentService Received Visa-MSD select: 00A4040007A000000003101000
Now the POS selects the only payment AID that we offered above.
SwipeYours sends Visa-MSD select response. For trivia sake, the second value in red above is the ASCII string VISA CREDIT represented in hexadecimal.
PaymentService Received GPO: 80A80000048302800000
POS sends the Get Processing Options (GPO) command.
Payment devices supporting Visa transactions can support different payment protocols (Visa uses the term "path" instead of protocol). Our response lets the POS terminal know that we only support Visa-MSD. Our GPO response above lets the POS know that we only support Visa -MSD.
PaymentService Received READ REC: 00B2010C00
POS sends Read Record command. It's a short command requesting the payment data.
Here SwipeYours sends your credit card data to the terminal in the read record response. The format of the data is known as track 2 equivalent data. Its a fairly straight forward transformation of the track 2 portion of the card's magstripe data. You replace the '=' with a valid hex digit 'D' and you add a single 'F' to the end if needed to create an even number of hex digits. The extra 'F' digit was necessary in this example, because each hex value is 4 bits of binary data and we need an even number of hex digits to convert to a whole number of 8-bit bytes.
Here is the track 2 data that was used to create the APDU above:
The track 2 syntax is:
- Card number
- Expiration date: YYMM
- Service code
- Issuer dependent discretionary data
How to decipher the service code, XXX:
- Values 1 or 2 in the first digit mean the card can be used internationally. Values 6 or 7 say the card is restricted to the issuer's country or some group of countries. 2 and 7 indicate that the card has a built in chip for tap payments and the magstripe data on these cards will probably not work with SwipeYours.
- The middle digit specifies who provides authorization processing. Value 0 means normal, 2 is by the issuer or their processor, and 4 is the issuer unless a bilateral agreement applies.
- The last digit specifies allowed services and pin requirements. Values 0, 1 and 6 mean that there are are no restrictions. Values 2, 5 and 7 are restricted to goods and services (i.e. no cash). 3 is ATM only. 4 is cash only /// Values 1, 2 and 4 indicate that no pin is required. Values 0, 3 and 5 indicate that a pin is required. 6 and 7 say the pin is required when a pin input device is present.