在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
unit PayIntf_Get; interface uses SysUtils, Windows, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdHashMessageDigest, IdGlobal, IdHash, HTTPApp, DateUtils, IdHTTP, superobject, DBClient, iniFiles; type {** 输入控制 符号 * 必须输入 M * 非必须输入 O * 不可输入 - * 条件必输 C * 类型 符号 长度 示例 * 字符串 S (20) S(20) 20位长度字符串 * 整数 N (10) N(10) 10位长度整数 * 数字(带小数) N (10,2) N(10,2)整数10位,小数2位数字 } //数据结构:支付 PUpPayData = ^TUpPayData; TUpPayData = record terminalNo: string; //[C]终端编号:支付的中行MIS终端编号,当支付方式是01或02时必填 orderNo: string; //[M]订单编号:大售检票系统中的订单编号 orderAmount: string; //[M]订单金额:12位,以分为单位,比如1分=000000000001 cashAmount: string; //[C]现金支付金额:当支付方式是00或02时必填,12位,以分为单位,比如1分=000000000001 misAmount: string; //[C]MIS支付金额:当支付方式是01或02时必填,12位,以分为单位,比如1分=000000000001 salesman: string; //[O]销售员 orderTime: string; //[M]下单时间:格式:yyyyMMddHHmmss payType: string; //[M]支付方式: 00现金; 01中行MIS; 02组合支付(现金+中行MIS) merchantNo: string; //[M]商户编号:财务结算中心分配的商户编号 tellerNo: string; //[M]销售员编号 orgInfo: string; //[O]预留信息:原交易要素,用于反向交易时定位原交易 orderDetail: string; //[M]订单详情 sign: string; //[M]签名数据:使用1.3通讯方式中的示例进行签名 end; PDownPayData = ^TDownPayData; TDownPayData = record return_code: string; //[M]返回状态码:通讯码为SUCCESS/FAIL return_desc: string; //[M]返回信息:当return_code为FAIL时返回信息为错误原因 ,例如:签名失败,参数格式校验错误 result_code: string; //[O]业务结果:SUCCESS/FAIL orderNo: string; //[O]售检票系统订单号:当result_code是SUCCESS才有返回 merchantOrderNo: string; //[O]财务结算中心订单号:当result_code是SUCCESS才有返回 succTime: string; //[O]订单成功时间:当result_code是SUCCESS才有返回,格式:yyyyMMddHHmmss succAmount: integer; //[O]成功金额:成功金额:当result_code是SUCCESS才有返回,12位,以分为单位,比如1分=000000000001 end; //数据结构:退票 PUpRefundData = ^TUpRefundData; TUpRefundData = record orderNo: string; //[M]订单编号:深大售检票系统中的订单编号 refundAmount: integer; //[M]退款金额:12位,以分为单位,比如1分=000000000001 end; PDownRefundData = ^TDownRefundData; TDownRefundData = record return_code: string; //[M]返回状态码:通讯码为SUCCESS/FAIL return_desc: string; //[M]返回信息:当return_code为FAIL时返回信息为错误原因,例如:签名失败/参数格式校验错误 result_code: string; //[O]业务结果:SUCCESS/FAIL orderNo: string; //[O]售检票系统订单号:当result_code是SUCCESS才有返回 refundTime: string; //[O]订单退款成功时间:当result_code是SUCCESS才有返回 refundAmount: integer; //[O]退款金额:当result_code是SUCCESS才有返回,12位,以分为单位,比如1分=000000000001 end; const L: integer = 12; //金额:12位,以分为单位,比如1分=000000000001 // Key: string = 'QAZWSXEDCTGFREDW@#$%123123'; //秘钥key需要与财务结算系统保持一致,不可随意更改 // Url_Pay: string = 'http://localhost:8080/pay/ParkingAction.createOrder.do'; // Url_Refund:string = 'http://localhost:8080/pay/ParkingAction.refundOrder.do'; procedure MyWriteLog(const mStr:string); function CheckInvalid(UpPayData: TUpPayData; var sMsg: string): boolean; function CheckInvalid_Refund(UpRefundData: TUpRefundData; var sMsg: string): boolean; function ExchangeMoney(Value: string): string; function FormatData(var UpPayData: TUpPayData; var sMsg: string): boolean; function BulidParam(nType: integer; UpPayData: TUpPayData): string; function BulidParam_Refund(nType: integer; UpRefundData: TUpRefundData): string; function ret_mymd5(const sVaule: string): string; function GetSign(var UpPayData: TUpPayData; var sMsg: string): boolean; function PostIntf(UpPayData: TUpPayData; var sJson,sMsg: string): boolean; function PostIntf_Refund(UpRefundData: TUpRefundData; var sJson,sMsg: string): boolean; function GetJsonArr(Cds_BillList: TClientDataSet): string; //提交支付接口函数 function Tkt_PayIntf(UpPayData: TUpPayData; DownPayData: TDownPayData): boolean; //提交退款接口函数 function Tkt_RefundIntf(UpRefundData: TUpRefundData; DownRefundData: TDownRefundData): boolean; implementation uses unit1; function Tkt_PayIntf(UpPayData: TUpPayData; DownPayData: TDownPayData): boolean; var sMsg,sJson: string; JO: ISuperObject; begin {** * 1、检查必要条件 * 2、格式化数据 * 3、获取签名 * 4、提交接口 * 5、解析返回Json *} Result := False; try if not CheckInvalid(UpPayData, sMsg) then begin MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; if not FormatData(UpPayData, sMsg) then begin MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; if not GetSign(UpPayData, sMsg) then begin MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; if not PostIntf(UpPayData, sJson, sMsg) then //提交接口 begin MyWriteLog('返回信息:' + sJson); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; //解析返回的Json MyWriteLog('解析Json:' + sJson); try sMsg := '解析Json错误!'; JO := SO(sJson); if UpperCase(JO.O['return_code'].AsString) = 'FAIL' then begin sMsg := '返回状态码:【' + JO.O['return_code'].AsString + ':' + JO.O['return_desc'].AsString + '】'; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; if UpperCase(JO.O['result_code'].AsString) = 'FAIL' then begin sMsg := '返回业务结果:【' + JO.O['result_code'].AsString + '】'; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; //只有为SUCCESS才返回以下信息 if UpperCase(JO.O['result_code'].AsString) = 'SUCCESS' then begin DownPayData.orderNo := JO.O['result_code'].AsString; DownPayData.merchantOrderNo := JO.O['merchantOrderNo'].AsString; DownPayData.succTime := JO.O['succTime'].AsString; DownPayData.succAmount := JO.O['succAmount'].AsInteger; sMsg := '返回业务结果:【' + JO.O['result_code'].AsString + '】'; MyWriteLog(sMsg); Result := True; end; except on e:exception do begin sMsg := '解析异常:' + e.Message; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; end; except on e:exception do begin sMsg := '接口异常[售票]:' + e.Message; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; end; end; function Tkt_RefundIntf(UpRefundData: TUpRefundData; DownRefundData: TDownRefundData): boolean; var sMsg,sJson: string; JO: ISuperObject; begin try {** * 1、检查必要条件 * 2、提交接口 * 3、解析返回Json *} Result := False; if not CheckInvalid_Refund(UpRefundData, sMsg) then begin Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; MyWriteLog('提交信息:' + BulidParam_Refund(1,UpRefundData)); if not PostIntf_Refund(UpRefundData, sJson, sMsg) then //提交接口 begin MyWriteLog('返回信息:' + sJson); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; //解析返回的Json MyWriteLog('解析Json:' + sJson); try sMsg := '解析Json错误!'; JO := SO(sJson); if UpperCase(JO.O['return_code'].AsString) = 'FAIL' then begin sMsg := '返回状态码:【' + JO.O['return_code'].AsString + ':' + JO.O['return_desc'].AsString + '】'; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; if UpperCase(JO.O['result_code'].AsString) = 'FAIL' then begin sMsg := '返回业务结果:【' + JO.O['result_code'].AsString + '】'; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; //只有为SUCCESS才返回以下信息 if UpperCase(JO.O['result_code'].AsString) = 'SUCCESS' then begin DownRefundData.orderNo := JO.O['orderNo'].AsString; DownRefundData.refundTime := JO.O['refundTime'].AsString; DownRefundData.refundAmount := JO.O['refundAmount'].AsInteger; sMsg := '返回业务结果:【' + JO.O['result_code'].AsString + '】'; MyWriteLog(sMsg); Result := True; end; except on e:exception do begin sMsg := '解析异常:' + e.Message; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; end; except on e:exception do begin sMsg := '接口异常[退票]:' + e.Message; MyWriteLog(sMsg); Application.MessageBox(Pchar(sMsg), '提示', MB_OK); Exit; end; end; end; function PostIntf(UpPayData: TUpPayData; var sJson,sMsg: string): boolean; var Temp: string; IdHttp: TIdHTTP; begin sMsg := '提交接口错误!'; sJson := ''; Result := False; Temp := g_sPayUrl + '?'; Temp := Temp + BulidParam(0, UpPayData); Temp := AnsiToUtf8(Temp); MyWriteLog('提交表单:' + Temp); IdHttp := TIdHTTP.Create(nil); try try IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoKeepOrigProtocol]; IdHttp.ProtocolVersion := pv1_1; IdHttp.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*'; IdHttp.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)'; IdHttp.Request.ContentEncoding := 'utf-8'; IdHttp.Request.ContentType := 'text/xml;Charset=UTF-8'; //正式提交接口 sJson := IdHttp.Get(Temp); sJson := UTF8Decode(sJson); sJson := StringReplace(sJson, '\', '', [rfReplaceAll]); sJson := StringReplace(sJson, '"{"', '[{"', [rfReplaceAll]); sJson := StringReplace(sJson, '"}"', '"}]', [rfReplaceAll]); if sJson = '' then begin sMsg := '错误:接口返回数据为空!'; Exit; end; Result := True; except on e: Exception do begin sMsg := '提交接口异常:' + e.Message; MyWriteLog(sMsg); Exit; end; end; finally FreeAndNil(IdHttp); end; end; function PostIntf_Refund(UpRefundData: TUpRefundData; var sJson,sMsg: string): boolean; var Temp: string; IdHttp: TIdHTTP; begin sMsg := '提交接口错误!'; sJson := ''; Result := False; Temp := g_sRefundUrl + '?'; Temp := Temp + BulidParam_Refund(0, UpRefundData); Temp := AnsiToUtf8(Temp); IdHttp := TIdHTTP.Create(nil); try try IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoKeepOrigProtocol]; IdHttp.ProtocolVersion := pv1_1; IdHttp.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*'; IdHttp.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)'; IdHttp.Request.ContentEncoding := 'utf-8'; IdHttp.Request.ContentType := 'text/xml;Charset=UTF-8'; //正式提交接口 sJson := IdHttp.Get(Temp); sJson := UTF8Decode(sJson); sJson := StringReplace(sJson, '\', '', [rfReplaceAll]); sJson := StringReplace(sJson, '"{"', '[{"', [rfReplaceAll]); sJson := StringReplace(sJson, '"}"', '"}]', [rfReplaceAll]); if sJson = '' then begin sMsg := '错误:接口返回数据为空!'; Exit; end; Result := True; except on e: Exception do begin sMsg := '提交接口异常:' + e.Message; MyWriteLog(sMsg); Exit; end; end; finally FreeAndNil(IdHttp); end; end; function BulidParam(nType: integer; UpPayData: TUpPayData): string; var i: integer; Temp: string; Hash: THashedStringList; begin Hash := THashedStringList.Create; try Hash.Add('terminalNo=' + UpPayData.terminalNo); Hash.Add('orderNo=' + UpPayData.orderNo); Hash.Add('orderAmount=' + UpPayData.orderAmount); Hash.Add('cashAmount=' + UpPayData.cashAmount); Hash.Add('misAmount=' + UpPayData.misAmount); Hash.Add('salesman=' + UpPayData.salesman); Hash.Add('orderTime=' + UpPayData.orderTime); Hash.Add('payType=' + UpPayData.payType); Hash.Add('merchantNo=' + UpPayData.merchantNo); Hash.Add('tellerNo=' + UpPayData.tellerNo); Hash.Add('orgInfo=' + UpPayData.orgInfo); if UpPayData.sign <> '' then begin Hash.Add('orderDetail=' + HttpEncode(UTF8Encode(UpPayData.orderDetail))); //订单明细字段需要进行URL编码 <--提交接口的时候 Hash.Add('sign=' + UpPayData.sign); end else begin Hash.Add('orderDetail=' + UpPayData.orderDetail); end; Hash.Sort; if nType = 0 then begin for i := 0 to Hash.Count-1 do begin Temp := Temp + Trim(Hash.Strings[i]) + '&'; end; Result := Copy(Temp,1,Length(Temp)-1); //去除最后一个字符"&" end else begin for i := 0 to Hash.Count-1 do begin Temp := Temp + '"' + Trim(Hash.Strings[i]) + '",'; end; Temp := StringRePlace(Temp,'=','","',[rfRePLaceAll]); Result := '{' + Copy(Temp,1,Length(Temp)-1) + '}'; //去除最后一个字符"," end; finally FreeAndNil(Hash); end; end; function BulidParam_Refund(nType: integer; UpRefundData: TUpRefundData): string; var Temp: string; begin if nType = 0 then begin Temp := 'orderNo' + UpRefundData.orderNo + '&'; Temp := Temp + 'refundAmount' + IntToStr(UpRefundData.refundAmount); Result := Temp; end else begin Temp := '{'; Temp := Temp + '"orderNo":"' + Trim(UpRefundData.orderNo) + '",'; Temp := Temp + '"refundAmount":"' + IntToStr(UpRefundData.refundAmount) + '"'; Temp := Temp + '}'; Result := Temp; end; end; function ret_mymd5(const sVaule: string): string; var mymd5: TIdHashMessageDigest5; begin try mymd5 := TIdHashMessageDigest5.Create; Result := (mymd5.AsHex(mymd5.HashValue(sVaule))); finally mymd5.Free; end; end; function GetSign(var UpPayData: TUpPayData; var sMsg: string): boolean; var Temp: string; begin Result := False; sMsg := '获取签名失败!'; try Temp := BulidParam(0, UpPayData); MyWriteLog('获取字符串:' + Temp); Temp := Temp + g_sKey; MyWriteLog('获取密钥:' + g_sKey); Temp := ret_mymd5(Temp); UpPayData.sign := LowerCase(Temp); //签名小写 sMsg := '获取签名成功!'; MyWriteLog('获取签名成功:' + UpPayData.sign); Result := True; except |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论