Unit PayIntf_MisDll; interface uses Windows, the Messages, the SysUtils, Variants, the Classes, Graphics, Controls, Forms, the Dialogs, StdCtrls; of the type {/ * Transaction Type: '00' consumption '01' undo '02' return '03' Charles I ' 04 'reprint' 05 'sign' 06 'billing' 08 'tip' 09 'pre-authorization ' 10 'to pre-authorize additional' 11 'pre-authorization is completed' 12 'pre-authorization revoked ' 13 'pre-authorization is completed revocation' 14 'mall staging '15' special stage '16' phased out '18' stage credits query '19' car wash card '20' Quick pay '21' designated account Quancun '22' e-cash return '23' electronic cash check more than '24 'redeem consumption' 25 'redeem revocation ' 26 'check points' 28'Equity integral inquiry '29' integral consumer interests '30' integral rights revocation '32' card for transfer out '33' for reimbursement '34' financial payment '60'- polymerization payment is swept ' 61'- polymerization payment main sweep ' 62'- polymerization charged return '63'- POS acquiring two-dimensional code data scan code gun ' 64'- single polymerization payment orders for abnormal '72'- polymerization payment orders for abnormal ' 90'- drove benefit concessions stand by bank card '94'- benefits CUP promotions drove up by the two-dimensional code '95'- cloud lightning pay transaction, minus Shipping ' 96'- mall stand by stage Shipping * /} TInputData = Record posid: Array [0..7] of char; // / * cash register number (8 bytes, left justified, complement deficiency of space) * / operid: Array [0..7] of char; // / * operator numbers (8 bytes, left, space fill the shortage ) * / Trans: Array [0..1] of char; // see above transaction types amount: array [0..11] of char ; // / * the amount (12 bytes, no decimal point, left fill 0, unit: minutes) * / old_date: array [0..7] of char ; // / * original transaction date (8 bytes, YYYYMMDD format, with every other day return) * / old_reference: Array [0..11] of char; // / * original transaction reference number * / Trk2: Array [0..36] of char; // / * two track data (37 bytes, left justified, complement deficiency of space) * / old_trace: array [0..5] of char ; // / * serial number (6 bytes, right, up left 0, with a return or re-printing) * / old_batch: Array [0..5] of char ; // / * 57 - 62 of the original batch number * / old_auth: Array [0..5] of char; // / ~ * 63 is 68 Ihara authorization code * / old_terno: Array [0..7] of char; // / * 69 ~ 76 Ihara transaction terminal number * / szFenqiNum: Array [0..1] of char; // / * 77 ~ 78 bit numbers 03,06,09,12,18,24 stage, * 36,42,48,60 / szServiceNum: Array [0..1] of char; // / * 79 ~ 80 Wei enjoy the service number * / szGoodsNo: Array [0..11] of char; // / * 81 to 92 commodity item code * / Trk3: Array [0..103] of char; // / * three track data (104 bytes, left justified, complement deficiency of space) * / LRC: Array [0 .. 2] of char; // / * check data transaction (3 random characters from 0 to 9) * / szOrderTrace: Array [0..19] of char; // 6/16/2015 water added silver ( No orders) left space if less than szPrefer: Array [0..49] of char; // coupon left space if less than szRsv: array [0..299] of char ; // reserved field of two-dimensional code of this input code data space if less than left End; TOutPutData = Record resp_code: Array [0..1] of char; // / * 1 ~ 2-bit return code (2-byte "00" successful transaction, other failure) * / bank_code: Array [0..3] of char; // / * ~. 3. 6 bank bit line number (4 bytes) * / CARD_NO: Array [0..29] of char; // / ~ * 36 card number. 7: 622 280 4860 * ********* / expr: Array [0 .. 3] of char; // / * 37 ~ 40 valid bit (4 bytes) * / aMOUNT: Array [0..11] of char; // / ~ * 141 is bit 52 is the amount (12 bytes, no decimal point, 0 up left, unit: min) * / the trace: Array [0..5] of char; // / ~ * 53 is 58 bit serial number (6 bytes, left) * / refer: array [0..11] of char ; // / * 59 ~ 70 bit transaction reference number * / the auth: Array [0..5] of char; // / ~ * 71 is 76-digit license number * / BATCH: Array [0..5] of char; // / ~ * 77 * 82 bit batch number / date: array [0..13] of char ; // / * 83 ~ 96 bit transaction date (8 bytes, yyyymmddhhmmss format) * / userNo: Array [0 .. 14] of char; // / ~ * 97 111 business number * / Terno: Array [0..7] of char; // / * terminal to No. 112 ~ 119 * / old_terno: Array [0..7] of char; // / * bit 120 ~ 127 original terminal number * / resp_chin: Array [0..49] of char; // / * error description (left-aligned, and the gap fill space) * / the OrderNo: Array [0..49] of char; // / * Order transaction order number dimensional code * / Trans: Array [0..1] of char; // / * transaction type * / ChannelType: Array [0..1] of char; // / * '0' two CUP dimensional code '1' micro-channel '2' Alipay '3' Long payment * / LRC: Array [0..2] of char;// / *'s check code (3 bytes) * / End; function PayIntf_Trans (ParkCode, OptorCode , Trans, Money, OldTrandID: string ; var OrderNo: string): Boolean; function GetInputStr(ParkCode, OptorCode, Trans, Money, OldTrandID: string; var InStr: string): Boolean; procedure GetOutputData(OutStr: string); procedure FillArrayChar(FillType, ParamVaule: string; var ArrVaule: array of char); function GetOldTradeInfo(OldTrandID: string; var old_date, old_reference, old_trace: string): boolean; function CheckDataValid(ParkCode, OptorCode, Trans, Money, OldTrandID: string): boolean; function Obj2Json_InputData(InputData: TInputData): string; function Obj2Json_OutputData(OutputData: TOutputData): string; procedure MyWriteLog(const mStr: string); function BankTrans(PInStr: Pchar; POutStr: Pchar): integer; stdcall; external 'C:\landiccbmispos\MisPos.dll'; //0- 成功 , 其他-失败 Implementation function CheckDataValid (ParkCode, OptorCode, Trans, Money, OldTrandID: String): Boolean; var sMsg, sFileDLL: String; the begin the Result: = False; sFileDLL: = 'C: \ landiccbmispos \ MisPos.dll'; IF Not the FileExists ( sFileDLL) the then the begin sMsg: = 'call payment interface file does not exist! '; MyWriteLog (sMsg +' [ 'sFileDLL + +'] '); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); the Exit; End; IF (Trans <>' 00 ') and (Trans < > '01') and (Trans <> '02') and (Trans <> '05') and (Trans <> '06') // the then '00' consumption '01' undo '02' return '03' Charles I ' 05 'sign' 06 'Clearing the begin sMsg: =' illegal transaction types! '; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg), 'prompt', MB_OK); the Exit; End; IF (Trans = '01') or (Trans = '02') the then the begin IF OldTrandID = '' the then the begin sMsg: = 'revocation and when return, pass the original transaction order number! '; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); the Exit; End; End; IF StrToCurrDef (Money, 0) <= 0 the then the begin sMsg: =' amount allowed negative or zero! '; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); the Exit; End; the Result: = True; End; function PayIntf_Trans (ParkCode, OptorCode, Trans, Money, OldTrandID: String; var OrderNo: string): Boolean; lv_nRet: Integer; the InStr: String; outStr: String; sMsg: String; resp_code: String; the begin {*. 1, examine incoming parameters: The document rules * 2, combined into a fixed-length string parameter * 3, method call DLL * 4, parsing returns a fixed length string: Analyzing results * 5, logging *} // check arguments passed IF Not CheckDataValid (ParkCode, OptorCode, Trans, Money, OldTrandID) the then the begin the Exit; End; // composition parameters passed forming a fixed length string the InStr IF Not GetInputStr (ParkCode, OptorCode, Trans, Money, OldTrandID, the InStr) the then the begin the Exit ; End; MyWriteLog ( 'transmission fixed-length string: [' the InStr + + ']'); the SetLength (outStr, the SizeOf (TOutPutData)); Application.ProcessMessages by; lv_nRet: = BankTrans (Pchar (the InStr), Pchar (outStr)) ; // call to the DLL BankTrans method IF the Copy (the OrderNo,. 1,. 8 ) <> 'eEEEEEEE' then // special return when abnormal situation, such as a network anomalies, Application.ProcessMessages by; MyWriteLog ( 'returns a fixed length string: [' outStr + + ']'); GetOutputData (outStr); IF (lv_nRet <> 0) or (the Copy (outStr,. 1, 2) <> '00' ) the then the begin sMsg: = 'transaction fails! '; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); Exit; End; OrderNo: = Trim (Copy (OrderNo, 158, 50)); the begin // dialogue will pop up at the same time DLL frame. Please verify that the merchant bank and timely return success! ! ! sMsg: = 'trading success! '; MyWriteLog (sMsg +' [ 'the OrderNo + +'] '); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); End the else the begin sMsg: =' transaction was successful, the need to manually check the mono! ' Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); End ; End; function GetInputStr (ParkCode, OptorCode, Trans, Money, OldTrandID: String; var InStr: String): Boolean; var OLD_DATE, old_reference, old_trace, sMsg: String; InputData: TInputData; the begin {trade description: consumer: incoming necessary information (transaction type, amount) Returns: incoming necessary information (type of transaction, the amount of the original transaction reference number, the date of the original transaction) revoked: incoming necessary information (type of transaction, the amount, the original serial number) to check more than : incoming necessary information (type of transaction) Note: the amount of operating card balance inquiry display in password keypad. And will not return the corresponding balance. Reprint: Incoming necessary information (type of transaction, the original serial number) Note: reprint the original serial number on the transaction: "000000" sign: Incoming necessary information (type of transaction) billing: incoming necessary information (type of transaction)} the Result: = False; the try FillChar(InputData,SizeOf(TInputData),' '); FillArrayChar('RN', ParkCode, InputData.posid); FillArrayChar('RN', OptorCode, InputData.operid); FillArrayChar('R0', Trans, InputData.trans); FillArrayChar('L0', IntToStr(Trunc(StrToCurrDef(Money, 0) * 100)), InputData.amount); if (Trans = '01') or (Trans = '02') then //'00'消费'01'撤销'02'退货'03'查余 begin if Trans = '01' then begin FillArrayChar('L0', old_trace, InputData.old_trace);// / * original serial number (6 bytes, right, up left 0, with a return or re-printing) * / if not GetOldTradeInfo(OldTrandID, old_date, old_reference, old_trace) then begin Exit; end; FillArrayChar('RN', '', InputData.old_date); FillArrayChar('RN', '', InputData.old_reference); end; if Trans = '02' then begin FillArrayChar('L0', '', InputData.old_trace); FillArrayChar('RN', old_date, InputData.old_date); // /* 原交易日期(8 字节,yyyymmdd 格式,隔日退货时用)*/ FillArrayChar('RN', old_reference, InputData.old_reference); // /* 原交易参考号*/ end; FillArrayChar ( 'the L0', '', InputData.old_trace); the begin the else // undo and non return End FillArrayChar ( 'the RN', '', InputData.old_date); FillArrayChar ( 'the RN', '', InputData.old_reference); End; // The following is the default fill FillArrayChar ( 'the RN', '', InputData.old_batch); // / ~ * 57 is 62 original batch number * / FillArrayChar ( 'the RN', '', InputData.old_auth); // / ~ * 63 is 68 Ihara authorization code * / FillArrayChar ( 'the RN', '', InputData.old_terno); / / / * 69 - 76 of the original transaction terminal number * / FillArrayChar ( 'the RN', '', InputData.szFenqiNum); // / * bit stages 77 - 78 number 03,06,09,12,18,24,36 , 42,48,60 * / FillArrayChar ( 'RN', '', InputData.szServiceNum); // / * 79 ~ 80 Wei enjoy the service number * / FillArrayChar ( 'RN', '', InputData.szGoodsNo); / / / * 81 to 92 commodity item code * / FillArrayChar ( 'RN ',' ', InputData.trk2); // / * two track data (37 bytes, left justified, complement deficiency of space) * / FillArrayChar ( 'RN', '', InputData.trk3); // / * three track data (104 bytes, left justified, complement deficiency of space) * / FillArrayChar ( 'the RN', '', InputData.lrc);// / * check data transaction (3 random characters from 0 to 9) * / No // 6/16/2015 water added silver (Order); FillArrayChar ( 'RN', '', InputData.szOrderTrace) left space if less thanstring); our MB_OK); Exit; End; End; End; the begin sMsg, sTemp: String; the OutputData: TOutPutData; the begin the try IF outStr = '' the then the begin sMsg: = 'transactions return parameter is empty! '; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg),' prompt ', MB_OK); the Exit; End; // string assigned to the recording FillChar (the OutputData, the SizeOf (TOutputData),' '); StrLCopy (@ the OutputData, Pchar (outStr), the SizeOf (TOutputData)); // record the information returned sTemp: = 'return information [convert the JSON]:' + Obj2Json_OutputData (the OutputData); MyWriteLog (sTemp); the except ON E: Exception do sMsg : = 'return parameter conversion exception:' + e.message; MyWriteLog (sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; end; end; function Obj2Json_InputData(InputData: TInputData): string; begin Result := '{'; Result := Result + '"posid":"' + Trim(InputData.posid) + '",'; Result := Result + '"operid":"' + Trim(InputData.operid) + '",'; Result := Result + '"trans":"' + Trim(InputData.trans) + '",'; Result := Result + '"amount":"' + Trim(InputData.amount) + '",'; Result := Result + '"old_date":"' + Trim(InputData.old_date) + '",'; Result := Result + '"old_reference":"' + Trim(InputData.old_reference) + '",'; Result := Result + '"old_trace":"' + Trim(InputData.old_trace) + '",'; Result := Result + '"old_batch":"' + Trim(InputData.old_batch) + '",'; Result := Result + '"old_auth":"' + Trim(InputData.old_auth) + '",'; Result := Result + '"old_terno":"' + Trim(InputData.old_terno) + '",'; Result := Result + '"szFenqiNum":"' + Trim(InputData.szFenqiNum) + '",'; Result := Result + '"szServiceNum":"' + Trim(InputData.szServiceNum) + '",'; Result := Result + '"szGoodsNo":"' + Trim(InputData.szGoodsNo) + '",'; Result := Result + '"trk2":"' + Trim(InputData.trk2) + '",'; Result := Result + '"trk3":"' + Trim(InputData.trk3) + '",'; Result := Result + '"lrc":"' + Trim(InputData.lrc) + '",'; Result := Result + '"szOrderTrace":"' + Trim(InputData.szOrderTrace) + '",'; Result := Result + '"szPrefer":"' + Trim(InputData.szPrefer) + '",'; Result := Result + '"szRsv":"' + Trim(InputData.szRsv) + '"'; Result := Result + '}'; end; function Obj2Json_OutputData(OutputData: TOutputData): string; begin Result := '{'; Result := Result + '"resp_code":"' + Trim(OutputData.resp_code) + '",'; Result := Result + '"bank_code":"' + Trim(OutputData.bank_code) + '",'; Result := Result + '"card_no":"' + Trim(OutputData.card_no) + '",'; Result := Result + '"expr":"' + Trim(OutputData.expr) + '",'; Result := Result + '"amount":"' + Trim(OutputData.amount) + '",'; Result := Result + '"trace":"' + Trim(OutputData.trace) + '",'; Result := Result + '"refer":"' + Trim(OutputData.refer) + '",'; Result := Result + '"auth":"' + Trim(OutputData.auth) + '",'; Result := Result + '"batch":"' + Trim(OutputData.batch) + '",'; Result := Result + '"date":"' + Trim(OutputData.date) + '",'; Result := Result + '"userno":"' + Trim(OutputData.userno) + '",'; Result := Result + '"terno":"' + Trim(OutputData.terno) + '",'; Result := Result + '"old_terno":"' + Trim(OutputData.old_terno) + '",'; Result := Result + '"resp_chin":"' + Trim(OutputData.resp_chin) + '",'; Result := Result + '"OrderNo":"' + Trim(OutputData.OrderNo) + '",'; Result := Result + '"trans":"' + Trim(OutputData.trans) + '",'; Result := Result + '"ChannelType":"' + Trim(OutputData.ChannelType) + '",'; Result := Result + '"lrc":"' + Trim(OutputData.lrc) + '"'; Result := Result + '}'; End; function GetOldTradeInfo (OldTrandID: String; var OLD_DATE, old_reference, old_trace: String): Boolean; var sMsg: String; the begin the Result: = False; the try OLD_DATE: = '20,190,805'; old_reference: = '123,456,789,987,456'; old_trace: = '123456 '; the Result: = True; the except ON E: exception do the begin sMsg: =' original transaction payment information acquiring abnormal [original transaction number: '+ + OldTrandID']: '+ e.message; MyWriteLog (sMsg); Application.MessageBox (Pchar (sMsg), 'prompt', MB_OK); the Exit; End; End; End; Procedure FillArrayChar (fillType, ParamVaule: String; var ArrVaule:array of char); var I, Len, Diff: integer; sTemp: string; begin Len := Length(ArrVaule); if Length(ParamVaule) < Len then begin Diff := Len - Length(ParamVaule); for I := 1 to Diff do begin if Copy(FillType, 2, 1) = '0' then //填充"0" begin sTemp := sTemp + '0'; end else begin sTemp := sTemp + ' '; //填充空格 end; end; if Copy(FillType, 1, 1) = 'L' then //左填充 begin sTemp := sTemp + ParamVaule; end else if Copy(FillType, 1, 1) = 'R' then //右填充 begin sTemp := ParamVaule + sTemp; End; End the else the begin sTemp: = ParamVaule; End; for the I: =. 1 to Len do the begin ArrVaule [the I -. 1]: = sTemp [the I]; End; End; Procedure MyWriteLog (const MSTR: String); var F: textfile; myDir, myfilename: String; FileHandle: Integer; the LogType, LogDate, the ModuleID: String; the begin the LogType: = 'the INFO'; LogDate: = the FormatDateTime ( 'YYYY-the MM-DD HH: NN: SS ZZZ', Now); ModuleID := ''; IF not // (CanLogFile in FLogFlags) the then Exit; // ------ written to implement parts of the document - beginning myDir: = ExtractFilePath (ParamStr (0)); // determine the file name myfilename: = FormatDateTime ( ' "PayIntf" YYYYMMDD ".log"', a Date); // If you create the log directory does not exist under executable directory if not DirectoryExists (myDir + '\ log') the then createDir (myDir + '\ log'); // if the date of the log file does not exist, create a file and release the handle if not the FileExists (myDir + '\ log \' + myfilename) the then the begin FileHandle: = FileCreate (myDir + '\ log \' + myfilename); // create a file FileClose (FileHandle); // release the handle End; the try // the try. ... statements ..except AssignFile (F, myDir + '\ log \' + myfilename); the Append (F); Writeln (F, '$$' + the Format ( '% 6S', [the LogType]) + '$ $ '+ Format ( '% 12s' [ModuleID]) + '$$' + LogDate + chr (9) + MSTR); The Flush (f); ; CloseFile (f) implement // ----- written document forming part of - the end of the except the except ... // ... the try statements End; // the try ... the except ... statements End; End.