MTI Parser
MTI Parser
You're building a payment gateway monitoring tool. Every message that flows through needs to be classified: Is this an authorization? A reversal? Who originated it?
The first 4 characters of every ISO8583 message encode this information. Your job is to extract it.
The Structure
An MTI like 0110 breaks down as:
Position: 0 1 2 3
Digit: 0 1 1 0
Meaning: │ │ │ └─ Origin (0=acquirer, 1=acquirer-repeat, 2=issuer, ...)
│ │ └─ Function (0=request, 1=response, 2=advice, ...)
│ └─ Class (1=auth, 2=financial, 4=reversal, 8=network)
└─ Version (0=1987, 1=1993, 2=2003)
Each position has specific valid values:
Position 0 - Version
| Value | Meaning |
|---|---|
| 0 | ISO 8583:1987 |
| 1 | ISO 8583:1993 |
| 2 | ISO 8583:2003 |
Position 1 - Message Class
| Value | Class |
|---|---|
| 1 | Authorization |
| 2 | Financial |
| 3 | File Actions |
| 4 | Reversal/Chargeback |
| 5 | Reconciliation |
| 6 | Administrative |
| 7 | Fee Collection |
| 8 | Network Management |
| 9 | Reserved |
Position 2 - Function
| Value | Function |
|---|---|
| 0 | Request |
| 1 | Request Response |
| 2 | Advice |
| 3 | Advice Response |
| 4 | Notification |
| 5 | Notification Acknowledgment |
| 6-9 | Reserved/ISO use |
Position 3 - Origin
| Value | Origin |
|---|---|
| 0 | Acquirer |
| 1 | Acquirer Repeat |
| 2 | Issuer |
| 3 | Issuer Repeat |
| 4 | Other |
| 5 | Other Repeat |
What You're Building
type MTI struct {
Version int // 0, 1, or 2
Class int // 1-9
Function int // 0-9
Origin int // 0-5
}
func ParseMTI(s string) (MTI, error)
Behavior
- Input: A string like "0100" or "0110"
- If the string isn't exactly 4 characters, return an error
- If any character isn't a digit, return an error
- Otherwise, extract each position into the struct
- You do NOT need to validate that the values are semantically correct (e.g., class=0 is technically invalid but your parser should still accept it)
Examples
ParseMTI("0100") // → MTI{Version: 0, Class: 1, Function: 0, Origin: 0}, nil
ParseMTI("0110") // → MTI{Version: 0, Class: 1, Function: 1, Origin: 0}, nil
ParseMTI("2400") // → MTI{Version: 2, Class: 4, Function: 0, Origin: 0}, nil
ParseMTI("0800") // → MTI{Version: 0, Class: 8, Function: 0, Origin: 0}, nil
ParseMTI("010") // → MTI{}, error (too short)
ParseMTI("01001") // → MTI{}, error (too long)
ParseMTI("010A") // → MTI{}, error (non-digit)
ParseMTI("") // → MTI{}, error (empty)
Why This Matters
When you're debugging a failed transaction at 3 AM, the MTI tells you immediately what kind of message you're looking at. 0100 → someone tried to authorize. 0110 → the network responded. 0400 → someone's trying to reverse. This is the first thing you check.
The ability to quickly parse and understand an MTI is fundamental to every ISO8583 task you'll encounter.
Hints (only if stuck)
<details> <summary>Hint 1: Validating length</summary> Go strings are UTF-8, but MTIs are always ASCII digits. For ASCII, len(s) gives you the character count. </details>
<details> <summary>Hint 2: Checking for digits</summary> A character is a digit if it's between '0' and '9' inclusive. You can check this with: c >= '0' && c <= '9' </details>
<details> <summary>Hint 3: Converting to int</summary> The simplest approach: s[0] - '0' gives you the numeric value of the first character. This works because ASCII digits are contiguous ('0'=48, '1'=49, ..., '9'=57). </details>