[[packagerimpl]]

== Implementing Custom Packagers

jPOS comes with several ISOPackager and ISOFieldPackager implementations that
can be used either out-of-the-box or as a reference to encode (pack) and decode
(unpack) messages that are built on the ISO-8583 standard. 


[TIP]
====
For a list of out-of-the-box packagers you may want to have a
look at the following directories:

*  +jpos/src/main/java/org/jpos/iso/packager+ (Java based packagers) 
*  +jpos/src/main/resources/packager+ (GenericPackager configurations accessible as a resource)
*  +jpos/src/dist/cfg/packager+ (GenericPackager configurations accessible as external files)
====

Although not required, most ISOPackager implementations extend the supporting
class ISOBasePackager. This approach makes writing a custom packager a very
simple task. It's basically just a matter of calling its 
+public void setFieldPackager (ISOFieldPackager[] fld)+ 
method with a suitable array of ISOFieldPackagers.

Let's look at a sample implementation:

.ISO-8583 version 1993 packager implementation
====
[source,java]
----
public class ISO93BPackager extends ISOBasePackager {
    private static final boolean pad = false;
    protected ISOFieldPackager fld[] = {
    /*000*/ new IFB_NUMERIC (  4, "Message Type Indicator", pad),
    /*001*/ new IFB_BITMAP  ( 16, "Bitmap"),
    /*002*/ new IFB_LLNUM   ( 19, "Primary Account number", pad),
    /*003*/ new IFB_NUMERIC (  6, "Processing Code", pad),
    /*004*/ new IFB_NUMERIC ( 12, "Amount, Transaction", pad),
    /*005*/ new IFB_NUMERIC ( 12, "Amount, Reconciliation", pad),
    /*006*/ new IFB_NUMERIC ( 12, "Amount, Cardholder billing", pad),
    /*007*/ new IFB_NUMERIC ( 10, "Date and time, transmission", pad),
    /*008*/ new IFB_NUMERIC (  8, "Amount, Cardholder billing fee", pad),
    /*009*/ new IFB_NUMERIC (  8, "Conversion rate, Reconciliation", pad),
    /*010*/ new IFB_NUMERIC (  8, "Conversion rate, Cardholder billing", pad),
    ...
    ...
    ...
    /*123*/ new IFB_LLLCHAR (999, "Reserved for private use"),
    /*124*/ new IFB_LLLCHAR (999, "Reserved for private use"),
    /*125*/ new IFB_LLLCHAR (999, "Reserved for private use"),
    /*126*/ new IFB_LLLCHAR (999, "Reserved for private use"),
    /*127*/ new IFB_LLLCHAR (999, "Reserved for private use"),
    /*128*/ new IFB_BINARY  (  8, "Message authentication code field")
    };
    public ISO93BPackager() {
        super();
        setFieldPackager(fld);
    }
}
----
====

We hope you see the key idea: writing a custom packager involves diving into
your interchange specification and setting up a suitable kind of field packager
for every possible field. 

