mt

package module
v0.0.0-...-28ad961 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2023 License: MIT Imports: 12 Imported by: 0

README

Go MT

Coverage Go Report Card

!! WORK IN PROGRESS !!

A library for parsing MT (message text) messages in Go according to the SWIFT specification.

Only a small subset of the specification is supported as of this moment but more shall be added in future and are welcomed through contributions.

Currently supported:

  • MT940
  • MT950

Documentation

Overview

A library for parsing of MT (message text) messages according to the SWIFT specification.

This software is released under the MIT License. https://opensource.org/licenses/MIT

This software is released under the MIT License. https://opensource.org/licenses/MIT

Index

Constants

View Source
const (
	TimeFormatTime            = "1504"
	TimeFormatMonth           = "0102"
	TimeFormatDate            = "060102"
	TimeFormatDateTime        = "0601021504"
	TimeFormatDateTimeSec     = "060102150405"
	TimeFormatDateTimeSecCent = "060102150405.999"
	TimeFormatDateTimeOffset  = "0601021504-0700"
)
View Source
const MessageTypeMT940 = "940"

Variables

This section is empty.

Functions

func Lax

func Lax(lax bool) option

Lax will cause messages that fail validation to be returned anyway. Otherwise invalid messages are discarded. In both cases any validation errors will be returned as parse errors. This is the main difference with SkipValidation as validation is still performed and its errors are sent to the client.

Default: false

func ParseMT940

func ParseMT940(ctx context.Context, rd io.Reader, options ...option) (chan MT940, chan Error)

ParseMT940 parses and validates MTx messages from ParseMTx into MT940 messages. Invalid messages are discarded unless the option Lax is passed.

func ParseMTx

func ParseMTx(ctx context.Context, rd io.Reader, options ...option) (chan MTx, chan Error)

ParseMTx takes as input a reader and will attempt to parse all MT messages in the input and publish them to the returned channel. Any messages that cannot be parsed are discarded. The errors encountered during parsing are published on the returned parse error channel.

This function returns generic MT messages, meaning the body is not parsed but simply returned as a map[string][]string. Look to the specialized derivatives for messages with fully parsed bodies.

Using channels here means that potentially very large inputs can be read without running out of memory. If input is expected to easily fit into memory it is advised to use ParseAllMTx for convenience instead.

Example usage:

f, err := os.Open("/path/to/mt/file.txt")
if err != nil {
	return nil, fmt.Errorf("could not open file: %w", err)
}
defer f.Close()

messages, errors := ParseMTx(f)

// handle the errors from the errors channel
// process the messages from the messages channel

func SkipValidation

func SkipValidation(skip bool) option

SkipValidation will skip message validation and return messages as-is. The difference with Lax is that with this option validation is skipped entirely and there won't be any gathering of validation errors. This option is therefore only useful when performance is more important than validity.

Default: false

func StopOnError

func StopOnError(stop bool) option

StopOnError will make the parsing process stop on the first error.

Default: false

func ValidateMT940

func ValidateMT940(mt940 MT940) error

Types

type AppHeaderInput

type AppHeaderInput struct {
	Set                         bool
	Raw                         string
	ObsolescencePeriodInMinutes int
	MessageType                 string
	ReceiverAddress             string
	MessagePriority             Priority
	DeliveryMonitor             DeliveryMonitor
}

AppHeaderInput contains information, from block 2, that is specific to the application. The application header is required for messages that users, or the system and users, exchange. Exceptions are session establishment and session closure.

It is filled if and only if the message is of the input variety and therefore might not have been set. It is advised to verify whether it has been set before accessing the data within. This can be done with the Set field or the IsInput function on the containing message.

type AppHeaderOutput

type AppHeaderOutput struct {
	Set                   bool
	Raw                   string
	MessagePriority       Priority
	MessageType           string
	MessageInputReference InputReference
	InputTime             Time
	OutputDate            Date
	OutputTime            Time
}

AppHeaderOutput contains information, from block 2, that is specific to the application. The application header is required for messages that users, or the system and users, exchange. Exceptions are session establishment and session closure.

It is filled if and only if the message is of the output variety and herefore might not have been set. It is advised to verify whether it has been set before accessing the data within. This can be done with the Set field or the IsOutput function on the containing message.

type ApplicationID

type ApplicationID int

ApplicationID identifies the application within which the message is being sent or received. The available options are: F = FIN All user-to-user, FIN system and FIN service messages A = GPA (General Purpose Application) Most GPA system and service messages L = GPA Certain GPA service messages, for example, LOGIN, LAKs, ABORT These values are automatically assigned by the SWIFT system and the user's CBT.

const (
	ApplicationIDFinancial ApplicationID = iota // F
	ApplicationIDGeneral                        // A
	ApplicationIDLogin                          // L
)

func (ApplicationID) RawString

func (aid ApplicationID) RawString() string

func (ApplicationID) String

func (aid ApplicationID) String() string

type Balance

type Balance struct {
	Set         bool
	Raw         string
	CreditDebit CreditDebit `mt:"M,1!a"`
	Date        Date        `mt:"M,6!n"`
	Currency    string      `mt:"M,3!a"`
	Amount      float32     `mt:"M,15d"`
}

Balance represents the balance of a given account at a given date.

func (Balance) RawString

func (b Balance) RawString() string

func (*Balance) UnmarshalMT

func (b *Balance) UnmarshalMT(input string) error

type Base

type Base struct {
	Raw             string
	Line            int
	BasicHeader     BasicHeader
	AppHeaderInput  AppHeaderInput
	AppHeaderOutput AppHeaderOutput
	UsrHeader       UsrHeader
	Trailers        Trailers
}

Base holds the basic structure all MT messages adhere to, excluding the body.

func (Base) HasTrailers

func (b Base) HasTrailers() bool

HasTrailers returns true if the trailers of the message were set/filled. It is advised to use this function before accessing information in the Trailers struct.

func (Base) HasUserHeader

func (b Base) HasUserHeader() bool

HasUserHeader returns true if the user header of the message was set/filled. It is advised to use this function before accessing information in the UsrHeader struct.

func (Base) IsInput

func (b Base) IsInput() bool

IsInput returns true if the message is of the input variety. If so it will contain an input type app header. It is advised to use this function before accessing information in the AppHeaderInput struct.

func (Base) IsOutput

func (b Base) IsOutput() bool

IsOutput returns true if the message is of the output variety. If so it will contain an output type app header. It is advised to use this function before accessing information in the AppHeaderOutput struct.

func (Base) Priority

func (b Base) Priority() Priority

Priority takes the priority from the app header, taking into account whether the message is input or output.

func (Base) Type

func (b Base) Type() string

Priority takes the message type from the app header, taking into account whether the message is input or output.

type BasicHeader

type BasicHeader struct {
	Raw                    string
	AppID                  ApplicationID
	ServiceID              ServiceID
	SessionNumber          string
	SequenceNumber         string
	LogicalTerminalAddress string
}

BasicHeader is the only mandatory block; block 1. The basic header contains the general information that identifies the message, and some additional control information. The FIN interface automatically builds the basic header.

type CreditDebit

type CreditDebit int

CreditDebit indicates whether the balance is a credit or a debit.

const (
	Credit CreditDebit = iota
	Debit
)

func (CreditDebit) RawString

func (cd CreditDebit) RawString() string

func (CreditDebit) String

func (cd CreditDebit) String() string

type Date

type Date struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (Date) RawString

func (d Date) RawString() string

func (Date) String

func (d Date) String() string

func (*Date) UnmarshalMT

func (d *Date) UnmarshalMT(input string) error

type DateOrDateTime

type DateOrDateTime struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateOrDateTime) RawString

func (d DateOrDateTime) RawString() string

func (DateOrDateTime) String

func (d DateOrDateTime) String() string

func (*DateOrDateTime) UnmarshalMT

func (d *DateOrDateTime) UnmarshalMT(input string) error

type DateTime

type DateTime struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateTime) RawString

func (d DateTime) RawString() string

func (DateTime) String

func (d DateTime) String() string

func (*DateTime) UnmarshalMT

func (d *DateTime) UnmarshalMT(input string) error

type DateTimeOffset

type DateTimeOffset struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateTimeOffset) RawString

func (d DateTimeOffset) RawString() string

func (DateTimeOffset) String

func (d DateTimeOffset) String() string

func (*DateTimeOffset) UnmarshalMT

func (d *DateTimeOffset) UnmarshalMT(input string) error

type DateTimeSec

type DateTimeSec struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateTimeSec) RawString

func (d DateTimeSec) RawString() string

func (DateTimeSec) String

func (d DateTimeSec) String() string

func (*DateTimeSec) UnmarshalMT

func (d *DateTimeSec) UnmarshalMT(input string) error

type DateTimeSecCent

type DateTimeSecCent struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateTimeSecCent) RawString

func (d DateTimeSecCent) RawString() string

func (DateTimeSecCent) String

func (d DateTimeSecCent) String() string

func (*DateTimeSecCent) UnmarshalMT

func (d *DateTimeSecCent) UnmarshalMT(input string) error

type DateTimeSecOptCent

type DateTimeSecOptCent struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (DateTimeSecOptCent) RawString

func (d DateTimeSecOptCent) RawString() string

func (DateTimeSecOptCent) String

func (d DateTimeSecOptCent) String() string

func (*DateTimeSecOptCent) UnmarshalMT

func (d *DateTimeSecOptCent) UnmarshalMT(input string) error

type DeliveryMonitor

type DeliveryMonitor int

DeliveryMonitor applies only to FIN user-to-user messages. The chosen option is expressed as a single digit: 1 = Non-Delivery Warning 2 = Delivery Notification 3 = Non-Delivery Warning and Delivery Notification If the message has priority 'U', the user must request delivery monitoring option '1' or '3'. If the message has priority 'N', the user can request delivery monitoring option '2' or, by leaving the option blank, no delivery monitoring.

const (
	DeliveryMonitorNonDelivery DeliveryMonitor = iota // 1
	DeliveryMonitorDelivery                           // 2
	DeliveryMonitorBoth                               // 3
)

func (DeliveryMonitor) RawString

func (dm DeliveryMonitor) RawString() string

func (DeliveryMonitor) String

func (dm DeliveryMonitor) String() string

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error is used when parsing of an input encounters a problem.

A parse error will generally not stop the parsing process, as the remaining messages will attempted to be parsed.

Any and all parse errors per input should be aggregated by this library and returned to the caller.

func NewError

func NewError(cause error, line int) Error

NewError creates a new parse error.

func (Error) Cause

func (e Error) Cause() error

Cause returns the underlying error.

func (Error) Error

func (e Error) Error() string

Error implements the Error interface.

func (Error) Line

func (e Error) Line() int

Line returns the line in the input where the error occurred.

func (Error) String

func (e Error) String() string

String returns the string representation of the parse error.

type Errors

type Errors []Error

Errors is a custom error type that is used for aggregating Error's into one error.

func (Errors) Error

func (es Errors) Error() string

Error implements the Error interface.

func (Errors) String

func (es Errors) String() string

String returns the string representation of a group of parse errors.

type FundsCode

type FundsCode int
const (
	FundsCodeCredit         FundsCode = iota // C
	FundsCodeCreditReversal                  // RC
	FundsCodeDebit                           // D
	FundsCodeDebitReversal                   // RD
)

func (FundsCode) RawString

func (fc FundsCode) RawString() string

func (FundsCode) String

func (fc FundsCode) String() string

type InputReference

type InputReference struct {
	Set                    bool
	Raw                    string
	LogicalTerminalAddress string
	SessionNumber          string
	SequenceNumber         string
	DateOrDateTime         DateOrDateTime
}

InputReference is a reference to an input message containing only the send date of said message.

type MT940

type MT940 struct {
	Base
	Reference                     string          `mt:"20,M,16x"`
	AccountIdentification         string          `mt:"25,M,2!c26!n|8!c/12!n"`
	StatementNumberSequenceNumber string          `mt:"28C,M,5!n(/3!n)"`
	OpeningBalance                Balance         `mt:"60F,M,dive"`
	StatementLines                []StatementLine `mt:"61,O,dive"`
	AccountOwnerInformation       []string        `mt:"86,O,6*65x"`
}

MT940 represents a Customer Statement Message. It's based on the spec here: https://www2.swift.com/knowledgecentre/publications/us9m_20210723/1.0?topic=mt940.htm

func MTxToMT940

func MTxToMT940(mtx MTx) (MT940, error)

func ParseAllMT940

func ParseAllMT940(ctx context.Context, rd io.Reader, options ...option) ([]MT940, error)

ParseAllMT940 parses and validates MTx messages from ParseAllMTx into MT940 messages. Invalid messages are discarded unless the option Lax is passed.

type MTx

type MTx struct {
	Base
	Body map[string][]string
}

MTx represents a complete message including headers and a body. The body has not been further processes or validated. The specific type of MT message this holds can be determined by the Type() function.

If parsing into a more specifc struct is desireed the MTxToMT... functions be used. After parsing into a more specific type the ValidateMT... functions can be used to validate the message.

func ParseAllMTx

func ParseAllMTx(ctx context.Context, rd io.Reader, options ...option) ([]MTx, error)

ParseAllMTx takes as input a reader and will attempt to parse all MT messages in the input and return them to the caller. It's a convenience function for reading an entire input. If the input is expected to be very large, too large to fit in memory, use ParseMTx instead.

In case of any errors during parsing a custom error is returned that encapsulates the parse errors. The presence of this error does not discredit the messages in the messages slice. Those were successfully parsed.

This function returns generic MT messages, meaning the body is not parsed but simply returned as a map[string]string. Look to the specialized derivatives for messages with fully parsed bodies.

Example usage:

f, err := os.Open("/path/to/mt/file.txt")
if err != nil {
	return nil, fmt.Errorf("could not open file: %w", err)
}
defer f.Close()

messages, results, err := ParseAllMTx(f)
if err != nil {
	// handle parse errors
}

return messages, nil

type Month

type Month struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (Month) RawString

func (m Month) RawString() string

func (Month) String

func (m Month) String() string

func (*Month) UnmarshalMT

func (m *Month) UnmarshalMT(input string) error

type OutputReference

type OutputReference struct {
	Set                    bool
	Raw                    string
	LogicalTerminalAddress string
	SessionNumber          string
	SequenceNumber         string
	DateOrDateTime         DateOrDateTime
}

OutputReference is a reference to an output message containing both the send date and time of said message.

type PossibleDuplicateEmission

type PossibleDuplicateEmission struct {
	Raw                   string
	Time                  Time
	MessageInputReference InputReference
}

PossibleDuplicateEmission is added if user thinks the same message was sent previously.

type PossibleDuplicateMessage

type PossibleDuplicateMessage struct {
	Raw                    string
	Time                   Time
	MessageOutputReference OutputReference
}

PossibleDuplicateMessage is added by the system to any output message (GPA and FIN with a Service Identifier of 01) being resent because a prior delivery may not be valid. If a system PLT receives a report request with a PDM trailer, the response has a plain PDM (without the optional delivery reference). Other PDMs may be added because of unsuccessful delivery attempts to the user.

type Priority

type Priority int

Priority is used within FIN Application Headers only, defines the priority with which a message is delivered. The possible values are: S = System U = Urgent N = Normal

const (
	PriorityNormal Priority = iota // N
	PrioritySystem                 // S
	PriorityUrgent                 // U
)

func (Priority) RawString

func (p Priority) RawString() string

func (Priority) String

func (p Priority) String() string

type Reference

type Reference struct {
	Set                   bool
	Raw                   string
	DateTime              DateTime
	MessageInputReference InputReference
}

Reference is a reference to an original user message.

type ServiceID

type ServiceID int

ServiceID consists of two numeric characters. It identifies the type of data that is being sent or received and, in doing so, whether the message which follows is one of the following: a user-to-user message, a system message, a service message, for example, a session control command, such as SELECT, or a logical acknowledgment, such as ACK/SAK/UAK. Possible values are 01 = FIN/GPA or 21 = ACK/NAK.

const (
	ServiceIDFINGPA  ServiceID = iota // 01
	ServiceIDACKNACK                  // 21
)

func (ServiceID) RawString

func (sid ServiceID) RawString() string

func (ServiceID) String

func (sid ServiceID) String() string

type StatementLine

type StatementLine struct {
	Set                   bool
	Raw                   string
	Date                  Date      `mt:"M,6!n"`
	EntryDate             Month     `mt:"O,4!n"`
	FundsCode             FundsCode `mt:"M,2a"`
	Amount                float64   `mt:"M,15d"`
	SwiftCode             string    `mt:"M,1!a3!c"`
	AccountOwnerReference string    `mt:"M,16x"`
	BankReference         string    `mt:"O,//20x"`
	Description           string    `mt:"O,34a"`
}

func (StatementLine) RawString

func (sl StatementLine) RawString() string

func (*StatementLine) UnmarshalMT

func (sl *StatementLine) UnmarshalMT(input string) error

type SystemOriginatedMessage

type SystemOriginatedMessage struct {
	Raw                   string
	Time                  Time
	MessageInputReference InputReference
}

SystemOriginatedMessage is the system message or service message.

type Time

type Time struct {
	Set  bool
	Raw  string
	Time time.Time
}

func (Time) RawString

func (d Time) RawString() string

func (Time) String

func (d Time) String() string

func (*Time) UnmarshalMT

func (d *Time) UnmarshalMT(input string) error

type Trailers

type Trailers struct {
	Set                       bool
	Raw                       string
	DelayedMessage            bool
	TestAndTrainingMessage    bool
	Checksum                  string
	MessageReference          Reference
	PossibleDuplicateEmission PossibleDuplicateEmission
	PossibleDuplicateMessage  PossibleDuplicateMessage
	SystemOriginatedMessage   SystemOriginatedMessage
	AdditionalTrailers        map[string]string
}

Trailers contains the information from block 5. The trailer either indicates special circumstances that relate to message handling or contains security information.

Trailers are optional and therefore might not have been set. It is advised to verify whether they have been set before accessing the data within. This can be done with the Set field or the HasTrailers function on the message.

type UsrHeader

type UsrHeader struct {
	Set                                bool
	Raw                                string
	ServiceID                          string
	AddresseeInformation               string
	BankingPriority                    string
	MessageUserReference               string
	ValidationFlag                     string
	RelatedReference                   string
	ServiceTypeID                      string
	UniqueEndToEndTransactionReference string
	PaymentReleaseInformation          string
	SanctionsScreeningInformation      string
	PaymentControlsInformation         string
	BalanceCheckpointDateTime          DateTimeSecOptCent
	MessageInputReference              InputReference
}

UsrHeader is an optional header that contains the information from block 3.

This header is optional and therefore might not have been set. It is advised to verify whether it has been set before accessing the data within. This can be done with the Set field or the HasUserHeader function on the message.

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL