9F10 up in any EMV tag directory and you get one line: Issuer Application Data โ proprietary. Technically true, and no help at all when a dispute hinges on the fourteen bytes sitting in your DE55 dump. In practice most IADs follow one of a handful of scheme layouts, and buried inside every one of them is the CVR โ Card Verification Results: the card's own record of what it checked, the card-side counterpart of the TVR.
EMV Book 3 spends exactly one definition on tag 9F10: data proprietary to the issuer application, up to 32 bytes. It rides in DE55 next to the cryptogram, and unlike the TVR or the TSI it is not written for the terminal at all. The IAD is a note from the card to its own issuer, and everyone in between โ terminal, acquirer, scheme โ is expected to forward it unread.
That note exists because the issuer's host cannot verify an ARQC blind. To check the cryptogram and judge the transaction, it needs to know which master key this card's keys were derived from (the DKI or KDI โ key derivation index), which recipe the card used to compute the cryptogram (the CVN โ cryptogram version number), and what the card itself verified along the way (the CVR). Those three things, plus whatever else the issuer chose to pack in, are the IAD.
Here is the part every one-line reference skips, and the reason it matters: the internal structure of the IAD changes with the CVN it carries, and issuers are free to define their own layout entirely. The byte maps below are how the common implementations read โ Visa's VIS and Mastercard's M/Chip, plus the issuer's personalisation choices on top. Wherever a value is going to drive a decision, the specification from your counterpart โ the issuer or the scheme โ is the authority, not this page and not any generic table. That is not a disclaimer; it is what the field is. Applying one table to every card produces answers that look precise and are wrong.
What a tool can do honestly is split the bytes and say which layout the shape suggests. Our IAD decoder uses two openly-stated heuristics: a leading byte of 06 reads as Visa format 0/1/3, and a total length of 18, 20 or 26 bytes reads as a Mastercard M/Chip candidate. Anything else gets a plain per-byte grid, which for a fully custom profile is the only truthful decode.
The common Visa layout is length-prefixed: the field opens with 06, announcing six bytes of Visa discretionary data, and may carry a second length-prefixed block of issuer discretionary data behind it.
| Position | Content | Meaning |
|---|---|---|
Byte 1 | 06 | Length indicator: 6 bytes of Visa discretionary data follow |
Byte 2 | DKI | Derivation Key Index โ which issuer master key derived this card's keys |
Byte 3 | CVN | Cryptogram Version Number โ the recipe behind the cryptogram, and the key to reading the CVR |
Bytes 4โ7 | CVR | Card Verification Results, 4 bytes; its own first byte 03 is the CVR length |
Byte 8 | length | Length indicator for issuer discretionary data, when present |
Bytes 9+ | IDD | Issuer discretionary data โ meaning set by the issuer's personalisation profile |
Take the seven-byte value 06101203A40000 and paste it into the IAD decoder: length indicator 06, DKI 0x10, CVN 18 (0x12), and the CVR 03A40000. A longer sibling like 06101203A4000011223344 decodes the same up to byte 7, then byte 8 (0x11) is read as the second length indicator and 223344 as issuer discretionary data. UnionPay cards follow a Visa-like structure, so this cut is the right first guess for them too.
M/Chip drops the length prefix and goes straight in โ which is why the decoder has to fall back on total length (18, 20 or 26 bytes) to spot it:
| Position | Content | Meaning |
|---|---|---|
Byte 1 | KDI | Key Derivation Index |
Byte 2 | CVN | Cryptogram Version Number |
Bytes 3โ8 | CVR | Card Verification Results, 6 bytes |
Bytes 9+ | โ | DAC / ICC dynamic number / plaintext counters โ depends on M/Chip version and personalisation |
Run the 18-byte value 0110A50003220000000000000000000000FF through the decoder: KDI 0x01, CVN 16 (0x10), a 6-byte CVR of A50003220000, and the tail read as DAC, ICC dynamic number or plaintext counters depending on the M/Chip version. Note the byte offsets: the CVR starts one byte earlier than in the Visa cut and runs two bytes longer.
Those offsets are the whole game, and the classic misread is applying the Visa table to a non-Visa card. The figure below takes one 18-byte hex string โ 06101203A400000A112233445566778899AA โ and cuts it both ways:
Feed that value to the decoder and it shows the Visa cut, because both heuristics match and the leading 06 wins โ and it flags the split as a guess, because that is what it is. The deciding fact lives outside the field: check the AID first, then pick the table. If the AID and the IAD shape disagree, trust neither until you know why.
The cargo worth all this trouble is the CVR, Card Verification Results. The TVR records what the terminal observed during the transaction; the CVR records what the card decided โ whether the last transaction completed online, how offline PIN verification went and how many tries remain, whether issuer authentication passed, how many issuer script commands ran. When the terminal log and the issuer's story disagree, the TVR is your side of the case file and the CVR is theirs. "What did the card think was happening?" has exactly one answer, and it lives in 9F10.
What neither this article nor the decoder will give you is a universal CVR bit table โ because the bit layout is selected by the CVN sitting right next to it. A VIS CVN 10 CVR and a CVN 18 CVR assign different meanings to the same positions, and M/Chip's 6-byte CVR is a different animal again. Decode with the wrong table and you get confident nonsense: bits that read as "PIN try limit exceeded" on a card that never saw a PIN. Read the CVN first, then pull the matching table from the scheme spec or the issuer's personalisation profile โ the one your counterpart actually implements.
The IAD earns its keep in issuer-side disputes. A decline that looks inexplicable from the terminal often carries its explanation here: offline PIN already failed before the online attempt, issuer authentication failed on the previous transaction, a script counter that never moved. Three habits make it useful: