MTI Parser

easy · iso8583, payments

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

ValueMeaning
0ISO 8583:1987
1ISO 8583:1993
2ISO 8583:2003

Position 1 - Message Class

ValueClass
1Authorization
2Financial
3File Actions
4Reversal/Chargeback
5Reconciliation
6Administrative
7Fee Collection
8Network Management
9Reserved

Position 2 - Function

ValueFunction
0Request
1Request Response
2Advice
3Advice Response
4Notification
5Notification Acknowledgment
6-9Reserved/ISO use

Position 3 - Origin

ValueOrigin
0Acquirer
1Acquirer Repeat
2Issuer
3Issuer Repeat
4Other
5Other 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>

Run tests to see results
No issues detected
    Join Discord