ISO-8583: Understanding Message Type Indicator

ASSI Avatar

Hey there! If you’ve ever worked with payment systems, especially in the realm of financial transactions, you’ve probably encountered ISO 8583. This standard is the foundation for electronic transactions across ATMs, POS terminals, and online payment gateway.

One of the core components of ISO 8583 is the Message Type Indicator (MTI). It’s a four-digit code that defines the message’s purpose, whether it’s an authorization request, financial transaction, or administrative message.

Why Should You Care About MTI?

During my work at a Payment Aggregator and our Payment Switch, I had to troubleshoot transaction failures, missing payments, and integration issues between acquirers and our system. One common problem was the misinterpretation of message types, either due to incorrect MTI handling or unexpected values from acquirers.

Understanding MTI was crucial to diagnosing errors quickly. So, let’s break it down in a way that’s useful whether you’re developing a payment gateway, debugging a POS system, or simply curious about financial transactions.


What is ISO 8583 MTI?

The Message Type Indicator (MTI) in ISO 8583 is a four-digit numeric code that identifies the nature of a financial transaction message. Each digit has a specific meaning:

MTI Breakdown
Digit PositionMeaningPossible Values
1st (Message Version)ISO 8583 Version0 (1987), 1 (1993), 2 (2003)
2nd (Message Class)Transaction Type1 (Authorization), 2 (Financial), 3 (File Action), 4 (Reversal), 5 (Reconciliation), 6 (Administrative), 7 (Fee Collection), 8 (Network Management)
3rd (Message Function)Message Flow0 (Request), 1 (Response), 2 (Advice), 3 (Advice Response), 4 (Notification), 5 (Notification Response)
4th (Message Origin)Message Origin0 (Acquirer), 1 (Issuer), 2 (Other)

Understanding Common MTIs

Here are some real-world MTIs that you might encounter:

MTIMeaning
0100Authorization Request (Customer wants to pay)
0110Authorization Response (Bank approves/rejects)
0200Financial Transaction Request (Debit or Credit)
0210Financial Transaction Response
0400Reversal Request (Transaction rollback)
0410Reversal Response
0800Network Management Request (Echo Test, Sign-On)
0810Network Management Response

Example: When a customer insert their card at a POS terminal, the system might send an 0100 (Authorization Request to the bank. The bank will respond with 0110 (Authorization Response), approving or declining the transaction.

Note: The 0800/0810 messages can be used for different purposes depending on the acquirer or host specifications. For example, at my company, we use 0800/0810 for a different purpose, not for network management requests, which I cannot disclose here on the blog.


Creating and Parsing an MTI

Now, let’s dive into some practical C# code that helps you construct and read an MTI. The code I’m presenting here is for C#, but the concept is the same with other programming languages. What’s important is that you understand the concept, and it will work regardless of the programming language you are using.

Creating an MTI
C#
public class ISO8583MTI
{
    public int Version { get; set; }   // First digit
    public int MessageClass { get; set; }  // Second digit
    public int MessageFunction { get; set; } // Third digit
    public int MessageOrigin { get; set; } // Fourth digit

    public ISO8583MTI(int version, int messageClass, int messageFunction, int messageOrigin)
    {
        Version = version;
        MessageClass = messageClass;
        MessageFunction = messageFunction;
        MessageOrigin = messageOrigin;
    }

    public string GetMTI()
    {
        return $"{Version}{MessageClass}{MessageFunction}{MessageOrigin}";
    }
}

// Example Usage:
var mti = new ISO8583MTI(0, 2, 0, 0);  // Financial Transaction Request (0200)
Console.WriteLine($"Generated MTI: {mti.GetMTI()}");

Output:

Bash
0200
Parsing MTI from a Host Response

If you’re receiving an MTI from a payment gateway or financial institution, you need to extract its meaning:

C#
public class MTIParser
{
    public static void ParseMTI(string mti)
    {
        if (mti.Length != 4 || !int.TryParse(mti, out _))
        {
            Console.WriteLine("Invalid MTI format.");
            return;
        }

        string version = mti[0] switch
        {
            '0' => "ISO 8583:1987",
            '1' => "ISO 8583:1993",
            '2' => "ISO 8583:2003",
            _ => "Unknown Version"
        };

        string messageClass = mti[1] switch
        {
            '1' => "Authorization",
            '2' => "Financial",
            '4' => "Reversal",
            '8' => "Network Management",
            _ => "Unknown Class"
        };

        string messageFunction = mti[2] switch
        {
            '0' => "Request",
            '1' => "Response",
            '2' => "Advice",
            '3' => "Advice Response",
            _ => "Unknown Function"
        };

        string messageOrigin = mti[3] switch
        {
            '0' => "Acquirer",
            '1' => "Issuer",
            _ => "Unknown Origin"
        };

        Console.WriteLine($"Parsed MTI: {mti}");
        Console.WriteLine($"- Version: {version}");
        Console.WriteLine($"- Class: {messageClass}");
        Console.WriteLine($"- Function: {messageFunction}");
        Console.WriteLine($"- Origin: {messageOrigin}");
    }
}

// Example Usage:
MTIParser.ParseMTI("0210");  // Financial Transaction Response

Output:

Bash
Parsed MTI: 0210
- Version: ISO 8583:1987
- Class: Financial
- Function: Response
- Origin: Acquirer

Sources and References: