Message Class Identifier

easy · iso8583, payments

Message Class Identifier

You're on call for a payment gateway. At 2 AM, alerts fire: transaction throughput dropped 40%. You pull up the message logs and see thousands of ISO8583 messages. To diagnose the issue, you need to quickly categorize them: how many are authorizations? How many reversals? Are network management messages failing?

Your task: given an MTI string, identify the message class and whether it's a request or response.

Background

The MTI encodes the message class in position 1 (second character):

MTI:     0   1   0   0
Position: 0   1   2   3
              │
              └─► Message Class
Class ValueNameDescription
1AuthorizationReal-time card authorization ("Can this card spend $50?")
2FinancialStore-and-forward financial messages
4ReversalCancel or void a previous transaction
8Network ManagementSign-on, echo test, key exchange
3, 5, 6, 7, 9OtherLess common: file actions, reconciliation, admin, fees

Position 2 tells you if it's a request or response:

Function ValueType
0Request
1Response
2Advice
3Advice Response
4+Other (notification, etc.)

What You're Building

type MessageClass string

const (
    ClassAuthorization    MessageClass = "authorization"
    ClassFinancial        MessageClass = "financial"
    ClassReversal         MessageClass = "reversal"
    ClassNetworkMgmt      MessageClass = "network_management"
    ClassOther            MessageClass = "other"
)

type MessageFunction string

const (
    FunctionRequest       MessageFunction = "request"
    FunctionResponse      MessageFunction = "response"
    FunctionAdvice        MessageFunction = "advice"
    FunctionAdviceResp    MessageFunction = "advice_response"
    FunctionOther         MessageFunction = "other"
)

type MessageInfo struct {
    Class    MessageClass
    Function MessageFunction
    IsRepeat bool  // True if origin indicates a repeat (positions 1, 3, 5)
}

func IdentifyMessage(mti string) (MessageInfo, error)

Behavior

  1. Validate the MTI (exactly 4 ASCII digits)
  2. Extract the class from position 1
  3. Extract the function from position 2
  4. Determine if it's a repeat from position 3 (values 1, 3, 5 indicate repeat)
  5. Return the structured information

Examples

IdentifyMessage("0100")
// → MessageInfo{
//     Class:    ClassAuthorization,
//     Function: FunctionRequest,
//     IsRepeat: false,
// }, nil

IdentifyMessage("0110")
// → MessageInfo{
//     Class:    ClassAuthorization,
//     Function: FunctionResponse,
//     IsRepeat: false,
// }, nil

IdentifyMessage("0401")
// → MessageInfo{
//     Class:    ClassReversal,
//     Function: FunctionRequest,
//     IsRepeat: true,  // Origin=1 means acquirer repeat
// }, nil

IdentifyMessage("0800")
// → MessageInfo{
//     Class:    ClassNetworkMgmt,
//     Function: FunctionRequest,
//     IsRepeat: false,
// }, nil

IdentifyMessage("0320")
// → MessageInfo{
//     Class:    ClassOther,  // Class 3 = File Actions
//     Function: FunctionAdvice,
//     IsRepeat: false,
// }, nil

IdentifyMessage("01")    // → error (too short)
IdentifyMessage("010X")  // → error (non-digit)

Why This Matters

In production monitoring, you often need to aggregate messages by type:

  • "Show me all authorization failures in the last hour"
  • "How many reversals are we processing?"
  • "Are network management messages getting responses?"

This function is the building block for that analysis. When you see 0420 in a log, you instantly know: reversal advice. When you see 0810, you know: network management response. This pattern recognition becomes second nature.

Mapping Rules

Class mapping:

  • 1 → authorization
  • 2 → financial
  • 4 → reversal
  • 8 → network_management
  • Everything else (0, 3, 5, 6, 7, 9) → other

Function mapping:

  • 0 → request
  • 1 → response
  • 2 → advice
  • 3 → advice_response
  • 4+ → other

Repeat detection:

  • Origin values 1, 3, 5 indicate retransmission
  • Origin values 0, 2, 4 indicate first transmission

Hints (only if stuck)

<details> <summary>Hint 1: Reuse your work</summary> You can use similar validation logic from the MTI parser problem. First validate, then extract. </details>

<details> <summary>Hint 2: Use a switch statement</summary> Go's switch is clean for mapping values:

switch classDigit {
case '1':
    return ClassAuthorization
case '2':
    return ClassFinancial
// ...
}

</details>

<details> <summary>Hint 3: Repeat detection</summary> The origin digit is odd (1, 3, 5) for repeats, even (0, 2, 4) for first transmissions. You could check origin % 2 == 1 after converting to int. </details>

Run tests to see results
No issues detected
    Join Discord