Skip to content

Getting a first read

How do I send my very first APDU to a payment card?

Find the card, then ask it for its payment directory. Two steps, and the second one is the same on every EMV card on earth.

With a PN532 you first put a card in the field and get hold of it. The frame is D4 4A MaxTg BrTy: the command code 4A for InListPassiveTarget, how many targets you will accept, and which radio flavor to look for. MaxTg should not exceed 0x02, because the chip handles two at once at most, and for a payment card the baud rate byte is almost always 0x00.

BrTyMeaning
0x00106 kbps type A, ISO/IEC 14443 Type A. Start here.
0x01212 kbps, FeliCa polling
0x02424 kbps, FeliCa polling
0x03106 kbps type B, ISO/IEC 14443-3B. Try this if type A finds nothing.
0x04106 kbps Innovision Jewel tag

With a card selected, the first thing to ask any payment card is which applications it offers. That is a SELECT of the Proximity Payment System Environment: an ordinary ISO 7816-4 SELECT whose data field is the ASCII name of the directory.

00CLAA4INS · SELECT04P1by name00P20ELc14 bytes2PAY.SYS.DDF01the directory name, in ASCII00Le
SELECT PPSE, the contactless entry point. The name is literally the ASCII text 2PAY.SYS.DDF01, fourteen bytes, which is why Lc is 0E. On the contact interface the same command carries 1PAY.SYS.DDF01 instead: one character different, and the most useful byte to remember in EMV.

Every one of those bytes comes from ISO/IEC 7816-4 rather than from EMV. A4 is the instruction for SELECT. P1 of 04 means the data field is a name rather than a file identifier. The specification calls it selection by DF name, and says the name may be an application identifier, possibly truncated on the right. P2 of 00 asks for the first or only occurrence and for the file control information to come back. Le of 00 says: return everything the selection produced.

What comes back, and in how many pieces#

Here is where a first attempt usually stalls, because the response may not arrive in one go. A card is allowed to answer a SELECT with two bytes that are not data at all: 61 followed by a count. That is not an error. ISO 7816-4 lists 61 XX under normal processing and says exactly what to do. The process is complete, and before issuing any other command you may send a GET RESPONSE using that count as the expected length.

ReaderCardFind and activate itInListPassiveTargetAsk for the directory00 A4 04 00 0E ...49 bytes are waiting61 31Send them00 C0 00 00 31The directory itself6F 2F ... 90 00Select an application00 A4 04 00 07 ...
The first conversation, complete. The opening step is the chip-level activation from the previous guide; every byte after it is read out of a real contactless capture in this site's corpus. Three APDUs, and only the first is the one everybody talks about. If your code stops at the third step because it read 61 31 as a failure, nothing is wrong with your card or your reader. The card told you the answer was ready and you did not collect it.

GET RESPONSE is the plainest APDU you will ever build. The count the card gave you goes straight into the expected-length byte, and everything else is zero. The class byte must match the one you used for the command it is collecting.

00CLAC0INSGET RESPONSE00P100P231Le49 bytes
The follow-up, built entirely from what the card just said. 0x31 is 49, the count that arrived in the status word. You never choose this number yourself. A card that answers 61 XX and is then asked for a different length has been asked a different question, which is a good way to turn one confusing response into two.

Reading the directory#

What arrives is a nest of BER-TLV templates, not a flat list. The outer one is a file control information template. Inside it are the name you asked for and a proprietary section. Inside that is a block of issuer discretionary data, and inside that one application template for each application the card is willing to offer. The identifiers you want are at the bottom of that nest.

6FFCI template84the name you sentA5proprietary partBF0Cissuer discretionary61one per application4Fthe AID to select50the label to display87priority, 01 first
Four levels deep before you reach anything you can use. Glance at tag 84 on the way past. It echoes the directory name you sent, so a response that echoes something else is answering a question you did not ask. Everything below tag 61 repeats: a card offering two applications sends two of these blocks, one after the other, inside the same discretionary data.

More than one application is normal rather than exotic, and it is the first place a card stops being a single thing in your head. Of the five captures in this site's corpus, two answer the directory query with two application templates each, every one with its own identifier and its own priority indicator. A third answers with a single one. Which one a terminal picks is a decision with consequences, and a later module takes it apart. For now, take the one whose priority indicator is 01 and carry on.

Status words are sentences, not error codes#

The two bytes at the end of every response are the most under-read part of an APDU trace. ISO 7816-4 organizes them into families you can read at a glance. 90 and 61 are normal processing. 62 and 63 are warnings where the command did complete. 64 to 66 are execution errors, and 67 to 6F are checking errors where the card refused before doing anything. The first byte alone tells you which of those happened.

Status wordWhat the specification says
90 00Normal processing, no further qualification. The command did what you asked.
61 XXAlso normal. XX is how many bytes are still available; collect them with GET RESPONSE.
6A 82File or application not found. The card has nothing by the name you sent.
6A 81Function not supported. The card understood and declines to do this at all.
6A 86Incorrect parameters P1-P2. Usually a selection option the card does not implement.
67 00Wrong length, no further indication. Your Lc and your data field disagree.
6E 00Class not supported. Check the first byte of your command before anything else.
6D 00Instruction code not supported or invalid. The card has no such command.

When you get 6A 82#

This is the one you will meet first, and the specification expects it here. The table describing the SELECT command lists 6A 82 among the status words a SELECT may legitimately answer with, alongside a handful of others. It means what it says, file or application not found. The useful move is to work out which of the four things you sent was the one the card could not match.

CheckWhy it produces this exact answer
The interface you are onThe contact and contactless directories have different names. Asking either interface for the other one's directory is a name the card does not have.
The bytes of the nameIt is ASCII with two dots and no terminator. One wrong character is a different name, and the card is not being helpful about which.
Lc against the data fieldFourteen characters means Lc of 0E. A short Lc truncates the name, and a truncated name is a legal request for something else.
The identifier, if selecting oneSelecting an application identifier the card does not carry gives the same answer as a mistyped directory name. Take identifiers from the directory response rather than from memory.

Where to go next#

You now have an application identifier, and the next command is the same SELECT with that identifier in place of the directory name. Same class, same instruction, same P1 and P2, a different length and a different data field. What comes back is the same shape of nest, this time describing the application rather than the directory. It is where a card starts telling you what it will demand of a terminal.

After that the transaction proper begins, and everything before it turns out to have been discovery. If you want to see the whole arc before writing another line of code, open a capture in the workbench. Every one of them starts with the exchange on this page, so you can compare your own card's answers against a worked example rather than reading in the dark.

PracticeA contact transaction, from the first SELECT onwards. Reading a working exchange before you write your own is the fastest way to recognize what your card is telling you.Open in the workbench →

Where to go next

Read nextWhy can't my reader capture a transaction at a real terminal?