github.com/danil/iso8583@v0.21.0/scan8583/scan8583_test.go (about)

     1  package scan8583_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"runtime"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/danil/iso8583/codec8583"
    12  	"github.com/danil/iso8583/scan8583"
    13  	"github.com/protoscan/protoscan"
    14  )
    15  
    16  var ScannerScanTestCases = []struct {
    17  	line      int
    18  	split     protoscan.SplitFunc
    19  	input     []byte
    20  	expected  int
    21  	benchmark bool
    22  }{
    23  	{
    24  		line:      line(),
    25  		split:     scan8583.ScanISO8583Indiscriminately,
    26  		input:     payload8583(tsysMsgs[0], tsysMsgs[1], tsysMsgs[2], tsysMsgs[3]),
    27  		expected:  4,
    28  		benchmark: true,
    29  	},
    30  	{
    31  		line:     line(),
    32  		split:    scan8583.ScanISO8583Indiscriminately,
    33  		input:    payload8583(tsysMsgs[3]),
    34  		expected: 1,
    35  	},
    36  	{
    37  		line:     line(),
    38  		split:    scan8583.ScanISO8583Indiscriminately,
    39  		input:    []byte{},
    40  		expected: 0,
    41  	},
    42  }
    43  
    44  func TestScannerScan(t *testing.T) {
    45  	_, testFile, _, _ := runtime.Caller(0)
    46  	for _, tc := range ScannerScanTestCases {
    47  		tc := tc
    48  		t.Run(strconv.Itoa(tc.line), func(t *testing.T) {
    49  			t.Parallel()
    50  			linkToExample := fmt.Sprintf("%s:%d", testFile, tc.line)
    51  			r := bytes.NewReader(tc.input)
    52  			s := protoscan.Protoscan{
    53  				Reader: r,
    54  				Split:  tc.split,
    55  			}
    56  			var (
    57  				count   int
    58  				payload []byte
    59  			)
    60  			for s.Scan() {
    61  				count++
    62  				payload = append(payload, s.Token...)
    63  			}
    64  			err := s.Err()
    65  			if err != nil {
    66  				t.Fatalf("unexpected scan error: %v %s", err, linkToExample)
    67  			}
    68  			if !bytes.Equal(payload, tc.input) {
    69  				t.Errorf("unexpected payload, expected: %#v, received: %#v %s", tc.input, payload, linkToExample)
    70  			}
    71  			if len(payload) != len(tc.input) {
    72  				t.Errorf("unexpected payload length, expected: %#v, received: %#v %s", len(tc.input), len(payload), linkToExample)
    73  			}
    74  			if count != tc.expected {
    75  				t.Errorf("unexpected token count, expected: %#v, received: %#v %s", tc.expected, count, linkToExample)
    76  			}
    77  		})
    78  	}
    79  }
    80  
    81  var tsysValidationTestCases = []struct {
    82  	line      int
    83  	input     []byte
    84  	benchmark bool
    85  }{
    86  	{
    87  		line:  line(),
    88  		input: payload8583(tsysMsgs[0], tsysMsgs[1], tsysMsgs[2], tsysMsgs[3]),
    89  	},
    90  	{
    91  		line:  line(),
    92  		input: payload8583(tsysMsgs[3]),
    93  	},
    94  	{
    95  		line:  line(),
    96  		input: []byte{},
    97  	},
    98  }
    99  
   100  func TestTSYSValidation(t *testing.T) {
   101  	_, testFile, _, _ := runtime.Caller(0)
   102  	for _, tc := range tsysValidationTestCases {
   103  		tc := tc
   104  		t.Run(strconv.Itoa(tc.line), func(t *testing.T) {
   105  			t.Parallel()
   106  			linkToExample := fmt.Sprintf("%s:%d", testFile, tc.line)
   107  			r := bytes.NewReader(tc.input)
   108  			s := protoscan.Protoscan{
   109  				Reader: r,
   110  				Split:  scan8583.ScanISO8583Indiscriminately,
   111  			}
   112  			var (
   113  				tokens  [][]byte
   114  				payload []byte
   115  			)
   116  			for s.Scan() {
   117  				token := append([]byte{}, s.Token...)
   118  				tokens = append(tokens, token)
   119  				payload = append(payload, token...)
   120  			}
   121  			err := s.Err()
   122  			if err != nil {
   123  				t.Fatalf("unexpected scan error: %v %s", err, linkToExample)
   124  			}
   125  			if !bytes.Equal(payload, tc.input) {
   126  				t.Errorf("unexpected payload, expected: %#v, received: %#v %s", tc.input, payload, linkToExample)
   127  			}
   128  			if len(payload) != len(tc.input) {
   129  				t.Errorf("unexpected payload length, expected: %#v, received: %#v %s", len(tc.input), len(payload), linkToExample)
   130  			}
   131  			for i, token := range tokens {
   132  				message := token[scan8583.ISO8583HeadSize:]
   133  				tr := tsysMessage{}
   134  				err := codec8583.TSYSUnmarshaler.Unmarshal(message, &tr)
   135  				if err != nil {
   136  					t.Errorf("unexpected error on unmarshaling tsys message %d: %v %s",
   137  						i, err, linkToExample)
   138  				}
   139  			}
   140  		})
   141  	}
   142  }
   143  
   144  func BenchmarkScannerScan(b *testing.B) {
   145  	b.ReportAllocs()
   146  	for _, tc := range ScannerScanTestCases {
   147  		if !tc.benchmark {
   148  			continue
   149  		}
   150  		b.Run(strconv.Itoa(tc.line), func(b *testing.B) {
   151  			for i := 0; i < b.N; i++ {
   152  				r := bytes.NewReader(tc.input)
   153  				s := protoscan.Protoscan{
   154  					Reader: r,
   155  					Split:  tc.split,
   156  				}
   157  				for s.Scan() {
   158  				}
   159  			}
   160  		})
   161  	}
   162  }
   163  
   164  func line() int { _, _, l, _ := runtime.Caller(1); return l }
   165  
   166  var tsysMsgs = [][]byte{
   167  	[]byte{0x30, 0x31, 0x30, 0x30, 0xf6, 0x7e, 0x44, 0x91, 0x2c, 0xe0, 0xb0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x1, 0x0, 0x31, 0x36, 0x35, 0x33, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x34, 0x32, 0x39, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x31, 0x38, 0x31, 0x37, 0x30, 0x34, 0x34, 0x33, 0x36, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x34, 0x31, 0x37, 0x30, 0x34, 0x34, 0x33, 0x31, 0x32, 0x31, 0x38, 0x32, 0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x38, 0x36, 0x30, 0x31, 0x31, 0x39, 0x30, 0x31, 0x30, 0x30, 0x30, 0x44, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x36, 0x39, 0x39, 0x39, 0x39, 0x30, 0x31, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x31, 0x34, 0x30, 0x36, 0x30, 0x31, 0x32, 0x38, 0x4d, 0x54, 0x46, 0x20, 0x54, 0x45, 0x53, 0x54, 0x41, 0x42, 0x43, 0x31, 0x32, 0x33, 0x54, 0x45, 0x53, 0x54, 0x4d, 0x54, 0x46, 0x31, 0x39, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x46, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x20, 0x20, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x46, 0x38, 0x34, 0x30, 0x38, 0x34, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x38, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x4d, 0x41, 0x50, 0x49, 0x4d, 0x41, 0x53, 0x54, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x38, 0x31, 0x31, 0x36, 0x34, 0x33, 0x30, 0x37, 0x38, 0x55, 0x44, 0x30, 0x37, 0x33, 0x43, 0x49, 0x30, 0x34, 0x35, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x32, 0x30, 0x31, 0x30, 0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x34, 0x30, 0x31, 0x32, 0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x36, 0x30, 0x31, 0x32, 0x30, 0x37, 0x30, 0x31, 0x32, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x43, 0x53, 0x30, 0x30, 0x34, 0x33, 0x30, 0x38, 0x31, 0x41, 0x44, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x35, 0x39, 0x37, 0x31, 0x31, 0x31},
   168  	[]byte{0x30, 0x31, 0x30, 0x30, 0xf6, 0x7e, 0x44, 0x81, 0x2c, 0xe0, 0xa0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x1, 0x0, 0x31, 0x36, 0x35, 0x33, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x34, 0x32, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, 0x30, 0x30, 0x31, 0x32, 0x31, 0x34, 0x31, 0x38, 0x30, 0x36, 0x34, 0x30, 0x36, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, 0x33, 0x31, 0x38, 0x30, 0x36, 0x34, 0x30, 0x31, 0x32, 0x31, 0x34, 0x32, 0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x34, 0x35, 0x39, 0x39, 0x39, 0x39, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x36, 0x39, 0x39, 0x39, 0x30, 0x33, 0x37, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x36, 0x32, 0x30, 0x34, 0x32, 0x37, 0x30, 0x30, 0x4d, 0x54, 0x46, 0x20, 0x54, 0x45, 0x53, 0x54, 0x41, 0x42, 0x43, 0x31, 0x32, 0x33, 0x54, 0x45, 0x53, 0x54, 0x4d, 0x54, 0x46, 0x31, 0x39, 0x4d, 0x69, 0x73, 0x63, 0x20, 0x52, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x65, 0x67, 0x61, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x56, 0x38, 0x34, 0x30, 0x38, 0x34, 0x30, 0x30, 0x38, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x4d, 0x41, 0x50, 0x49, 0x4d, 0x41, 0x53, 0x54, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x38, 0x31, 0x31, 0x36, 0x34, 0x33, 0x30, 0x37, 0x38, 0x55, 0x44, 0x30, 0x37, 0x33, 0x43, 0x49, 0x30, 0x34, 0x35, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x32, 0x30, 0x31, 0x30, 0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x34, 0x30, 0x31, 0x32, 0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x43, 0x53, 0x30, 0x30, 0x34, 0x33, 0x30, 0x38, 0x31, 0x41, 0x44, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x35, 0x39, 0x36, 0x36, 0x33, 0x32},
   169  	[]byte{0x30, 0x31, 0x30, 0x30, 0xf2, 0x3a, 0x44, 0x81, 0x2c, 0xe0, 0x93, 0x10, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x1, 0x0, 0x31, 0x36, 0x35, 0x33, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x32, 0x35, 0x31, 0x34, 0x32, 0x35, 0x34, 0x35, 0x39, 0x32, 0x32, 0x32, 0x37, 0x34, 0x31, 0x37, 0x32, 0x37, 0x30, 0x39, 0x30, 0x35, 0x32, 0x35, 0x30, 0x35, 0x32, 0x35, 0x36, 0x30, 0x31, 0x31, 0x30, 0x35, 0x31, 0x30, 0x30, 0x32, 0x30, 0x36, 0x39, 0x39, 0x39, 0x39, 0x30, 0x35, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x31, 0x34, 0x35, 0x31, 0x39, 0x39, 0x32, 0x32, 0x32, 0x37, 0x34, 0x30, 0x35, 0x34, 0x32, 0x35, 0x34, 0x30, 0x30, 0x30, 0x37, 0x37, 0x38, 0x31, 0x30, 0x30, 0x30, 0x30, 0x37, 0x37, 0x38, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x54, 0x4d, 0x20, 0x4e, 0x45, 0x4f, 0x50, 0x41, 0x4c, 0x49, 0x4d, 0x4f, 0x56, 0x53, 0x4b, 0x59, 0x20, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x4d, 0x4f, 0x53, 0x43, 0x4f, 0x57, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x55, 0x36, 0x34, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x38, 0x38, 0x9f, 0x26, 0x8, 0x33, 0xe, 0xc5, 0x84, 0x6d, 0x83, 0xa4, 0xea, 0x9f, 0x10, 0x12, 0x1, 0x10, 0xa0, 0x0, 0x3, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x9f, 0x37, 0x4, 0x76, 0x40, 0x6, 0x37, 0x9f, 0x36, 0x2, 0x0, 0x5d, 0x95, 0x5, 0x80, 0x0, 0x4, 0x0, 0x0, 0x9a, 0x3, 0x17, 0x5, 0x25, 0x9c, 0x1, 0x1, 0x9f, 0x2, 0x6, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x5f, 0x2a, 0x2, 0x9, 0x78, 0x82, 0x2, 0x39, 0x0, 0x9f, 0x1a, 0x2, 0x6, 0x43, 0x9f, 0x33, 0x3, 0x60, 0x40, 0x20, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x34, 0x32, 0x33, 0x30, 0x38, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x4f, 0x43, 0x54, 0x49, 0x44, 0x48, 0x49, 0x31, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x31, 0x31, 0x36, 0x34, 0x33, 0x30, 0x36, 0x32, 0x55, 0x44, 0x30, 0x35, 0x37, 0x43, 0x49, 0x30, 0x34, 0x35, 0x30, 0x31, 0x30, 0x31, 0x32, 0x30, 0x32, 0x30, 0x31, 0x30, 0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x34, 0x30, 0x31, 0x32, 0x30, 0x35, 0x30, 0x31, 0x32, 0x30, 0x36, 0x30, 0x31, 0x32, 0x30, 0x37, 0x30, 0x31, 0x32, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x43, 0x53, 0x30, 0x30, 0x32, 0x34, 0x31},
   170  	[]byte{0x30, 0x34, 0x32, 0x31, 0xf6, 0x38, 0x44, 0x81, 0xe, 0xe0, 0xa1, 0x18, 0x0, 0x0, 0x0, 0x42, 0x14, 0x0, 0x1, 0x0, 0x31, 0x36, 0x35, 0x33, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x31, 0x33, 0x31, 0x34, 0x33, 0x36, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x34, 0x31, 0x33, 0x35, 0x32, 0x35, 0x33, 0x30, 0x35, 0x31, 0x36, 0x36, 0x30, 0x31, 0x30, 0x39, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x36, 0x39, 0x39, 0x39, 0x39, 0x30, 0x35, 0x37, 0x31, 0x33, 0x36, 0x31, 0x39, 0x39, 0x30, 0x39, 0x34, 0x34, 0x38, 0x30, 0x35, 0x38, 0x31, 0x33, 0x32, 0x30, 0x30, 0x38, 0x30, 0x31, 0x31, 0x30, 0x30, 0x30, 0x31, 0x38, 0x30, 0x31, 0x31, 0x30, 0x30, 0x30, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x4c, 0x20, 0x4f, 0x46, 0x46, 0x49, 0x43, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x55, 0x36, 0x34, 0x33, 0x36, 0x34, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x39, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x34, 0x30, 0x36, 0x31, 0x33, 0x31, 0x34, 0x33, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x39, 0x39, 0x39, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x4f, 0x43, 0x54, 0x49, 0x44, 0x48, 0x49, 0x31, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x31, 0x31, 0x36, 0x34, 0x33, 0x30, 0x36, 0x37, 0x55, 0x44, 0x30, 0x36, 0x32, 0x43, 0x49, 0x30, 0x34, 0x35, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x32, 0x30, 0x31, 0x30, 0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x34, 0x30, 0x31, 0x30, 0x30, 0x35, 0x30, 0x31, 0x30, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x31, 0x30, 0x49, 0x52, 0x30, 0x30, 0x30, 0x43, 0x53, 0x30, 0x30, 0x32, 0x34, 0x31},
   171  }
   172  
   173  func payload8583(messages ...[]byte) []byte {
   174  	var s []byte
   175  	for _, msg := range messages {
   176  		msgLen := make([]byte, 2)
   177  		binary.BigEndian.PutUint16(msgLen, uint16(len(msg)))
   178  		s = append(s, append(msgLen, msg...)...)
   179  	}
   180  	return s
   181  }
   182  
   183  type tsysMessage struct {
   184  	MTI                                string `iso8583:"MTI"`
   185  	PrimaryAccountNumber               string `iso8583:"2"`
   186  	ProcessingCode                     string `iso8583:"3"`
   187  	AmountOrig                         string `iso8583:"4"`
   188  	Amount                             string `iso8583:"6"`
   189  	TransmissionDateTime               string `iso8583:"7"`
   190  	BillingRate                        string `iso8583:"10"`
   191  	TraceNumber                        string `iso8583:"11"`
   192  	LocalTime                          string `iso8583:"12"`
   193  	LocalDate                          string `iso8583:"13"`
   194  	DateExpiration                     string `iso8583:"14"`
   195  	DateSettlement                     string `iso8583:"15"`
   196  	DateCapture                        string `iso8583:"17"`
   197  	MerchantType                       string `iso8583:"18"`
   198  	AcquiringInstitutionCountryCode    string `iso8583:"19"`
   199  	POSDataCode                        string `iso8583:"22"`
   200  	PointOfServiceConditionCode        string `iso8583:"25"`
   201  	TransactionFee                     string `iso8583:"28"`
   202  	ONLINEIssuerAuthorizationFeeAmount string `iso8583:"31"`
   203  	AcquirerInstitutionID              string `iso8583:"32"`
   204  	TrackData                          string `iso8583:"35"`
   205  	RetrievalReference                 string `iso8583:"37"`
   206  	AuthIDCode                         string `iso8583:"38"`
   207  	RespCode                           string `iso8583:"39"`
   208  	CardAccptrTermnlID                 string `iso8583:"41"`
   209  	CardAccptrIDCode                   string `iso8583:"42"`
   210  	CardAccptrNameLoc                  string `iso8583:"43"`
   211  	AdditionalResponseData             string `iso8583:"44"`
   212  	CurrencyOrig                       string `iso8583:"49"`
   213  	Currency                           string `iso8583:"51"`
   214  	PersonalIdentificationNumberData   string `iso8583:"52"`
   215  	SecurityRelatedControlInformation  string `iso8583:"53"`
   216  	AddtnlAmounts                      string `iso8583:"54"`
   217  	ICCRelatedData                     string `iso8583:"55"`
   218  	OriginalDataSerials                string `iso8583:"56"`
   219  	AdditionalInformation              string `iso8583:"60"`
   220  	OtherAmtTrans                      string `iso8583:"61"`
   221  	NetworkManagementInformationCode   string `iso8583:"70"`
   222  	BusinessDate                       string `iso8583:"73"`
   223  	OrigDataElemts                     string `iso8583:"90"`
   224  	NumberOfAccounts                   string `iso8583:"93"`
   225  	QuerySequence                      string `iso8583:"94"`
   226  	ReplacementAmount                  string `iso8583:"95"`
   227  	MoreFlag                           string `iso8583:"99"`
   228  	MessageOriginator                  string `iso8583:"100"`
   229  	AccountFrom                        string `iso8583:"102"`
   230  	AccountTo                          string `iso8583:"103"`
   231  	PrivateData                        string `iso8583:"104"`
   232  	AdditionalInformationPart2         string `iso8583:"116"`
   233  	AdditionalAmountAccountTo          string `iso8583:"117"`
   234  	AdditionalInformationPart1         string `iso8583:"120"`
   235  	Transfercurrencies                 string `iso8583:"122"`
   236  	CardholderUtilityAccount           string `iso8583:"125"`
   237  	PrivateUseFields                   string `iso8583:"126"`
   238  }