1 2 12
1 10 13

: ISO8583 -

  1. #1

    Mar 2012
    Athens, , Greece.
    :
    99

    ISO8583 -





    ATM. ? . pin . internet .

    ISO8583 (http://en.wikipedia.org/wiki/ISO_8583) ATM, EFT, web banking

    1. . () (EFT, ATM PC) , ( processor ). modem TCP/IP .

    2. TerminalID MerchantID, . ATMs .

    3. () . .

    4. . .

    5. . client Server. ( ).

    6. .

    TCP/IP .
    • server (). .
    • ISO8583 server
    • server.
    • server.
    • ISO8583 server client
    • client.
    • server .
    • client.

    . ( ) .

    , (reverse) . () . . .
    .

    7. (batch) batch, . . batch server ( ) . server . , batch , .
    . , vouchers, batch.
    .



    modbus , .

    ISO8583 o .

    1. , .
    2. ().
    3. .
    4. batch .
    5. "" .


  2. #2

    Mar 2012
    Athens, , Greece.
    :
    99
    ?

    VT100 character terminals unix servers. unix process (logged in) .
    unix, , .

    super market . (unix host) .
    barcode scanner, barcodes unix. modem 2400 baud unix server .

    , [:0], POSes . ( , , ) ( , , ..). bandwidth server . , , , .

    ޅ

    Web retail Application

    O Web Server session cookies.
    O browser barcode usb barcode scanner .
    O browser barcode Web Server , , , .
    O browser , xml island, .
    O browser WebServer . WebServer browser () (batch)

    TCP/IP Web server (SHA1 digest).

    Web Server TCP/IP .

    ISO8583. , , .

    , SPDH. Stay tuned..

    . . . . .

  3. #3

    Mar 2012
    Athens, , Greece.
    :
    99
    Web retail application

    supermarket internet. barcode scanner . , site .
    . 2 server. , sms. , , internet supermarket. , ( ) . .[V]

    (issuer) EFT (aquirer).

    . (15 + 1 LUHN check digit ) . , , . VISA, MC, . , .

    & (virtual) ISO8583 POS.


    SPDH.

    ?. SPDH. ?

    . ISO8583 . ? .

    (abstract) BaseEFTPos ( ) 2 SPDHEFT TISO8583EFT .


    BaseEFTPos

    - Initialization
    - uthorization ( , ) ,
    - Sale( , )
    - Void Sale ( , )
    - Refund ( , )
    Void Refund( , )
    - Finalization

    TISO8583EFT

    A. TBaseEFT
    B.
    . ISO8583
    . , tcp/ip, ISO8583 .
    . (reversals)
    . batch
    . batch

    TSPDHEFT
    . TBaseEFT
    .
    . SPDH
    . , x25 SPDH .
    . (reversals)
    . batch

    2 reversal batch. SPD .



    .



    TBasePos. , , , , .

    . flat oracle mysql TBaseEft.

    TBasePos dbHandler. TBasePos NeutralTerm NeutralTrn. .

    . attributes dbTable.

    . . software soft. . project. cash flow . .

    passwords encryption. . PIN. Chip

    ISO8583.

    . (crc).
    (Field Separator).

    modem 2400 baud byte . .

    . bitmap. bits 8 bytes , (1..64) .

    o ISO8583 ascii , primary bitmap ( ) .
    64 2 bitmap (secondary). 1o bit primary bitmap 2 bitmap 64 128 .

    :
    function TISO8583.FieldExists(fieldNo: integer): boolean;
     begin
      if fieldNo>64 then
       result:=TestBit(PrimaryBitmap,1) and TestBit(SecondaryBitmap,fieldNo-64)
      else
       result:=TestBit(PrimaryBitmap,fieldNo)
     end;
    , ascii . 128 ?. case statement . .

    :
    type  TNibble = 0..15;
          T8583FieldTypes  = (ftb,ftn,ftx_n,ftns,fta,ftan,ftans,ftz,fta_n);
          T8583FieldFormat = (ffNone,ffLLVAR,ffLLLVAR,ffMMDDhhmmss,
                              ffhhmmss,ffMMDD,ffYYMM,ffYYMMDD,ffx,ffb);
    
          T8583FieldDef = packed record
                           bit:byte;
                           kind:T8583FieldTypes;
                           len:word;
                           opt:T8583FieldFormat;
                          end; 
    
    
          T8583FieldDef = packed record
                           bit:byte;
                           kind:T8583FieldTypes;
                           len:word;
                           opt:T8583FieldFormat;
                          end;
    
    
    const FieldDefs  : array[1..128] of T8583FieldDef =
                     ((bit:  1; kind:  ftb; len:  1; Opt:ffNone),
                      (bit:  2; kind:  ftn; len: 19; Opt:ffLLVAR),
                      (bit:  3; kind:  ftn; len:  6; Opt:ffNone),
    ..
                      (bit:  7; kind:  ftn; len: 10; Opt:ffMMDDhhmmss),
    ..
                      (bit: 12; kind:  ftn; len:  6; Opt:ffhhmmss),
                      (bit: 13; kind:  ftn; len:  4; Opt:ffMMDD),
                      (bit: 14; kind:  ftn; len:  4; Opt:ffYYMM),
                      (bit: 15; kind:  ftn; len:  4; Opt:ffMMDD),
    ..
                      (bit: 28; kind:ftx_n; len:  8; Opt:ffx),
    ..
    , . .

    :
    procedure TISO8583.SetField(fieldNo: integer;const Value: string);
     var ok:boolean;
     begin
      with FieldDefs[fieldNo] do
       begin
        case opt of
         ffLLVAR,
         ffLLLVAR : ok:=length(value)<=len;
         ffx      : ok:=length(Value)=len+1;
         ffb      : ok:=length(value)=(len div 8)*2
        else
         ok:=length(Value)=len;
        end;
    
        if not ok then
         raise Exception.CreateFmt('Invalid Field %d length %d vs %d',
                                  [fieldNo,length(value),len]);
    
        case kind of
         ftb   : ok:=isHex(Value);
         ftn   : begin
                  ok:=isN(Value);
                  if ok then
                   case opt of
                    ffMMDDhhmmss : ok:=isMMDD(copy(value,1,4)) and
                                       isHHMMSS(copy(value,5,6));
                    ffhhmmss     : ok:=isHHMMSS(value);
                    ffMMDD       : ok:=isMMDD(value);
                    ffYYMM       : ok:=isYYMM(value);
                    ffYYMMDD     : ok:=isYYMMDD(value);
                   end
                 end;
         ftx_n : ok:=(value[1] in ['C','D']) and
                     isN(copy(Value,2,length(value)-1));
         ftns  :;
         fta   :ok:=isA(Value);
         ftan  :ok:=isAN(Value);
         ftans :ok:=isANS(Value);
         ftz   :;
         fta_n :ok:=isN(Value) or isA(value);             // a or n
        end;
        if not ok then
         raise Exception.CreateFmt('Invalid Field data %d [%s]',
                                   [FieldNo,Value]);
       end;
    
      // Valid field value, store it
      fFields[pred(fieldNo)]:=value;
      if (fieldNo>64) then
       begin
        SetBit(SecondaryBitmap,fieldNo-64);
        SetBit(PrimaryBitmap,1);
       end
      else
       SetBit(PrimaryBitmap,fieldNo)
     end;
    
    
    TISO8583 = class
      private
       fFields:TStringList;
       fID:string;
       fMTI: string;
       PrimaryBitmap : array[1..8] of byte;  // 16 hex bytes
       SecondaryBitmap : array[1..8] of byte;
       function  GetData: string;
       procedure SetData(Value: string);
       function  GetField(fieldNo: integer): string;
       procedure SetField(fieldNo: integer; const Value: string);
       function  AsString(fieldNo:integer;value:int64):string;
       procedure SetBit(var buf;bitNo: integer);
       function  TestBit(var buf;bitNo: integer): boolean;
      protected
       function  isN(value:string):boolean;
       function  isANS(value:string):boolean;
       function  isA(value:string):boolean;
       function  isAN(value: string): boolean;
       ..
    
       constructor Create(const aMerchantId,aTerminalId, 
                          aAcquirerId : string); overload; virtual;
      public
       constructor Create; reintroduce; overload;
       constructor Create(const msg:string); overload;
       destructor  Destroy; override;
       procedure   AssignTo(source:TISO8583);
    
       function    FieldExists(fieldNo:integer):boolean;
       procedure   Clear; virtual;
       property    MTI: string read fMTI write fMTI;
       property    Data:string read GetData write SetData;
    
       property    Fields[fieldNo:integer]:string read GetField 
                                                  write SetField;
      end;

    ascii iso8583 .

    :
    iso8583 := TISO8583.Create;
    iso8583.Data:=msg;
    
    procedure TISO8583.SetData(Value: string);
     var i,ilen:integer;
         s:string;
         p:pByte;
         w:pword;
         b:byte;
     begin
      Clear;
      fID:=copy(value,1,6);  delete(value,1,6);
      fMTI:=copy(value,1,4); delete(value,1,4);
    
      BitCopy(value, PrimaryBitmap); delete(value,1,16);
    
      if TestBit(PrimaryBitmap,1) then begin
       BitCopy(value, SecondaryBitmap); delete(value,1,16);
       end;
    
      for i:=1 to 128 do // skip Primary and Secondary bitmaps
       if (i<>1) and (i<>65) and fieldExists(i) then
        with FieldDefs[i] do begin
          case Opt of
           ffLLVAR : begin
                      ilen:=StrToInt(copy(value,1,2));
                      delete(value,1,2);
                     end;
           ffLLLVAR: begin
                      ilen:=StrToInt(copy(value,1,3));
                      delete(value,1,3);
                     end;
           ffx     : ilen:=len+1;
           ffb     : ilen:=(len div 8)*2;
          else
           { ffMMDDhhmmss, ffhhmmss, ffMMDD, ffYYMM, ffYYMMDD, ffNone :}
           ilen:=len;
          end;
          s:=copy(value,1,ilen); delete(value,1,ilen);
    
    //      
    //     
    // property Fields[FieldNo:integer]:string ... write SetField;
    
          Fields[i]:=s;
         end;
     end;

  4. #4

    Mar 2012
    Athens, , Greece.
    :
    99
    SPH.
    .
    ascii . FS (0x1C). SPDH FS+_+ .

    &
    , . ( TCP/IP) , .

    .
    . TCP/IP . (character vs block streams).

    state machine (, , checksum) ( timeouts).
    state machine . ( ) .

    TCP/IP checksum ( TCP/IP ). state machine


    1. case (Chuck Norris way).
    2. , (schema) . C Delphi . 2 . ( dipoli).
    3. post . , . (Integer, String, Amount, Price, Quantity, Rate, Date8, Time, Flags). ascii.
    domains databases.
    Delphi (integer, long, double, string) objects objects TObject.

    / objects
    OOP . Java. . 2 . (class=, methods= )
    Java , , . Delphi Turbo pascal ( )

    objects bject.

    .

    :
    type TObjClass = class of TObj;
    
         TObj = class
           protected
            procedure fromAscii(const a:string); virtual;
            function  toAscii:string; virtual;
            procedure nag;
           public
            function  equals(a:TObj):boolean; virtual;// same instance
            property  Ascii:string read toAscii write fromAscii;
         end;
    
         TString = class(TObj)
           private
            Fs:string;
           public
            constructor Create(const a:string);
            procedure fromAscii(const a:string); override;
            function  toAscii:string; override;
            function  equals(a:TObj):boolean; override;
           end;
    
         TA = class(TString) // alpha
           protected
            procedure fromAscii(const a:string); override;
         end;
    
         TAN  = class(TString) // alphanumeric
           protected
            procedure fromAscii(const a:string); override;
         end;
    
         TNumber = class(TObj)
           private
            Ftype: integer;
    //      ... :)
            FNum : record case integer of
                     0 : (b  : byte);
                     1 : (w  : word);
                     2 : (sh : shortInt);
                     3 : (sm : smallInt);
                     4 : (i  : integer);
                     5 : (c  : cardinal);
                     6 : (i64: int64);
                    end;
           public
            constructor Create(const b:byte); overload;
            constructor Create(const w:word); overload;
            constructor Create(const i:ShortInt); overload;
            constructor Create(const i:SmallInt); overload;
            constructor Create(const i:integer); overload;
            constructor Create(const c:cardinal); overload;
            constructor Create(const i:int64); overload;
            function equals(a:TObj):boolean; override;// same instance
           end;
    
    
    { TObj }
    
    function TObj.equals(a: TObj): boolean;
     begin
      result:=self=a;
     end;
    
    procedure TObj.fromAscii(const a: string);
     begin
     end;
    
    procedure TObj.nag;
     begin
      raise Exception.CreateFmt('Invalid ascii for type %s',[ClassName]);
     end;
    
    function TObj.toAscii: string;
     begin
      result:='';
     end;
    
    { TString }
    
    constructor TString.Create(const a: string);
     begin
      Fs:=a;
     end;
    
    function TString.equals(a: TObj): boolean;
     begin
      result:=(a is ClassType) and (TString(a).Fs=Fs);
     end;
    
    procedure TString.fromAscii(const a: string);
     begin
      fs:=a;
     end;
    
    function TString.toAscii: string;
     begin
      result:=fs;
     end;
    
    { TNumber }
    
    constructor TNumber.Create(const w: word);
     begin
      FType   := 1;
      FNum.w  := w;
     end;
    
    constructor TNumber.Create(const b: byte);
     begin
      FType   := 0;
      FNum.b  := b;
     end;
    
    function TNumber.equals(a: TObj): boolean;
     begin
      result:=(a is ClassType);
      if result then
       case Ftype of
        0 : result :=  FNum.b=TNumber(a).FNum.b;
        1 : result :=  FNum.w=TNumber(a).FNum.w;
        2 : result :=  FNum.sh=TNumber(a).FNum.sh;
        3 : result :=  FNum.sm=TNumber(a).FNum.sm;
        4 : result :=  FNum.i=TNumber(a).FNum.i;
        5 : result :=  FNum.c=TNumber(a).FNum.c;
        6 : result :=  FNum.i64=TNumber(a).FNum.i64;
       else
        result:=false;
       end;
     end;
    
    { TA }
    
    procedure TA.fromAscii(const a: string);
     var i:integer;
     begin
      for i:=1 to length(a) do
       if not (a[i] in ['A'..'Z','a'..'z']) then nag;
      fs:=a;
     end;
    
    
    { TAN }
    
    procedure TAN.fromAscii(const a: string);
     var i:integer;
     begin
      for i:=1 to length(a) do
       if not (a[i] in ['0'..'9','A'..'Z','a'..'z']) then nag;
      fs:=a;
     end;
    Objs.

    :
    var Fields : array[0..3] of TObj;


    :
    const FieldTypes : array[0..3] of TObjClass =
                       ( TString,
                         TNumber,
                         TA,
                         TAN
                       );
    .

    :
      for i:=low(Fields) to High(Fields) do
       Fields[i]:=FieldTypes[i].Create;
    .
    :
      Fields[0].Ascii:='Panos';
      Fields[1].Ascii:='12345';
      Fields[2].Ascii:='12345'; // invalid assignment, nag is called
      Fields[3].Ascii:='12345';


  5. #5

    Mar 2012
    Athens, , Greece.
    :
    99
    . Site. , 6.

    . , software. ( [8D]).

    .

    . field separators ( ) 2 3 .

    .

    domain. domain . double Quantity, Price, Amount domains double (, ). ascii TStringList . array TObjs ( VB scripting) array of variants.

    variants data type .

    procedural OOP .

    :
        case kind of
         ftb   : ok:=isHex(Value);
         ftn   : begin
                  ok:=isN(Value);
                  if ok then
                   case opt of
                    ffMMDDhhmmss : ok:=isMMDD(copy(value,1,4)) and
                                       isHHMMSS(copy(value,5,6));
                    ffhhmmss     : ok:=isHHMMSS(value);
                    ffMMDD       : ok:=isMMDD(value);
                    ffYYMM       : ok:=isYYMM(value);
                    ffYYMMDD     : ok:=isYYMMDD(value);
                   end
                 end;
         ftx_n : ok:=(value[1] in ['C','D']) and
                     isN(copy(Value,2,length(value)-1));
         ftns  :;
         fta   :ok:=isA(Value);
         ftan  :ok:=isAN(Value);
         ftans :ok:=isANS(Value);
         ftz   :;
         fta_n :ok:=isN(Value) or isA(value);             // a or n
        end;
        if not ok then
         raise Exception.CreateFmt('Invalid Field data %d [%s]',
                                   [FieldNo,Value]);
       end;
    regular expressions.

    Regular Expressions

    ( ) .

    :
    \n:      0x0a
    \r:      0x0d
    \d:   
    . :       \n
    \:        .
     
    ^ :      string
    $ :      string
    
    ? :          (0,1)
    * :          (0,)
    + :          (1,)
    {n}:      n 
    
    (..) : ,    0
    [..] :        
    [^..]: not  
    : \d{10}
    2 : ^[\+|\-]?(\d*\.?\d{0,2})$

    981-982 : 98[1|2]\d{10}


    Visa (length 16, prefix 4),
    Mastercard (length 16, prefix 51-55),
    Discover (length 16, prefix 6011),
    American Express (length 15, prefix 34 or 37).
    :
    ^((4\d{3})|(5[1-5]\d{2})|(6011))-?\d{4}-?\d{4}-?\d{4}|3[4,7]\d{13}$
    passwords

    1 Case Sensitive
    2 .
    3 6 ( 10)
    4 (!@#$%^&*()_+|~=\{}[]:";<>?,./).
    5 .
    :
    ^[\D](?=.+\d)[\w!@#$%^&*()_+|~={}]{4,8}[\D]$
    . regular expressions.




    .
    .
    . PCI DSS .
    chip .
    PIN.

    PIN .
    1234 PIN.
    .

    internet prepaid "" .

    / .


    Mature software developer.

  6. #6

    Oct 2010
    Athens, , Greece.
    :
    1,632
    " " prepaid.

    ... ( , unbanked ..)
    .

    ( prepaid 100 ... )

    , debit web-banking.
    , ..


    Burn baby, burn

  7. #7
    quote prepaid 100 ... )
    100 200 100 ;

    quote: , debit web-banking.
    , ..
    . ;

  8. #8

    Oct 2010
    Athens, , Greece.
    :
    1,632
    abuse .

    , web banking.

    , ( ).
    card not present .
    ...

    prepaid .
    prepaid .
    , , unbanked ,
    20% 15-20% , .


    Burn baby, burn

  9. #9
    quote: . Site. , 6.
    ...
    .... ... ....
    ...

    http://udravlikos.gr

  10. #10

    Mar 2012
    Athens, , Greece.
    :
    99


    . .
    thread.

    2 .
    bitmap .
    types & domains



    . . .

    .

    (indexes).
    .

    ...


  • You may not post new threads
  • You may not post attachments
  •