Iso8583
A golang implementation to marshal and unmarshal iso8583 message.
Install / Use
/learn @moov-io/Iso8583README
moov-io/iso8583
Moov's mission is to give developers an easy way to create and integrate bank processing into their own software products. Our open source projects are each focused on solving a single responsibility in financial services and designed around performance, scalability, and ease of use.
ISO8583 implements an ISO 8583 message reader and writer in Go. ISO 8583 is an international standard for card-originated financial transaction messages that defines both message format and communication flow. It's used by major card networks around the globe including Visa, Mastercard, and Verve. The standard supports card purchases, withdrawals, deposits, refunds, reversals, balance inquiries, inter-account transfers, administrative messages, secure key exchanges, and more.
Table of contents
- Project status
- Installation
- Quick Start
- Go version support policy
- How to
- ISO8583 CLI
- Learn more
- Getting help
- Contributing
- Related projects
Project status
Moov ISO8583 is a Go package that's been thoroughly tested and trusted in the real world. The project has proven its reliability and robustness in real-world, high-stakes scenarios. Please let us know if you encounter any missing feature/bugs/unclear documentation by opening up an issue or asking on our #iso8583 Community Slack channel. . Thanks!
Installation
go get github.com/moov-io/iso8583
Quick Start
The following example demonstrates how to:
- Define message structure using Go types
- Pack a message for transmission
- Unpack and parse a received message
package main
import (
"fmt"
"os"
"github.com/moov-io/iso8583"
"github.com/moov-io/iso8583/examples"
)
// Define types for the message fields
type Authorization struct {
MTI string `iso8583:"0"` // Message Type Indicator
PrimaryAccountNumber string `iso8583:"2"` // PAN
ProcessingCode string `iso8583:"3"` // Processing code
Amount int64 `iso8583:"4"` // Transaction amount
STAN string `iso8583:"11"` // System Trace Audit Number
ExpirationDate string `iso8583:"14"` // YYMM
AcceptorInformation *AcceptorInformation `iso8583:"43"` // Merchant details
}
type AcceptorInformation struct {
Name string `iso8583:"1"`
City string `iso8583:"2"`
Country string `iso8583:"3"`
}
func main() {
// Pack the message
msg := iso8583.NewMessage(examples.Spec)
authData := &Authorization{
MTI: "0100",
PrimaryAccountNumber: "4242424242424242",
ProcessingCode: "000000",
Amount: 2599,
ExpirationDate: "2201",
AcceptorInformation: &AcceptorInformation{
Name: "Merchant Name",
City: "Denver",
Country: "US",
},
}
// Set the field values
err := msg.Marshal(authData)
if err != nil {
panic(err)
}
// Pack the message
packed, err := msg.Pack()
if err != nil {
panic(err)
}
// send packed message to the server
// ...
// Unpack the message
msg = iso8583.NewMessage(examples.Spec)
err = msg.Unpack(packed)
if err != nil {
panic(err)
}
// get individual field values
var amount int64
err = msg.UnmarshalPath("4", &amount)
if err != nil {
panic(err)
}
fmt.Printf("Amount: %d\n", amount)
// get value of composite subfield
var acceptorName string
err = msg.UnmarshalPath("43.1", &acceptorName)
if err != nil {
panic(err)
}
fmt.Printf("Acceptor Name: %s\n", acceptorName)
// Get the field values into data structure
authData = &Authorization{}
err = msg.Unmarshal(authData)
if err != nil {
panic(err)
}
// Print the entire message
iso8583.Describe(msg, os.Stdout)
}
Go version support policy
Always up-to-date, never left behind
While we strive to embrace the latest language enhancements, we also appreciate the need for a certain degree of backward compatibility. We understand that not everyone can update to the latest version immediately. Our philosophy is to move forward and embrace the new, but without leaving anyone immediately behind.
Which versions do we support now?
As of today, we are supporting the following versions as referenced in the setup-go action step:
stable(which points to the current Go version)oldstable(which points to the previous Go version)
The setup-go action automatically manages versioning, allowing us to always stay aligned with the latest and preceding Go releases.
What does this mean for you?
Whenever a new version of Go is released, we will update our systems and ensure that our project remains fully compatible with it. At the same time, we will continue to support the previous version. However, once a new version is released, the 'previous previous' version will no longer be officially supported.
Continuous integration
To ensure our promise of support for these versions, we've configured our GitHub CI actions to test our code with both the current and previous versions of Go. This means you can feel confident that the project will work as expected if you're using either of these versions.
How to
Defining Message Specifications
Most ISO 8583 implementations use confidential specifications that vary between payment systems, so you'll likely need to create your own specification. We provide example specifications in /specs directory that you can use as a starting point.
Core Concepts
The package maps ISO 8583 concepts to the following types:
- MessageSpec - Defines the complete message format with fields
- field.Spec - Defines field's structure and behavior
- field.Field - Represents an ISO 8583 data element with its value storing and handling logic:
field.String- For alphanumeric fieldsfield.Numeric- For numeric fieldsfield.Binary- For binary data fieldsfield.Composite- For structured data like TLV/BER-TLV fields or fields with positional subfields
Each field specification consists of these elements:
| Element | Notes | Example |
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|
| Length | Maximum length of field (bytes, characters or digits), for both fixed and variable lengths. | 10 |
| Description | Describes what the data field holds. | "Primary Account Number" |
| Enc | Sets the encoding type (ASCII, Binary, BCD, LBCD, EBCDIC). | encoding.ASCII |
| Pref | Sets the encoding (ASCII, Binary, BCD, EBCDIC) of the field length and its type as fixed or variable (Fixed, L, LL, LLL, LLLL). The number of 'L's corresponds to the number of digits in a variable length. | prefix.ASCII.Fixed |
| Pad (option

