# Decoding an ISO 8583 Payload

> **Goal:** Understand the fixed‑position pieces that make up the ASCII string we receive in `ISOFullMessage`, so you can split it by eye or with any language / tool.

***

## 1. High‑level Structure

```
┌──────────────────────────────────────────────────────────────┐
│ Transport / Host header        (variable, host‑specific)     │
│ ──────────────────────────────────────────────────────────── │
│ MTI           4  n                                            │
│ Primary bitmap 16  n  (64 bits → 16 hex characters)          │
│ Secondary bitmap 16  n  (present only if bit 1 = 1)          │
│ Data elements  …   (1‑128, in ascending order)               │
└──────────────────────────────────────────────────────────────┘
```

* **All characters are ASCII.**
* Numeric fields (`n`) are right‑justified, **zero‑padded**.
* Alphanumeric fields (`ans`) are left‑justified, **space‑padded**.
* Variable‑length fields begin with a numeric **length prefix**:
  * `LLVAR` → 2 digits (00‑99)
  * `LLLVAR` → 3 digits (000‑999)

***

## 2. Example in the Wild

Below is the **authorization** message you saw (line‑wrapped & spaced):

```
ISO0260000700 | 0120 | B23AC4112EE1801C
0000000214000100 | 0000000000000000 | 0285
0724181349 | 863303 | 141300 | 0724 | 0724
554105 | 2C0000000006 | 12345621543464******6993=0000427704382626
185503 | 0000010003        | 127298000000000
EXXON UPPY'S #68 #2009CENTREVILLE  VA US
0100724141353840 | 0160000000
… (continues)
```

### What those chunks are

| Segment            | Meaning                                                                                                                                   | Why the spacing?                                                                                                    |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `ISO0260000700`    | **Transport header** – prepended by the host to carry length, protocol version, routing info. Its size (12–20 bytes) is *vendor‑defined*. | Not part of ISO 8583 proper. Discard before parsing.                                                                |
| `0120`             | **MTI** – `0 120` = Authorization Advice.                                                                                                 | Always 4 numeric chars.                                                                                             |
| `B23AC4112EE1801C` | **Primary bitmap** (16 hex chars = 64 bits). Bit 1 is set (`B = 1011`), so a secondary bitmap follows.                                    | Every 4 bits are packed into one hex char—no delimiter.                                                             |
| `0000000214000100` | **Secondary bitmap** (also 16 hex).                                                                                                       | Present only because bit 1 in the primary bitmap = 1.                                                               |
| Remaining blocks   | **Data elements** in ascending order (2, 3, 4, … ). Each occupies exactly its specified length, *or* `LL/LLL` prefix + value.             | Padding (zeros / spaces) makes every fixed field keep its place so downstream systems can slice without delimiters. |

***

## 3. Bitmap → Which Fields Follow?

1. Convert each hex char to binary. *Example:* `B23A…` → `1011 0010 0011 1010 …`
2. Number bits **1‑64** (or 1‑128).
3. If a bit = 1, its corresponding field *immediately follows* the bitmap(s).
4. Move through the message **in ascending field order**, reading:

| Field #                        | Format    | Length   | Notes                                          |
| ------------------------------ | --------- | -------- | ---------------------------------------------- |
| **2 – PAN**                    | `LLVAR n` | up to 19 | `LL` tells you how many digits follow.         |
| **3 – Processing code**        | `n`       | 6        | Always `000000` for POS sale in our messages.  |
| **4 – Amount, Txn**            | `n`       | 12       | Right‑padded zeros: `00000000285` = $2.85      |
| **11 – STAN**                  | `n`       | 6        | `185503` in the sample.                        |
| **37 – Retrieval Ref # (RRN)** | `an`      | 12       | `724181349863` – used to link auth ↔ purchase. |
| **41 – Terminal ID**           | `ans`     | 8        | `00010003` (space‑padded if shorter).          |
| **…**                          |           |          |                                                |

*(The complete ISO 8583 spec defines > 120 fields. Only the ones lit by the bitmap are present.)*

***

## 4. Reading Variable‑length Fields

```
PAN (Field 2)  =  16  543464******6993
                 ──┘ └─────────────────
                 length indicator  (2 chars)
```

* If the bitmap says Field 2 exists, **take the next 2 chars**, convert to an int (`16`), then read *exactly* that many chars for the PAN.
* Immediately after that, continue with the next field (Field 3).

***

## 5. Padding Rules Cheat‑Sheet

| Format                                | Justify   | Pad with                              | Example                                          |
| ------------------------------------- | --------- | ------------------------------------- | ------------------------------------------------ |
| `n` (numeric)                         | **right** | `0`                                   | `00000000285`                                    |
| `an`, `ans` (alpha / alnum / special) | **left**  | space (`0x20`)                        | `00010003··` → becomes `00010003 <space><space>` |
| Track / discretionary                 | fixed     | `F` or `=` etc. as per card standards | `543464******6993=...`                           |

> *Tip:* When debugging, replace `0x20` with `·` so you can *see* trailing spaces.

***

## 6. Putting It All Together (Walk‑through)

1. **Strip transport header** (`ISO0260000700`).
2. **Read MTI** (`0120`).
3. **Read Primary bitmap** (16 hex).
4. Because bit 1 = 1, read **Secondary bitmap** (another 16 hex).
5. **Iterate fields**:
   * bit 2 = 1 → Field 2 (LLVAR) → read length *LL* → read PAN.
   * bit 3 = 1 → Field 3 (6 n) → read 6 chars.
   * … continue until all `1` bits are consumed.
6. You should land **exactly on the last byte** of the message. Extras mean parsing error.

***

## 7. Where the Retrieval Reference Number Hides

* Field 37 (RRN) always shows up **after** Field 35/36 (Track2/Track3) for our host.
* Because we *never* carry field 70+ in auth/purchase, the RRN is usually < halfway down the message.
* Example auth vs. purchase pair:

```
Auth  – … 185503 | **724181349863** | 0000010003 …
Purchase – … 583719 | **724181349863** | 895229592889 …
```

**Same RRN → same transaction lifecycle**.

***

## 8. Appendix – Field Directory (Common in Our Webhooks)

| Field | Length         | Format | Meaning                          |
| ----- | -------------- | ------ | -------------------------------- |
| 2     | LLVAR (≤ 19)   | n      | Primary account number (PAN)     |
| 3     | 6              | n      | Processing code                  |
| 4     | 12             | n      | Amount, transaction              |
| 11    | 6              | n      | System trace audit number (STAN) |
| 12    | 6              | n      | Local Txn time (hhmmss)          |
| 13    | 4              | n      | Local Txn date (MMDD)            |
| 37    | 12             | an     | Retrieval reference number (RRN) |
| 41    | 8              | ans    | Terminal ID                      |
| 42    | 15             | ans    | Merchant ID (sometimes blank)    |
| 43    | 40             | ans    | Card acceptor name / location    |
| 55    | LLLVAR (≤ 999) | b      | EMV data (if e‑com / chip)       |

*(Fields differ per processor; consult the host spec if something new appears.)*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apidocs.juicefin.com/apis/transactions/decoding-an-iso-8583-payload.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
