Coder Social home page Coder Social logo

zemuldo / iso_8583 Goto Github PK

View Code? Open in Web Editor NEW
85.0 5.0 49.0 3.82 MB

:credit_card::moneybag: JavaScript library for iso 8583 messaging. Handles message validation & conversion between interfaces using iso 8583 standard. Contributors are welcome.

Home Page: https://zemuldo.github.io/iso_8583/

License: MIT License

JavaScript 5.67% TypeScript 94.33%
iso8583 tcpmessage iso card node 8583

iso_8583's Introduction

ISO_8583

Greenkeeper badgeTravis CI build badgeKnown Vulnerabilities

ISO_8583 is a Customizable ISO 8583 Library for JavaScript and NodeJS that does message conversion between a system and an interface that exchange ISO 8583 Financial transaction card originated messages.

Install from npm using

npm install --save iso_8583

OR

yarn add iso_8583

Basic Usage: Bitmap Messaging

See the a sample usage example see this example

const iso8583 = require('iso_8583');
let data = {
    0: "0100",
    2: "4761739001010119",
    3: "000000",
    4: "000000005000",
    7: "0911131411",
    12: "131411",
    13: "0911",
    14: "2212",
    18: "4111",
    22: "051",
    23: "001",
    25: "00",
    26: "12",
    32: "423935",
    33: "111111111",
    35: "4761739001010119D22122011758928889",
    41: "12345678",
    42: "MOTITILL_000001",
    43: "My Termianl Business                    ",
    49: "404",
    52: "7434F67813BAE545",
    56: "1510",
    123: "91010151134C101",
    127: "000000800000000001927E1E5F7C0000000000000000500000000000000014A00000000310105C000128FF0061F379D43D5AEEBC8002800000000000000001E0302031F000203001406010A03A09000008CE0D0C840421028004880040417091180000014760BAC24959"
};

let customFormats = {
    '3': {
      ContentType: 'n',
      Label: 'Processing code',
      LenType: 'fixed',
      MaxLen: 9
    }
  };

let isopack = new iso8583(data,customFormats);

The object initialized has the following methods:

To validate the iso message
isopack.validateMessage();  // returns true for valid message or error
To get the mti as a string:
isopack.getMti(); // returns a 4 byte buffer containing the mti
To get the bitmaps in binary:
isopack.getBmpsBinary(); // returns a string '1111001000111..' or an error object with error prop
To get the bitmap active fields:
isopack.getBitMapFields(); 
// returns the array of enabled fields in bitmap, excluding MTI and bitmap fields
// e.g. [2, 3, 4, 7, 12, 13, 14, 18, 22, 23, 25, 26, 32, 33, 35, 41, 42, 43, 49, 52, 56, 123, 127]
To get the bitmaps in hex for fields 0-127, fields 127 extensions and fields 127.25 extensions
isopack.getBitMapHex();             // returns 'f23c46c1a8e091000000000000000022'
isopack.getBitMapHex_127_ext();     // returns '8000008000000000'
isopack.getBitMapHex_127_ext_25();  // returns 'fe1e5f7c00000000'

// in case of error, the error object returned with error prop
To get a raw message:
let bufferMessage = isopack.getRawMessage(); 
// returns a buffer containing the message (without 2-byte length field) or an error object
<Buffer 30 31 30 30 f2 3c 46 c0 20 e8 80 00 00 00 00 00 00 00 00 20 30 37 35 34 ...
To get a buffer tcp message to send to the ISO 8583 Interface:
let bufferMessage = isopack.getBufferMessage(); 
// returns a buffer containing the message with 2 additional bytes indicating the length 
// or an error object
<Buffer 01 11 30 31 30 30 f2 3c 46 c0 20 e8 80 00 00 00 00 00 00 00 00 20 30 37 35 34 ...
To get the field description:
const iso8583 = require('iso_8583');
iso8583.getFieldDescription(24);
// The object with field descriptions to be returned:
// {24: 'Network International identifier (NII)'}

To get the several fields descriptions:

const iso8583 = require('iso_8583');
iso8583.getFieldDescription([24, 37, 39]);
// The object with field descriptions to be returned:
// {
//    24: 'Network International identifier (NII)'},
//    37: 'Retrieval reference number', 
//    39: 'Response code'
// }

To unpack a message from the interface, that usually comes in a tcp stream/buffer just parse the incoming buffer or string to the method

let incoming = new isopack().getIsoJSON(incoming);
// returns parsed json object:
let testData = {
    "0": "0100",
    "2": "5413330",
    "3": "000000",
    "4": "000000002000",
    "7": "0210160607",
    "11": "148893",
    "12": "160607",
    "13": "0210",
    "14": "2512",
    "18": "4111",
    "22": "141",
    "23": "003",
    "25": "00",
    "26": "12",
    "35": "5413330089020011D2512601079360805F",
    "41": "31327676",
    "42": "4D4F424954494C4",
    "43": "My Termianl Business                    ",
    "49": "404",
    "45": "0303030204E4149524F4249204B452dataString04B45",
    "123": "09010001000105010103040C010001"
};

Basic Usage: XML Messaging

To get xml from a json

Initialize the iso object with the json as argument

let isoPack = new isoPack(testData);
isoPack.getXMLString();     // returns a string of iso 8583 xml string

To get json form the xml string

let isoPack = new isoPack();    // Initialize with no argument

Parse the string to the method to get the iso json

let xmlData = '<?xml version="1.0" encoding="UTF-8"?>\n' +
    '<Iso8583PostXml>\n' +
    '<MsgType>0200</MsgType>\n' +
    '<Fields>\n' +
    '<Field_002>4839123456709012</Field_002>\n' +
    '<Field_003>000000</Field_003>\n' +
    '<Field_004>000000001500</Field_004>\n' +
    '<Field_007>0604074705</Field_007>\n' +
    '<Field_011>804058</Field_011>\n' +
    '<Field_012>074808</Field_012>\n' +
    '<Field_013>0604</Field_013>\n' +
    '<Field_014>0812</Field_014>\n' +
    '<Field_015>0905</Field_015>\n' +
    '<Field_022>901</Field_022>\n' +
    '<Field_025>02</Field_025>\n' +
    '<Field_026>05</Field_026>\n' +
    '<Field_028>000000500</Field_028>\n' +
    '<Field_030>000000500</Field_030>\n' +
    '<Field_032>483912</Field_032>\n' +
    '<Field_035>4839123456709012=08125876305082011</Field_035>\n' +
    '<Field_037>D000A0030000</Field_037>\n' +
    '<Field_040>507</Field_040>\n' +
    '<Field_041>FOFUGUT1</Field_041>\n' +
    '<Field_042>191121119111112</Field_042>\n' +
    '<Field_043>Postilion Cafeteria Rondebosch ZA</Field_043>\n' +
    '<Field_049>710</Field_049> <Field_056>1510</Field_056>\n' +
    '<Field_059>0000000072</Field_059>\n' +
    '<Field_123>211401213041013</Field_123>\n' +
    '<Field_127_002>0007713856</Field_127_002>\n' +
    '<Field_127_009>013040604040604016501100330000</Field_127_009>\n' +
    '<Field_127_012>My Terminal Business</Field_127_012>\n' +
    '<Field_127_020>20100604</Field_127_020>\n' +
    '</Fields>\n' +
    '</Iso8583PostXml>';

isoPack.getJsonFromXml(xmlData); // returns a json object or an error object

Usage: MTI converting

Changing current mti type

Initialize the iso object with the json as argument

  let data = {
    0: '0400',
    2: '4761739001010119',
    3: '000000',
    4: '000000005000',
    7: '0911131411'
  };

  let isopack = new isoPack(data);
  isoPack.toRetransmit()
  isoPack.getMti(); // returns '0401'
  
  isopack = new isoPack(data);
  isoPack.toResponse(); 
  isoPack.getMti(); // returns '0410'
  
  isopack = new isoPack(data);
  isoPack.toAdvice(); 
  isoPack.getMti(); // returns '0420'
  

There are other cool stuff like isoPack.attachTimeStamp() which adds times stamps to field 7,12,13, plus more When working with xml, first change the xml to json then validate.

Configuration and Customization

Custom ISO 8583 Formats.

This library Supports custom ISO 8583 Formats, versions 1993 and 2003. This means you can decide what data types are allowed on each field, the length properties of the field and its description. Custom ISO 8583 formats must be passed in the format below.

{
      'FIELD_NAME': {
        ContentType: 'Types accepted',
        Label: 'Description of the field',
        LenType: 'Length type can bee fixed or lvar ...',
        MaxLen: Maximum length (number)
      }
    }

Here is an example of custom format for field 3. You can refer to formats in the docs to see the default formats.

let customFormats = {
    '3': {
      ContentType: 'n',
      Label: 'Processing code',
      LenType: 'fixed',
      MaxLen: 9
    }
  };

Required fields

You can also set required field for message types as you desire. To use required fields you need to create a json config file and add to the class when creating a new message class, thats two ways works:

let isopack = new iso8583(iso);
isopack.requiredFieldsSchema = './config/required-fields.json';
const required_fields = './config/required-fields.json';
let isopack = new iso8583(iso, customFormats, required_fields);

And at the config file you can organize by process code and by messages codes, like this:

[
  {
    "processing_code": "000000",
    "required_fields": [0, 2, 4]
  },
  {
    "processing_code": "999999",
    "required_fields":[
      {
        "0100": [3, 7],
        "0500": [3, 7, 11]
      }
    ]
  }
]

Message Packaging and Un-packaging

This library uses a default mode of message encoding and packaging. If you are using a third party message source or a third party packaging source, you have to pre-format your data to meet the default encoding or configure things for yourself. See configuration for more info.

Unpacking

This only applies when you are receiving messages from others sources that don't encode as per this library like JPos. Default unpack conditions:

2-byte leng header in hex + 4-byte MTI encoded in utf8 + 16-byte Bitmap encoded in hex

If the message you are receiving is in a different state, the passing config to getIsoJSON like below.

Packing

Messages are packaged as:

  • 2 byte length indicator + 4 byte message type + 16 byte bitmap(primary + secondary bitmap) + message field data.
  • Each field with variable length data is preceded with the actual length of the data in that field.
Field 127 and 127.25

The library extends fields 127 and fields 127.25 to their sub fields.
If you are handling a json with field 127 or 127.25 as one string, the bitmap must be 16 character string then a 4 digit number indicating the length In the above case the library will expand them.
If they are already broken down to subfields, nothing changes.
To invoke the package initialize with the iso8583 json or object as argument. If the json contains any fields not defined in iso8583 or has no field 0, the error is returned in an object.
If you want to handle xml iso 8583 messages, the usage is described down there.

Thanks , Have Fun

iso_8583's People

Contributors

dependabot[bot] avatar ekoeryanto avatar greenkeeper[bot] avatar kunalmaveric avatar lucasinocente avatar msaadsiddiqui avatar pawelpalka avatar pawelpalka81 avatar timgabets avatar zemuldo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

iso_8583's Issues

BUG: Suspecting a bug in checking binary fields length

When we check the length of a binary field, we compare the binary length directly with the length of the incoming value, which is in hex.

   if (this_format.ContentType === 'b') {
              if (this_format.MaxLen  === this.Msg[field].length) {    // this.Msg[field] is in hex format and this_format.MaxLen is in bytes
                const size = this_format.MaxLen / 2;
                const thisBuff = Buffer.alloc(size, this.Msg[field], 'hex');
                buff = Buffer.concat([buff, thisBuff]);
    ...

This should be

   if (this_format.ContentType === 'b') {
              if (this_format.MaxLen * 2  === this.Msg[field].length) {    // multiplied with 2 to make a byte with couple of hex characters 
                const size = this_format.MaxLen / 2;
                const thisBuff = Buffer.alloc(size, this.Msg[field], 'hex');
                buff = Buffer.concat([buff, thisBuff]);
    ...

Let me know if any further details necessary

Secondary Bitmap - exclusion

Hi, Zemuldo. First of all, thanks for sharing this useful library, it's been of great help for us.

We've been looking forward for an enhancement, maybe we don't know your initial use case, but we see that library always includes the secondary bitmap, altough all bytes are set to 0 (no fields present from field 65 to 127).

We think we can check for the presence of fields 65 to 127 in the assembleBitmap.js#assembleBitmap function and avoid hardcoding always the presence of the secondary bitmap _map[0] = 1; line 14.

We'll be working on a POC to see how this behaves for us, let us know if you have some feedback.

x8xx (Network Management) messages are treated as invalid

let data = { 
0: '0100' ,
2: '4761739001010119'
};
let isopack = new iso8583(data);
isopack.validateMessage(); 
> true
let data = { 
0: '0800',
70: '001'
};
let isopack = new iso8583(data);
isopack.validateMessage(); 
> false

x8xx messages are the part of ISO8583 as well, and must pass validateMessage() check.

Feature Request

Hi. First off. this is an awesome library. thank you very much for you hard work on this. it is amazing.

i would like to log 4 feature requests. i believe it would help quite a bit with the library.
the first would be to initialize the ISOPack library with a buffer. the current solution only allows it to be created via JSON as per your basic usage example.
the current way i use this is as per below

  const jsonData = new iso8583().getIsoJSON(bufferData);
  const isopack = new iso8583(jsonData);

this would allow me to perform functions on the message

the second request would be to set fields to whatever i want. the current use case i have would be for example to set the response code. i have copied your attachTimeStamp function and updated the magic sauce to below.

this.Msg['39'] = code

it would be useful to do this with other fields as well.

the third request would be to show the contents of a specific field. i have added the below function to do that.

getField(field) {
    if (this.Msg[field]) return this.Msg[field]
    else return T.toErrorObject(['field not defined in message']);
  }

the last request would be to decode 127.22
this is a postilion specific request. the field works much like 127.25

An in-range update of date-fns is breaking the build 🚨

The dependency date-fns was updated from 1.29.0 to 1.30.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

date-fns is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Custom Format Support - variable binary field within first 127 fields

First thanks for this awesome library.
I am using this for some IFSF messages encode/decode at client side application.
i have some custom requirement t support subfields at 48 position. It has bitmap + 48.1, 48.2, 48.3 ... very much same as 127.25
i can not use "LLLVAR ans" because it is at host side the field content is treated as binary similar to fixed binary field.

here is test case attached for the above requirement.

import test from 'ava';
import iso8583 from '../lib/8583.js';

/*
Support custom iso 8583 formats
Support Case: Binary var field encode decode
*/
test('iso8583 Ext - binary var field must be encoded', t => {
  const format = {
    2: {
      ContentType: 'b',
      Label: 'F1',
      LenType: 'llvar',
      MaxLen: 99
    },
        
  };
  const data = {
    0: '0800',
    '2': '1004000000000000303030303030303030343048' 
    // #2 is prepard by encodng subfields - 8bytes bitmap followed by subfields data
  };
  let isopack = new iso8583(data, format);
  let buff = isopack.getRawMessage();
  const iso1 = new iso8583(undefined, format).getIsoJSON(buff, {lenHeader: false});
  t.deepEqual(iso1, data);
  let isopack1 = new iso8583(iso1);
  t.is(isopack1.Msg['2'], '1004000000000000303030303030303030343048');
});

Use Fixe Header

Hi @zemuldo,
Hope you are doing well.
First of all I want to congratulate you for the work done.

In addition, is it possible to use string fixed header concatenated at the beginning of the message just after the size?

for example : msgLength+fixedHeader+Msg

Typescript

I noticed the current main is written in typescript with a beta 3 version. The newest version released is 2.6.7, and not written in typescript. Is there a timeline for releasing 3.0? Is there anything I can do to help get it there?

User-defined ISO8583 formats support

As we all know, there are tons of different flavours of ISO8583, but currently the format specification is harcoded in formats.js

I think it would be generally a good idea to implement a user-defined ISO8583 customizations support in the library. Probably, from the user's point of view it may look like this:

// Create the new ISO8583 format, which will be exact the same 
// as the default one from lib/formats.js, 
// but with the different DE12 (n6 type changed to n12):
let format = {
  12: {
        ContentType: "n",
        Label: "Time, local transaction (hhmmss)",
        LenType: "fixed",
        MaxLen: 12
    },
}
let isopack = new iso8583(data, format);

I think this will make the library more flexible and customizable.

Any thoughts/ideas are welcome ;)

If you are okay with that, I'll start the development soon.

Response to received data from socket

Hi
How can I parseJPOS XMLPackage data receiving from the socket?
I have problems with iso_8583.

const net = require('net');
const iso8583 = require('iso_8583');

const port = 7070;
const host = '127.0.0.1';

net.createServer(function(socket) {
    console.log('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort);
    socket.on('data', function(data) {
        // ********* Problem is here. Below Line ***********
        var isopack = new iso8583().isoPack(data).getXMLString();
        // ********* And how to change MTI ***********
        isopack.console.log('DATA ' + socket.remoteAddress + ': ' + data);
        socket.write('You said "' + isopack + '"');
    });
    socket.on('close', function() {
        console.log('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort);
    });
}).listen(port, host);

console.log('Server listening on ' + host + ':' + port);

I couldn't parse received data from the socket and change MTI.
How Can i do this?
Thanks.

Bitmap 32

Hello, how can i use .getISOJson() to convert iso with 32 bitmap?

Invalid x+n type

input :

<?xml version="1.0" encoding="UTF-8"?>
<Iso8583PostXml>
<MsgType>0200</MsgType>
<Fields>
<Field_002>4839123456709012</Field_002>
<Field_003>000000</Field_003>
<Field_004>000000001500</Field_004>
<Field_007>0604074705</Field_007>
<Field_011>804058</Field_011>
<Field_012>074808</Field_012>
<Field_013>0604</Field_013>
<Field_014>0812</Field_014>
<Field_015>0905</Field_015>
<Field_022>901</Field_022>
<Field_025>02</Field_025>
<Field_026>05</Field_026>
<Field_028>000000500</Field_028>
<Field_030>000000500</Field_030>
<Field_032>483912</Field_032>
<Field_035>4839123456709012=08125876305082011</Field_035>
<Field_037>D000A0030000</Field_037>
<Field_040>507</Field_040>
<Field_041>FOFUGUT1</Field_041>
<Field_042>191121119111112</Field_042>
<Field_043>Postilion Cafeteria Rondebosch ZA</Field_043>
<Field_049>710</Field_049> <Field_056>1510</Field_056>
<Field_059>0000000072</Field_059>
<Field_123>211401213041013</Field_123>
<Field_127_002>0007713856</Field_127_002>
<Field_127_009>013040604040604016501100330000</Field_127_009>
<Field_127_012>My Terminal Business</Field_127_012>
<Field_127_020>20100604</Field_127_020>
</Fields>
</Iso8583PostXml>

Current Output

  • {error: "while processing field 28: provided data is not of type 'x+n'"}

Expected Result

  • Parsed ISO 8583 Valid Format

Any comment would be appreciate.

while starting server in the example

getting error while starting server "npm run t"

Error: Cannot find module 'jxon'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object. (C:\Users\akulkarni\Documents\iso_8583-master\lib\8583.js:3:14)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)

tried re installing packages still not working

An in-range update of eslint is breaking the build 🚨

The devDependency eslint was updated from 5.15.3 to 5.16.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v5.16.0
  • dfef227 Build: gensite passes rulesMeta to formatter rendering (#11567) (Kevin Partington)
  • c06d38c Fix: Allow HTML formatter to handle no meta data (#11566) (Ilya Volodin)
  • 87a5c03 Docs: func-style: clarify when allowArrowFunctions is used (#11548) (Oliver Joseph Ash)
  • bc3e427 Update: pass rule meta to formatters RFC 10 (#11551) (Chris Meyer)
  • b452f27 Chore: Update README to pull in reviewer data (#11506) (Nicholas C. Zakas)
  • afe3d25 Upgrade: Bump js-yaml dependency to fix Denial of Service vulnerability (#11550) (Vernon de Goede)
  • 4fe7eb7 Chore: use nyc instead of istanbul (#11532) (Toru Nagashima)
  • f16af43 Chore: fix formatters/table test (#11534) (Toru Nagashima)
  • 78358a8 Docs: fix duplicate punctuation in CLI docs (#11528) (Teddy Katz)
Commits

The new version differs by 11 commits.

  • ded2f94 5.16.0
  • ea36e13 Build: changelog update for 5.16.0
  • dfef227 Build: gensite passes rulesMeta to formatter rendering (#11567)
  • c06d38c Fix: Allow HTML formatter to handle no meta data (#11566)
  • 87a5c03 Docs: func-style: clarify when allowArrowFunctions is used (#11548)
  • bc3e427 Update: pass rule meta to formatters RFC 10 (#11551)
  • b452f27 Chore: Update README to pull in reviewer data (#11506)
  • afe3d25 Upgrade: Bump js-yaml dependency to fix Denial of Service vulnerability (#11550)
  • 4fe7eb7 Chore: use nyc instead of istanbul (#11532)
  • f16af43 Chore: fix formatters/table test (#11534)
  • 78358a8 Docs: fix duplicate punctuation in CLI docs (#11528)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Bitmap Length

Hello there, I have an issue here.
I'm trying to unpack a message which consisted of something like this:
4-byte MTI encoded in utf8 + 16-byte Bitmap encoded in hex + Message Field Data
Which fairly refer to this Wikipedia
"The bitmap may be represented as 8 bytes of binary data or as 16 hexadecimal characters (0–9, A–F) in the ASCII or EBCDIC character sets."

Thus, I got an ISO8583 string like this:
0200 + F23A400108E1800E + [Message Field Data]
I have used the config for { lenHeader: false }.
However, when I tried to unpack the messages, I don't get any error, but the unpacked messages aren't the expected result.
Here's the result I get:

{ '0': '0200',
  '2': 'E1800E00',
....
}

The 'E1800E' part that should be included in Bitmaps is parsed to the second bit of the messages.
I noticed that it might have something to do in unpack_0_127.js snippet which states

// Does data contain a secondary bitmap?
    const secondaryBitmap = this.hasSecondaryBitmap(
      incoming.slice(4, 8),
      config
    );
    if (secondaryBitmap === false) bitmapEnd = 12;
    else bitmapEnd = 20;

I wonder is there any config that I miss regarding the expected result?

Field 127.25 - Integrated circuit card (ICC) Data - XML support

Request to add a feature for xml support in field 127.25

The current implementation creates subfields of 127.25 from the data received in field 127. If a subfield is sent separately and not in HEX, the lib breaks.

Example:
The following data works well:
All subfields are derived from the hex in field 127.

{
  "0": "0200",
  "2": "4761735683548903",
  "3": "000000",
  "4": "000000007834",
  "11": "0000002",
  "14": "2009",
  "18": "7659",
  "22": "051",
  "23": "001",
  "25": "00",
  "26": "12",
  "32": "108600",
  "41": "12000014",
  "42": "TERMINAL_DIGITA",
  "43": "TERMINAL BUSINESS 1 0000000 TEXASUS US  ",
  "49": "404",
  "56": "1510",
  "123": "51010151134C101",
  "127": "000000800000000001567C19517C0000000000000000247900000000000014A00000000310105800BE925"
  }

The elements of subfield 127.25 are parsed correctly because data is in HEX format.

When field 127.25 is sent separately(not parsed from 127) and as XML, parsing breaks

{
  "0": "0200",
  "2": "4761735683548903",
  "3": "000000",
  "4": "000000007834",
  "11": "0000002",
  "14": "2009",
  "18": "7659",
  "22": "051",
  "23": "001",
  "25": "00",
  "26": "12",
  "32": "108600",
  "41": "12000014",
  "42": "TERMINAL_DIGITA",
  "43": "TERMINAL BUSINESS 1 0000000 TEXASUS US  ",
  "49": "404",
  "56": "1510",
  "123": "51010151134C101",
  "127.25": "<IccData><IccRequest><AmountAuthorized>000000002341</AmountAuthorized><AmountOther>000000000000</AmountOther><ApplicationIdentifier>14A0000000031010</ApplicationIdentifier><ApplicationInterchangeProfile>5000</ApplicationInterchangeProfile><ApplicationTransactionCounter>0008</ApplicationTransactionCounter><Cryptogram>D17AC224D703ED03</Cryptogram><CryptogramInformationData>80</CryptogramInformationData><InterfaceDeviceSerialNumber>3332303030303632</InterfaceDeviceSerialNumber><IssuerApplicationData>1406011203A09800</IssuerApplicationData><TerminalApplicationVersionNumber>0096</TerminalApplicationVersionNumber><TerminalVerificationResult>4280000800</TerminalVerificationResult><TransactionCurrencyCode>404</TransactionCurrencyCode><TransactionDate>201008</TransactionDate><TransactionSequenceCounter>800000144</TransactionSequenceCounter><TransactionType>00</TransactionType><UnpredictableNumber>9FACCF09</UnpredictableNumber></IccRequest></IccData>"
}

Below is the stack trace

TypeError: Cannot read property 'LenType' of undefined
   at Main.rebuildExtensions_127_25 (/home/acc/example/node_modules/iso_8583/lib/8583.js:333:27)
   at Main.rebuildExtensions (/home/acc/example/node_modules/iso_8583/lib/8583.js:402:17)
   at Main.module.exports (/home/acc/example/node_modules/iso_8583/lib/pack/assemble127_extensions.js:13:20)
   at Main.assemble0_127_Fields (/home/acc/example/node_modules/iso_8583/lib/pack/assemble0_127_Fields.js:40:38)
   at Main.getBufferMessage (/home/acc/example/node_modules/iso_8583/lib/8583.js:584:30)

Solution suggestion:
If field 127.25 is sent/present it should be left as is

Thanks.

Don't parse field 127.X, only 127 as a string

Is your feature request related to a problem? Please describe.
We are receiving ISO messages where 127 is a complete custom string, and we are currently solving it by commenting out the code that parses field 127

Describe the solution you'd like
It would be great to be able to pass in a parameter to skip 127.x and only return 127 as a hex string

Describe alternatives you've considered
We currently have a fork where we have commented this code out. We would be happy to do a PR to implement this change if it is something you would be interested in supporting.

Additional context
You can check out our fork to see what we have commented about :)

4 UTF-8 string as indicator message length

First of all, thank you for this library. Help me a lot!!
Just wondering that how i can set indicator message length is using 4 utf8 string than using hex encoding for send and receive?
Thank you!

Nested TLV ISO fields

Just wondering if you have considered supporting nested TLV where a bitmap field is itself comprised of a set of TLV fields
An example would be found in this Elavon spec under Field 60
Elavon spec

Would be good if they were also externally configurable as currently implemented in your customFormats

Thanks

question about message length and bitmap size

After running som tests on "real world" messages I've got two questions:

  1. Message size (=length) is not part of the ISO standard but anyway sometimes found as a header before the message. The format of this header could differ, for example: not present, two bytes hex or four bytes ascii decimal. As far as I can see this implementation is using two bytes for message length:

let len1 = parseInt(buffer.slice(0,1).toString('hex'), 16);
let len2 = parseInt(buffer.slice(1,2).toString('hex'), 16);
let actualLen = (256*len1)+len2;
buffer = buffer.slice(2,buffer.byteLength);

Would be a nice feature if the message length header was optional or configurable.

  1. The ISO standard specifies bitmap size to 8, 16 or 24 bytes. First bit of bitmap is used to indicate if next bitmap is present. It seems like this implementation has hardcoded bitmap size to 16 bytes:

let bitmap = getHex(incoming.slice(4, 20).toString('hex')).split('').map(Number);

Description from Wikipedia

The bitmap may be represented as 8 bytes of binary data, or as sixteen hexadecimal characters (0-9, A-F) in the ASCII or EBCDIC character sets. A message will contain at least one bitmap, called the primary bitmap, which indicates which of data elements 1 to 64 are present. The presence of an optional secondary bitmap is also indicated by bit 1 of the primary bitmap. If present, the secondary bitmap indicates whether data elements 65 to 128 are present. Similarly, a tertiary bitmap can be used to indicate the presence of fields 129 to 192, although these data elements are rarely used.

Would it be possible to add support for one, two or three bitmaps according to the ISO standard?

TypeError: Cannot read properties of undefined (reading 'match')

Hello πŸ‘‹ @zemuldo
Your library is awesome. I am stuck having this error when I try to parse the json below

{
    "0": "0200",
    "2": "4761739001010465",
    "3": 501000,
    "4": 210000,
    "7": 202194610,
    "11": 116337,
    "12": 74610,
    "13": 202,
    "14": 2406,
    "15": 202,
    "18": 6014,
    "22": 51,
    "23": 1,
    "25": 0,
    "26": 4,
    "28": 0,
    "32": 424367,
    "35": "4761739001010465D25122011172745689",
    "37": "116337",
    "40": 226,
    "41": "2070597N",
    "42": "2TUPLA000000003",
    "43": "T LIFEs LINK        002424 2070597N LANG",
    "49": 566,
    "52": "****************",
    "56": 1510,
    "98": "87001511",
    "103": "87001511",
    "123": "1=15; 2=5; 3=1; 4=1; 5=1; 6=0; 7=1; 8=5; 9=1; 10=2; 11=3; 12=4; 13='4'; 14=1; 15=1",
    "123.1": 15,
    "123.2": 5,
    "123.3": 1,
    "123.4": 0,
    "123.5": 1,
    "123.6": 0,
    "123.7": 1,
    "123.8": 5,
    "123.9": 1,
    "123.10": 3,
    "123.11": 3,
    "123.12": 4,
    "123.13": "4",
    "123.14": 1,
    "123.15": 1,
    "127": "2='000000116337'; 3='                        002424002424            '; 22='221ThirdPartyBillPayment3125<ThirdPartyBillPayment><BillPaymentRequest><ReferenceId>1022436062</ReferenceId></BillPaymentRequest></ThirdPartyBillPayment>230ThirdPartyBillPaymentExtension3225<ThirdPartyBillPaymentExtension><BillPaymentRequestExtension><CustomerId>1022436062</CustomerId><ProductCode>5000000</ProductCode><ItemCode>08125438953</ItemCode></BillPaymentRequestExtension></ThirdPartyBillPaymentExtension>211MediaTotals3211<MediaTotals><Totals><Amount>99300000</Amount><Currency>566</Currency><MediaClass>Cash</MediaClass></Totals><Totals><Amount>0</Amount><Currency>000</Currency><MediaClass>Cards</MediaClass></Totals></MediaTotals>218Postilion:MetaData3141221ThirdPartyBillPayment111230ThirdPartyBillPaymentExtension111211MediaTotals111212MediaBatchNr111217AdditionalEmvTags111214AdditionalInfo111212MediaBatchNr16198916217AdditionalEmvTags3344<AdditionalEmvTags><EmvTag><TagId>50</TagId><TagValue>5645525645</TagValue></EmvTag><EmvTag><TagId>81</TagId><TagValue>004C4B40</TagValue></EmvTag><EmvTag><TagId>5F36</TagId><TagValue>00</TagValue></EmvTag><EmvTag><TagId>5F34</TagId><TagValue>02</TagValue></EmvTag><EmvTag><TagId>9B</TagId><TagValue>6800</TagValue></EmvTag></AdditionalEmvTags>214AdditionalInfo3449<AdditionalInfo><Transaction><OpCode> D B  CC</OpCode><BufferB>08125438953</BufferB><BufferC>1022436062</BufferC><CfgExtendedTrxType>9701</CfgExtendedTrxType><CfgReceivingInstitutionIDCode>011</CfgReceivingInstitutionIDCode></Transaction><Download><ATMConfigID>5006</ATMConfigID><AtmAppConfigID>5006</AtmAppConfigID><LoadsetGroup>FEP Wincor EMV+VISA</LoadsetGroup><DownloadApp>2020_HYOSUNG_DWNLD_SWT_ETZ_PAY</DownloadApp></Download></AdditionalInfo>'; 25='<?xml version=\"1.0\" encoding=\"UTF-8\"?> <IccData><IccRequest><AmountAuthorized>000000210000</AmountAuthorized><AmountOther>000000000000</AmountOther><ApplicationInterchangeProfile>3800</ApplicationInterchangeProfile><ApplicationTransactionCounter>002D</ApplicationTransactionCounter><Cryptogram>93E957223EF23846</Cryptogram><CryptogramInformationData>80</CryptogramInformationData><CvmResults>420300</CvmResults><IssuerApplicationData>06010A03A0A802</IssuerApplicationData><TerminalCapabilities>E040C8</TerminalCapabilities><TerminalCountryCode>566</TerminalCountryCode><TerminalType>22</TerminalType><TerminalVerificationResult>0000040000</TerminalVerificationResult><TransactionCurrencyCode>566</TransactionCurrencyCode><TransactionDate>220202</TransactionDate><TransactionType>00</TransactionType><UnpredictableNumber>39EB665C</UnpredictableNumber></IccRequest></IccData>'",
    "127.2": "'000000116337'",
    "127.3":"'                        002424002424            '",
    "127.22": "'221ThirdPartyBillPayment3125<ThirdPartyBillPayment><BillPaymentRequest><ReferenceId>1022436062</ReferenceId></BillPaymentRequest></ThirdPartyBillPayment>230ThirdPartyBillPaymentExtension3225<ThirdPartyBillPaymentExtension><BillPaymentRequestExtension><CustomerId>1022436062</CustomerId><ProductCode>5000000</ProductCode><ItemCode>08125438953</ItemCode></BillPaymentRequestExtension></ThirdPartyBillPaymentExtension>211MediaTotals3211<MediaTotals><Totals><Amount>99300000</Amount><Currency>566</Currency><MediaClass>Cash</MediaClass></Totals><Totals><Amount>0</Amount><Currency>000</Currency><MediaClass>Cards</MediaClass></Totals></MediaTotals>218Postilion:MetaData3141221ThirdPartyBillPayment111230ThirdPartyBillPaymentExtension111211MediaTotals111212MediaBatchNr111217AdditionalEmvTags111214AdditionalInfo111212MediaBatchNr16198916217AdditionalEmvTags3344<AdditionalEmvTags><EmvTag><TagId>50</TagId><TagValue>5645525645</TagValue></EmvTag><EmvTag><TagId>81</TagId><TagValue>004C4B40</TagValue></EmvTag><EmvTag><TagId>5F36</TagId><TagValue>00</TagValue></EmvTag><EmvTag><TagId>5F34</TagId><TagValue>02</TagValue></EmvTag><EmvTag><TagId>9B</TagId><TagValue>6800</TagValue></EmvTag></AdditionalEmvTags>214AdditionalInfo3449<AdditionalInfo><Transaction><OpCode> D B  CC</OpCode><BufferB>08125438953</BufferB><BufferC>1022436062</BufferC><CfgExtendedTrxType>9701</CfgExtendedTrxType><CfgReceivingInstitutionIDCode>011</CfgReceivingInstitutionIDCode></Transaction><Download><ATMConfigID>5006</ATMConfigID><AtmAppConfigID>5006</AtmAppConfigID><LoadsetGroup>FEP Wincor EMV+VISA</LoadsetGroup><DownloadApp>2020_HYOSUNG_DWNLD_SWT_ETZ_PAY</DownloadApp></Download></AdditionalInfo>'",
    "127.25": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <IccData><IccRequest><AmountAuthorized>000000210000</AmountAuthorized><AmountOther>000000000000</AmountOther><ApplicationInterchangeProfile>3800</ApplicationInterchangeProfile><ApplicationTransactionCounter>002D</ApplicationTransactionCounter><Cryptogram>93E957223EF23846</Cryptogram><CryptogramInformationData>80</CryptogramInformationData><CvmResults>420300</CvmResults><IssuerApplicationData>06010A03A0A802</IssuerApplicationData><TerminalCapabilities>E040C8</TerminalCapabilities><TerminalCountryCode>566</TerminalCountryCode><TerminalType>22</TerminalType><TerminalVerificationResult>0000040000</TerminalVerificationResult><TransactionCurrencyCode>566</TransactionCurrencyCode><TransactionDate>220202</TransactionDate><TransactionType>00</TransactionType><UnpredictableNumber>39EB665C</UnpredictableNumber></IccRequest></IccData>",
    "70": "001"
}

I have custom formats as below

let customFormats = {
    '123': {
        ContentType: 'ans',
        Label: 'Reserved for private use',
        LenType: 'llllllvar',
        MaxLen: 999999
    },
    '123.1': {
        ContentType: 'ans',
        Label: 'Len',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.2': {
        ContentType: 'ans',
        Label: 'Card data input capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.3': {
        ContentType: 'ans',
        Label: 'Cardholder authentication capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.4': {
        ContentType: 'ans',
        Label: 'Card capture capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.5': {
        ContentType: 'ans',
        Label: 'Operating environment',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.6': {
        ContentType: 'ans',
        Label: 'Cardholder is present',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.7': {
        ContentType: 'ans',
        Label: 'Card is present',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.8': {
        ContentType: 'ans',
        Label: 'Card data input mode',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.9': {
        ContentType: 'ans',
        Label: 'Cardholder authentication method',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.10': {
        ContentType: 'ans',
        Label: 'Cardholder authentication entity',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.11': {
        ContentType: 'ans',
        Label: 'Card data output capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.12': {
        ContentType: 'ans',
        Label: 'Terminal output capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.13': {
        ContentType: 'ans',
        Label: 'PIN capture capability',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.14': {
        ContentType: 'ans',
        Label: 'Terminal operator',
        LenType: 'fixed',
        MaxLen: 15
    },
    '123.15': {
        ContentType: 'ans',
        Label: 'Terminal type',
        LenType: 'fixed',
        MaxLen: 15
    },
    '127.50': {
        ContentType: 'ans',
        Label: 'Integrated circuit card (ICC) Data',
        LenType: 'llllvar',
        MaxLen: 8000,
        MinLen: 10
    },
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.