Tuesday, June 11, 2013

Parsing ISO 8583 dengan jPOS Library

Sekilas Mengenai ISO 8583

ISO 8583 adalah sebuah standar internasional format message untuk transaksi finansial, khususnya yang berbasis kartu. iso8583 secara garis besar memiliki 3 component besar: header, data, trailer. di dalam data, terbagi 3 lagi: MTI, bitmap, data element.

MTI (Message Type Indicator) = 4 digit field numerik, yang mengklasifikasikan fungsi message. terdiri dari 4 komponen: ISO 8583 version, Message Class, Message Sub-class, dan Transaction Originator. penjelasan dan contoh2 MTI dapat dilihat di http://www.codeproject.com/Articles/100084/Introduction-to-ISO-8583.

Bitmap = 16 digit field hexadecimal, teknik indexing utk menunjukkan bit berapa yang digunakan di data element. contoh sebuah nilai bitmap di wikipedia, misalnya 4210001102C04804. 
gimana cara nentuin bit mana yang aktif?

4210001102C04804 -> 8 byte. dipecah per byte: 42 10 00 11 02 C0 48 04.
kemudian tiap byte kita ubah jadi binary
42 => 01000010,
10 => 00010000,
00 => 00000000,
dan seterusnya sampai byte ke-8,
kemudian susun kembali sesuai posisi bytenya, kita dapat nilai binary
0100001000010000000000000001000100000010110000000100100000000100.
hitung dari kiri dimulai dari 1, index yang bernilai 1 menunjukkan bit yang aktif pada data element, yaitu: 2, 7, 12, 28, 32, 39, 41, 42, 50, 53 dan 62.

Data Element = fixed-length string atau byte[]. data element menyimpan field2 yang digunakan dalam transaksi. length tiap field bisa berbeda, sesuai dengan spesifikasinya. spesifikasi data element bisa dilihat di wikipedia. tidak semua field tersebut digunakan dalam tiap transaksi. biasanya hanya beberapa field saja yang terpakai, tergantung kesepakatan antara pemilik sistem dengan third party.

Contoh iso specification requirement bisa didownload di sini https://docs.google.com/file/d/0B_bLNqTuGdsGQUJ2WDctbkFiNmM/edit?usp=sharing.

Contoh Implementasi Parsing ISO 8583 dengan Java (jpos library)

library yang digunakan misalnya jPOS, ambil aja dependencynya dari maven:
 <dependency>  
   <groupId>org.jpos</groupId>  
   <artifactId>jpos</artifactId>  
   <version>1.9.0</version>  
 </dependency>  
 <dependency>  
   <groupId>commons-cli</groupId>  
   <artifactId>commons-cli</artifactId>  
   <version>1.2</version>  
 </dependency>  
 <dependency>  
   <groupId>org.jdom</groupId>  
   <artifactId>jdom</artifactId>  
   <version>1.1.3</version>  
 </dependency>  
note: jpos memiliki dependency ke commons-cli dan jdom.

Kita akan membutuhkan kedua file di bawah ini, silakan didownload:
Simpan keduanya di dalam struktur project, folder src/main/resources/.

Untuk packing ke Iso Message, bisa gunakan method:
 public String packToIso() {  
   String result = null;  
   org.jpos.iso.packager.GenericPackager genericPkg; //spec teknis yg dijadikan acuan fixed-length utk parsing  
   org.jpos.iso.ISOMsg isoMsg; //utk menyimpan nilai2 pada field2 transaksi, utk diparsing ke byte[] atau string.  
   try {  
     genericPkg = new org.jpos.iso.packager.GenericPackager("src/main/resources/isoPackager.xml");  
     isoMsg = new org.jpos.iso.ISOMsg();  
     isoMsg.setPackager(genericPkg);  
     //value2nya di-set sesuai dengan acuan spec isoSpecSample  
     isoMsg.setMTI("0200"); //request financial transaction  
     isoMsg.set(3, "123456");  
     isoMsg.set(4, "300000");  
     String formattedDate = new java.text.SimpleDateFormat("MMddhhmmss").format(new Date());  
     isoMsg.set(7, formattedDate);  
     isoMsg.set(11, "654321"); //bebas, can be sequencial  
     isoMsg.set(22, "123"); //special specification from channel  
     isoMsg.set(24, "123"); //special specification from channel  
     isoMsg.set(35, "AAAAAAAAAAAAAAA"); //special specification from channel  
     isoMsg.set(37, "1234567890AB"); //bebas, can be sequencial  
     isoMsg.set(41, "CAT12345"); //special specification from channel  
     isoMsg.set(42, "MERCHANT1234567"); //special specification from channel  
     isoMsg.set(48, "000"); //special specification from host  
     isoMsg.set(63, "020010023110030001"); //special specification from host  
     byte[] isoMsgByte = isoMsg.pack();  
     result = new String(isoMsgByte);  
     System.out.println(result);  
   } catch (org.jpos.iso.ISOException e) {  
     e.printStackTrace();  
   }  
   return result;  
 }  

Jalankan method di atas, resultnya adalah:
02003220050028C10002123456000000300000061103381365432112312315AAAAAAAAAAAAAAA1234567890ABCAT12345MERCHANT1234567003000018020010023110030001

Coba kita lihat char ke-1 sampai 4 adalah MTI, sesuai yang kita input yaitu 0200.
Char ke-5 sampai 20 adalah bitmap, yaitu 3220050028C10002. Bisa dicek dengan cara yang sama seperti di bagian pertama di atas apakah bit yang aktif sesuai dengan yang kita set.

Sedangkan untuk membongkar string iso 8583, misalnya ke Map, bisa gunakan method ini:
 public Map unpackFromIso(String stringMsg){  
   Map map = new HashMap();  
   try{  
     org.jpos.iso.ISOMsg isoMsg = new org.jpos.iso.ISOMsg();  
     isoMsg.setPackager(new org.jpos.iso.packager.GenericPackager("src/main/resources/isoPackager.xml"));  
     isoMsg.unpack(stringMsg.getBytes());  
     for(int i=1; i<=isoMsg.getMaxField(); i++){  
       if(isoMsg.hasField(i)){  
         map.put("bit-"+i, isoMsg.getString(i));  
       }  
     }  
   }catch(ISOException e){  
     e.printStackTrace();  
   }  
   return map;  
 }  

utk mencoba, bisa dengan main method ini:
 public static void main(String[] args) {  
   String parsed = packToIso();  
   Map map = unpackFromIso(parsed);  
   Iterator it = map.keySet().iterator();  
   while(it.hasNext()){  
     String key = (String)it.next();  
     System.out.println(key+" = "+map.get(key));  
   }  
 }  

selamat mencoba.

No comments:

Post a Comment