How to Read EMV Tag 9F02 — Authorized Amount (n6 BCD) Explained

If you’ve ever debugged an EMV transaction and seen 9F0206000000011934 in a TLV stream, you’ve encountered Tag 9F02 — the Amount, Authorized. This 6-byte value encodes the transaction amount in a format called BCD (Binary-Coded Decimal) with a length specifier of n6. Understanding how to read it is fundamental to EMV transaction analysis, payment terminal development, and card simulation.

Try it now: Use our Hex Converter to paste a 9F02 hex value and see the decimal equivalent. Or look up any EMV tag in our EMV Tag Lookup tool.

1. What Is Tag 9F02?

EMV Tag 9F02 is defined in EMV Book 3 (Application Specification) as:

FieldValue
Tag9F02
NameAmount, Authorized
Formatn6 (numeric, 6 bytes)
EncodingBCD (Binary-Coded Decimal)
Length06 bytes (12 nibbles / 12 decimal digits)
SourceTerminal → Card (in CDOL1 / CDOL2)
Used inGENERATE AC command, cryptogram computation
MandatoryYes — always present in CDOL1

The terminal sends this value to the card during the GENERATE AC command as part of CDOL1 (Card Risk Management Data Object List 1). The card uses it when computing the ARQC (Authorization Request Cryptogram) or TC (Transaction Certificate), binding the transaction amount into the cryptographic proof.

2. BCD Encoding — How n6 Works

BCD (Binary-Coded Decimal) encodes each decimal digit (0-9) into exactly one nibble (4 bits). Since a byte has 2 nibbles, each byte holds 2 decimal digits. For n6 (6 bytes), you get 12 decimal digits:

Amount: $119.34

Decimal representation:  0  0  0  0  0  0  0  1  1  9  3  4
                         |  |  |  |  |  |  |  |  |  |  |  |
Hex bytes:              00 00 00 01 19 34

Tag 9F02 encoded as:  9F 02 06 00 00 00 01 19 34
                      --- -- -- ---------------
                      Tag Len      6 bytes BCD
Key insight: The amount is always a 12-digit decimal number where the last 2 digits are the minor unit (cents, pence, fen, etc.). So 000000011934 = 11934 minor units = $119.34 (if USD with 2 decimal places).

BCD Nibble Map (byte by byte)

ByteHexHigh NibbleLow NibbleDigit Position
10000d1 d2
20000d3 d4
30000d5 d6
40101d7 d8
51919d9 d10
63434d11 d12

The 12 digits represent: d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 = 000000011934

3. Currency and the Minor Unit

Tag 9F02 alone doesn’t tell you the currency. The terminal also sends Tag 9F42 (Currency Code) and the card references Tag 9F44 (Currency Exponent) to determine how many digits are the minor unit (decimal places).

Currency Code (9F42)CurrencyMinor Unit (exponent)9F02 = 000000011934 means
0840USD2$119.34
0978EUR2€119.34
0826GBP2£119.34
0156CNY2¥119.34
0392JPY0¥11934 (no decimals)
0364IRR011934 rial (no decimals)
0336BHD311.934 BHD (3 decimal places)
Rule: The minor unit exponent determines how many of the rightmost digits are the fractional part. Exponent 2 = last 2 digits are cents. Exponent 0 = the full 12 digits are the integer amount. Exponent 3 (Bahrain, Kuwait, Iraq) = last 3 digits are the fractional part.

4. Parsing 9F02 in Python

# Parse EMV Tag 9F02 from BCD to decimal amount
def parse_9f02(hex_bcd: str, minor_unit: int = 2) -> float:
    """
    Parse EMV Tag 9F02 (Amount, Authorized) from BCD hex string.

    Args:
        hex_bcd: 12-character hex string (e.g. '000000011934')
        minor_unit: number of decimal places (from 9F44 or currency code table)

    Returns:
        Float amount (e.g. 119.34)

    Example:
        >>> parse_9f02('000000011934', minor_unit=2)
        119.34
        >>> parse_9f02('000000011934', minor_unit=0)  # JPY
        11934.0
    """
    # BCD: each hex digit IS a decimal digit
    # Just read the hex string as a decimal number
    raw_value = int(hex_bcd)
    return raw_value / (10 ** minor_unit)


# Full example: extract 9F02 from a TLV stream
def extract_amount_from_tlv(tlv_hex: str, minor_unit: int = 2) -> float:
    """Find and parse 9F02 from an EMV TLV data string."""
    tag = '9F02'
    pos = tlv_hex.upper().find(tag)
    if pos == -1:
        raise ValueError('9F02 not found in TLV data')

    # Skip tag (4 chars) + read length (2 chars)
    len_pos = pos + 4
    length = int(tlv_hex[len_pos:len_pos+2], 16)

    # Read value
    val_pos = len_pos + 2
    value_hex = tlv_hex[val_pos:val_pos + (length * 2)]

    return parse_9f02(value_hex, minor_unit)


# Usage
tlv_data = '9F02060000000119349F420208409F440102'
amount = extract_amount_from_tlv(tlv_data, minor_unit=2)
print(f'Authorized amount: ${amount:.2f}')  # $119.34

5. Parsing 9F02 in JavaScript

/**
 * Parse EMV Tag 9F02 (Amount, Authorized) from BCD hex string.
 * @param {string} hexBcd - 12-char BCD hex (e.g. '000000011934')
 * @param {number} minorUnit - decimal places (2 for USD/EUR, 0 for JPY)
 * @returns {number} The amount as a float
 */
function parse9F02(hexBcd, minorUnit = 2) {
    // BCD digits are directly the hex characters as decimal
    const rawValue = parseInt(hexBcd, 10); // parse as base-10
    return rawValue / Math.pow(10, minorUnit);
}

// Example
const hex9f02 = '000000011934';
const amount = parse9F02(hex9f02, 2);
console.log(`$${amount.toFixed(2)}`); // $119.34

// For JPY (no minor units)
const jpyAmount = parse9F02(hex9f02, 0);
console.log(`\u00a5${jpyAmount}`); // \u00a511934

// For BHD (3 minor units)
const bhdAmount = parse9F02('000000011934', 3);
console.log(`${bhdAmount} BHD`); // 11.934 BHD
Why parseInt(hex, 10)? Because BCD digits 0-9 are identical in hex and decimal representation. The hex string 000000011934 contains only digits 0-9 (no A-F), so reading it as base-10 gives the correct decimal value directly. This is the beauty of BCD — no base conversion needed.

6. Where 9F02 Appears in EMV Transactions

Tag 9F02 flows through the EMV transaction in these key locations:

LocationCommand/FieldDescription
CDOL1GENERATE AC (first)Terminal sends 9F02 to card for ARQC/TC/AAC generation
CDOL2GENERATE AC (second)Present in second GENERATE AC if issuer auth performed
Tag 9F10Issuer Application DataNot 9F02 itself, but the card may echo the amount in IAD
CVR (within 9F10)Card Verification ResultsCard may indicate if amount exceeded floor limit
Tag 9F03Amount, OtherCompanion tag for cashback amount (000000000000 if none)

Full GENERATE AC CDOL1 Example

// CDOL1 data sent in GENERATE AC:
9F0206000000011934     // Amount, Authorized: $119.34
9F0306000000000000     // Amount, Other: $0.00 (no cashback)
9F1A020840             // Terminal Country Code: USA
9500020000             // TVR: all zeros (no terminal risk issues)
5F2A020840             // Transaction Currency Code: USD
9A03260805             // Transaction Date: 2026-08-05
9C0100                 // Transaction Type: 00 (purchase)
9F370412345678         // Unpredictable Number: 0x12345678
82                     // AIP: 0x820

7. Common Mistakes and Pitfalls

Mistake 1: Treating 9F02 as regular hex. If you do parseInt('000000011934', 16), you get 4532 — completely wrong. The BCD digits are decimal digits expressed in hex nibbles. Always parse as base-10.
Mistake 2: Ignoring the minor unit. If the currency is JPY (exponent 0), 000000011934 means 11,934 yen, not $119.34. Always check Tag 9F42 (Currency Code) and 9F44 (Currency Exponent) to determine how many digits are fractional.
Mistake 3: Negative amounts. BCD in EMV does not support negative values. Refund transactions use Tag 9C (Transaction Type) = 20 (refund) with a positive 9F02 amount, not a negative amount.
Mistake 4: Length mismatch. Sometimes test tools send 9F02 with fewer than 6 bytes. The EMV spec requires exactly 06 bytes. If you see 9F0204, the data is malformed — pad with leading zeros to 12 digits.

Self-Check: Decode These

Hex BCD (9F02)CurrencyMinor UnitAnswer
000000000500USD2$5.00
000100000000USD2$10,000.00
000000012345JPY0¥12,345
000000123450BHD3123.450 BHD
000000999999EUR2€9,999.99

8. Maximum Amount and Edge Cases

With 12 decimal digits, the maximum n6 value is 999999999999 (12 nines). With a minor unit of 2, that’s $9,999,999,999.99 — nearly $10 billion, which exceeds any practical transaction amount. For currencies with exponent 0 (JPY, KRW), the max is 999,999,999,999 units.

Edge Case9F02 ValueMeaning
Zero amount000000000000$0.00 — used in balance inquiry, pre-auth
Maximum999999999999Max representable (unlikely real transaction)
Cashback9F02 = purchase, 9F03 = cashbackTotal = 9F02 + 9F03
Refund9C = 20, 9F02 = refund amountPositive BCD amount with type=refund

9. Related EMV Tags

TagNameFormatRelation to 9F02
9F03Amount, Othern6 BCDCashback amount; 000000000000 if none
9F42Currency Coden3 (hex)ISO 4217 numeric code (0840=USD, 0978=EUR, ...)
9F44Currency Exponentn1Minor unit (decimal places) for 9F02
9CTransaction Typen100=purchase, 20=refund, 01=cash advance
9F01ATCn2Application Transaction Counter — pairs with amount in ARQC
9F37Unpredictable Numberb4Fresh nonce for each GENERATE AC — with 9F02 in CDOL1

10. Quick Reference

Tag: 9F02  |  Name: Amount, Authorized  |  Format: n6 (6 bytes, BCD)  |  Length: always 06
Encoding: Each byte = 2 BCD digits (0-9)  |  Parse as: parseInt(hexStr, 10) / 10^exponent
Range: 000000000000 to 999999999999  |  Sent by: Terminal → Card in CDOL1/CDOL2
Used in: GENERATE AC, ARQC/ARPC/TC/AAC computation  |  Mandatory: Yes