西安有哪些做网站建设的公司好,中国电力建设股份部官方网站,公司网站建设亚运村,wordpress4.9.5漏洞文章目录 前言一、对账系统构建二、执行流程三、获取支付渠道数据1.接口形式1.1 后台配置1.2 脚本编写1.2.1 模板1.2.2 解析脚本 2.FTP形式2.1 后台配置2.2 脚本编写2.2.1 模板2.2.2 解析脚本 四、获取支付平台数据五、数据比对1. 比对模型2. 比对器 总结 前言
从《支付系统设… 文章目录 前言一、对账系统构建二、执行流程三、获取支付渠道数据1.接口形式1.1 后台配置1.2 脚本编写1.2.1 模板1.2.2 解析脚本 2.FTP形式2.1 后台配置2.2 脚本编写2.2.1 模板2.2.2 解析脚本 四、获取支付平台数据五、数据比对1. 比对模型2. 比对器 总结 前言
从《支付系统设计一支付系统产品化》系列中支付网关系统设计我们知道在对接支付渠道的时候只需要产品经理进行后台渠道相关信息的配置以及开发人员编写的模板、脚本就能够完成支付渠道的对接了同样的通过此模式也可以完成支付系统和支付渠道的对账。 一、对账系统构建 对账系统构建在网关系统的基础上将网关应用单独部署几个节点作为对账系统。 需要解决的问题有
作为对账的网关节点不能向注册中心注册服务对账节点只是用来完成对账功能。 项目有两个主启动类包demo-reconmain依赖demo-main其中通过demo-reconmain主启动类启动需要配置 // 对账节点不注册服务System.setProperty(eureka.client.register-with-eureka, false);作为处理交易的网关节点不能消费对账任务网关节点只是用来完成交易功能。 // 对账节点消费对账任务以及刷新任务System.setProperty(paygw.rabbit.flag, buildRabbitFlag(RabbitFlagConsts.ALL, RabbitFlagConsts.RECON));关于这块见以前写的篇博客《多机房控制消息消费方实现》
即通过此设计支付网关系统又可以作为对账系统可以很巧妙的解决支付渠道侧对账数据获取的问题。
二、执行流程 三、获取支付渠道数据
不同的支付渠道获取对账文件的方式也各不相同有的是推送FTP有的是通过接口下载等文件类型也有所不同有的是TEXT有的是CSV等文件内容格式也是各不相同所以我们同样的套路不同处使用脚本实现将渠道侧数据解析入临时表。
1.接口形式
1.1 后台配置
如兴业银行的对账文件通过接口下载那么我们需要配置下载对账文件的通讯信息 1.2 脚本编写
1.2.1 模板
cib_depute_recon_main.vm
##单付对账脚本
#set($umask 1000)
#set($version 1.0.2)##版本号
#set($mchtId$data.merExtends.merId)##渠道商户号
#set($signTypeRSA)##签名类型
#set($serialNo$DateUtil.getCurrentDateTimeStr()) ##渠道请求流水号使用时间
#set($transTime$DateUtil.getCurrentDateTimeStr())##交易时间
#set($checkType1)##D1对账文件
#set($checkDate $DateUtil.format($data.reconStartDate,yyyyMMdd))##对账日期yyyyMMdd
#set($businessMap
{version:$!version,mchtId:$!mchtId,signType:$!signType,serialNo:$!serialNo,transTime:$!transTime,checkType:$!checkType,checkDate:$!checkDate
})
#set($certCodePrivate$data.merExtends.certCodePrivate)##商户自己的私钥
#set($businessStr$MapUtils.generateParamStr($businessMap))
#set($mac$certService.sign($certCodePrivate,$businessStr))##获取签名
#set($signMap
{mac:$!mac
})
$umask$JSON.toJSONString($MapUtils.putAll($businessMap,$signMap))cib_depute_recon_header.vm
#set($map
{Content-Type:application/json;charsetUTF-8
})
$map1.2.2 解析脚本
/*** author Kkk* Describe: 兴业银行代付对账解析*/
class CIBDeputeReconParser extends AbstractReconDataFetchParser{def logger LoggerFactory.getLogger(CIBDeputeReconParser.class)def resp_code_success [E0000]public static final String ALGORITHM SHA1PRNG/** 证书服务*/AutowiredCertService certService/*** 查询结果处理*/OverrideReconDataFetchResult parse4ReconData(PayGwContext context, Object message) {MapString, Object data context.getMessageDescription().getDatas()ReconDataFetchResult fetchResult new ReconDataFetchResult()try {//验证签名(必须)def flag verifySign(context, message)if (!flag) {//签名通过返回解析后的数据不包含签名类型和签名数据throw new Exception([兴业银行-单笔代付对账请求] 返回参数验签失败!)}Object result JSON.parse(message)JSONObject jobj (JSONObject) resultdef respCode jobj.get(respCode);def respMsg jobj.get(respMsg);if(!resp_code_success.contains(respCode)){fetchResult.setSuccess(false)fetchResult.setRemark(兴业银行对账失败[respCode][respMsg]);return fetchResult}String fileContent jobj.get(fileContent)String aesKey jobj.get(aesKey)//使用私钥解密aesKeydef certCodePrivate context.getMessageDescription().getData(merExtends).get(certCodePrivate)def aesKcertService.decryptBase64(certCodePrivate,aesKey)//用解密得到的aesKey解密fileContentbyte[] afterFileContent this.AESDecode(fileContent,aesK)//将得到的fileContent解码byte[] bb1 BASE64.decodeCib(new String(afterFileContent,utf-8).toCharArray())//解压缩byte[] dedata FileUtils.decompress(bb1)//流读取文件内容并入表保存InputStream is new ByteArrayInputStream(dedata)BufferedReader bufferedReadertry{def tempStrLoggerUtil.info(logger, 兴业银行-单付对账-文件-开始解析)bufferedReader new BufferedReader(new InputStreamReader(is,UTF-8))//解析第一行def strbufferedReader.readLine()LoggerUtil.info(logger, 解析第一行str:{},str)while ((tempStr bufferedReader.readLine()) ! null) {if (StringUtils.isNotBlank(tempStr)) {LoggerUtil.info(logger, 兴业对账文件解析内容:{},tempStr)String[] transStr tempStr.split(\\|)ReconTrans reconTrans convert2ReconTrans(transStr)store(context, reconTrans)}}} catch (Exception e) {logger.error(兴业银行-单笔代付-对账异常, e)fetchResult.setSuccess(false)fetchResult.setRemark(e.getMessage())} finally {if (bufferedReader ! null) {try {bufferedReader.close()} catch (IOException e1) {}}}fetchResult.setSuccess(true)data.put(PayGwConstant.PAYGW_TRANS_STATUS, TransStatusEnum.SUCCESS.getCode())fetchResult.setRemark(兴业银行-单笔代付对账成功。)return fetchResult}catch (PayGwException e){LoggerUtil.error(logger, [兴业银行-单笔代付对账请求失败], e);fetchResult.setSuccess(false)fetchResult.setRemark(e.getErrorMsg())return fetchResult}catch (Exception e){LoggerUtil.error(logger,[兴业银行-单笔代付对账请求失败]:{}--异常信息,e)fetchResult.setSuccess(false)fetchResult.setRemark(兴业银行-单笔代付对账失败paygw解析数据异常)return fetchResult}}/*** 验签*/boolean verifySign(PayGwContext context, String resData) {def certCodePublic context.getMessageDescription().getData(merExtends).get(certCodePublic)MapString,String resMapMapUtils.covertToJSON(resData);String macresMap.get(mac);//获取签约值resMap.remove(mac);String oriSignMapUtils.generateParamStr(resMap);boolean vflag certService.checkSign(certCodePublic,mac,oriSign)logger.info(兴业银行-单笔代付对账请求,请求返回签名值({}),验签结果({}),mac,vflag)return vflag}/*** 构建对象*/private ReconTrans convert2ReconTrans(def transStr) {ReconTrans trans new ReconTrans()trans.setInstReqNo(transStr[0])trans.setAcctNo(transStr[1])trans.setTransCode(TransactionEnum.DEPUTE.code)trans.setTransAmount(new BigDecimal(transStr[4]))String dataStrtransStr[5]if(StringUtils.isNotEmpty(dataStr)){Date dDateUtil.parseDateTime(dataStr,yyyyMMddHHmmss)trans.setTransDateTime(d)trans.setTransDate(d)}trans.setTransStatus(TransStatusEnum.SUCCESS.code())return trans}/*** 使用AES解密fileContent*/static byte[] AESDecode(String str,String num) throws Exception{KeyGenerator kg KeyGenerator.getInstance(AES);SecureRandom sr SecureRandom.getInstance(ALGORITHM);sr.setSeed(num.getBytes());kg.init(128, sr);SecretKey sk kg.generateKey();byte[] raw sk.getEncoded();SecretKey key new SecretKeySpec(raw,AES);Cipher cipher Cipher.getInstance(AES/ECB/PKCS5Padding);cipher.init(Cipher.DECRYPT_MODE, key);byte[] str_AES cipher.doFinal(HexConvertorUtil.hex2Bytes(str));return str_AES;}
}2.FTP形式
2.1 后台配置
如平安银行的对账文件通过FTP下载那么我们需要配置下载对账文件的通讯信息 2.2 脚本编写
2.2.1 模板
pingan_depute_recon_main.vm
#set($umask 1000)
#set($map
{fileName:$!data.fileNameCHK
})
$umask$!MapUtils.toJsonStr($map)2.2.2 解析脚本
/*** author Kkk* Describe: 平安银行单付对账文件解析*/
class PANBANKDeputeReconFilesParser extends AbstractReconDataFetchParser {Logger logger LoggerFactory.getLogger(PANBANKDeputeReconFilesParser.class)def success true, remark 平安银行单付对账入库成功。, panbank_success 0000OverrideReconDataFetchResult parse4ReconData(PayGwContext context, Object message) {ReconDataFetchResult fetchResult new ReconDataFetchResult()MapString, Object data context.getMessageDescription().getDatas()//先设置结果的扩展字段JSONObject extend JSON.parseObject(StringUtils.valueOf(data.get(extend1)))logger.info(平安银行单付对账解析文件第四步解析前extend值为:{},extend)if (StringUtils.isNotBlank(message) message.length 0) {//解析文件并入库parseFile(context, message)extend.put(stepOrder, 6)fetchResult.setExtend1(extend.toString())fetchResult.setSuccess(success)fetchResult.setRemark(remark)logger.info(平安银行单付对账解析文件data:{},data)data.put(PayGwConstant.PAYGW_TRANS_STATUS, TransStatusEnum.SUCCESS.getCode())logger.info(平安银行单付对账解析文件并入库fetchResult.setRemark-4:{}--extend:{},fetchResult.getRemark(),extend)return fetchResult}fetchResult.setSuccess(false)fetchResult.setRemark(平安银行单付对账失败文件下载失败。)logger.info(平安银行单付对账fetchResult.setRemark-4:{}--extend:{},fetchResult.getRemark(),extend)return fetchResult}/*** 解析对账文件*/void parseFile(PayGwContext context, byte[] absoluteFilePath) {def line null//获取对账文件的文件流InputStream is new ByteArrayInputStream(absoluteFilePath)try {//按行读取对账文件LineReader xline new LineReader(new InputStreamReader(is, GBK))//获取渠道文件集合ListReconTrans list new ArrayList()boolean firstLine truewhile ((line xline.readLine()) ! null) {//按行转换成对账流水记录ReconTrans reconTrans convert2ReconTrans(line, firstLine)//从此以后再无第一行firstLine falseif (reconTrans null) {continue}list.add(reconTrans)}//入库for (ReconTrans trans : list) {store(context, trans)}} catch (PayGwException e) {//更新success falseremark 平安银行单付对账失败原因: e.getErrorMsg()LoggerUtil.error(logger, 文件读取异常:, e)} catch (Exception e) {//更新success falseremark 平安银行单付对账失败LoggerUtil.error(logger, 文件读取异常:, e)}finally {IOUtils.closeQuietly(is)}}private ReconTrans convert2ReconTrans(def lineStr, boolean firstLine) {ReconTrans trans new ReconTrans()def transStatusdef item lineStr.split(\\|\\:\\:\\|, -1)def transDate item[0]def instReqNo item[3]def acctNo item[5]def transAmt new BigDecimal(item[6])//0000 成功 其余为失败def errorCode item[10]//交易状态(平安银行对账文件全为成功数据)if (StringUtils.equals(errorCode, panbank_success)) {transStatus TransStatusEnum.SUCCESS.code()} else {//其他状态不入库return null}trans.setTransStatus(transStatus)trans.setInstReqNo(instReqNo)trans.setTransCode(TransactionEnum.DEPUTE.code)//用户卡号trans.setAcctNo(acctNo)//交易金额trans.setTransAmount(transAmt)//交易日期trans.setTransDate(DateUtil.parseDate(transDate, yyyyMMdd))//交易时间因对账文件中不存在交易时间故将交易日期入库trans.setTransDateTime(DateUtil.parseDateTime(transDate, yyyyMMdd))return trans}
}四、获取支付平台数据
直接使用SQL查询出对应支付渠道的对应的交易类型的交易数据。
五、数据比对
拉取两侧数据构建数据比对模型放到内存中进行数据比对
1. 比对模型
/*** author Kkk* Describe: 对账-比对模型*/
public class CompareModel {/*** 唯一索引*/private String uniqueIndex;/*** 值*/private String value;/*** 业务流水ID*/private Long transId;
}2. 比对器
/*** author Kkk* Describe: 对账-比较器定义*/
public interface IComparator {IComparator putOrigins(ListCompareModel origins);IComparator putTargets(ListCompareModel targets);CompareResult compare();
}总结
后文详细展开具体实现。 文章转载自: http://www.morning.ryrgx.cn.gov.cn.ryrgx.cn http://www.morning.hctgn.cn.gov.cn.hctgn.cn http://www.morning.rfwrn.cn.gov.cn.rfwrn.cn http://www.morning.ftwlay.cn.gov.cn.ftwlay.cn http://www.morning.pqppj.cn.gov.cn.pqppj.cn http://www.morning.jmnfh.cn.gov.cn.jmnfh.cn http://www.morning.xmyrn.cn.gov.cn.xmyrn.cn http://www.morning.kllzy.com.gov.cn.kllzy.com http://www.morning.rnrfs.cn.gov.cn.rnrfs.cn http://www.morning.skkmz.cn.gov.cn.skkmz.cn http://www.morning.tqfnf.cn.gov.cn.tqfnf.cn http://www.morning.nnpwg.cn.gov.cn.nnpwg.cn http://www.morning.ngmjn.cn.gov.cn.ngmjn.cn http://www.morning.tpkxs.cn.gov.cn.tpkxs.cn http://www.morning.plxnn.cn.gov.cn.plxnn.cn http://www.morning.qljxm.cn.gov.cn.qljxm.cn http://www.morning.dongyinet.cn.gov.cn.dongyinet.cn http://www.morning.jcyrs.cn.gov.cn.jcyrs.cn http://www.morning.bprsd.cn.gov.cn.bprsd.cn http://www.morning.cpktd.cn.gov.cn.cpktd.cn http://www.morning.kxbdm.cn.gov.cn.kxbdm.cn http://www.morning.gycyt.cn.gov.cn.gycyt.cn http://www.morning.krklj.cn.gov.cn.krklj.cn http://www.morning.gycyt.cn.gov.cn.gycyt.cn http://www.morning.tldfp.cn.gov.cn.tldfp.cn http://www.morning.bpkqd.cn.gov.cn.bpkqd.cn http://www.morning.zgqysw.cn.gov.cn.zgqysw.cn http://www.morning.pmghz.cn.gov.cn.pmghz.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.qyqdz.cn.gov.cn.qyqdz.cn http://www.morning.3jiax.cn.gov.cn.3jiax.cn http://www.morning.hrzky.cn.gov.cn.hrzky.cn http://www.morning.mnjyf.cn.gov.cn.mnjyf.cn http://www.morning.nhzxr.cn.gov.cn.nhzxr.cn http://www.morning.cjrmf.cn.gov.cn.cjrmf.cn http://www.morning.srbfp.cn.gov.cn.srbfp.cn http://www.morning.jwtjf.cn.gov.cn.jwtjf.cn http://www.morning.dcmnl.cn.gov.cn.dcmnl.cn http://www.morning.prls.cn.gov.cn.prls.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.fdmfn.cn.gov.cn.fdmfn.cn http://www.morning.cbnjt.cn.gov.cn.cbnjt.cn http://www.morning.mcqhb.cn.gov.cn.mcqhb.cn http://www.morning.gfmpk.cn.gov.cn.gfmpk.cn http://www.morning.dljujia.com.gov.cn.dljujia.com http://www.morning.fqmcc.cn.gov.cn.fqmcc.cn http://www.morning.xhgxd.cn.gov.cn.xhgxd.cn http://www.morning.cmhkt.cn.gov.cn.cmhkt.cn http://www.morning.rwmft.cn.gov.cn.rwmft.cn http://www.morning.dfrenti.com.gov.cn.dfrenti.com http://www.morning.znsyn.cn.gov.cn.znsyn.cn http://www.morning.lbrrn.cn.gov.cn.lbrrn.cn http://www.morning.tgwfn.cn.gov.cn.tgwfn.cn http://www.morning.zlfxp.cn.gov.cn.zlfxp.cn http://www.morning.mjgxl.cn.gov.cn.mjgxl.cn http://www.morning.kjgdm.cn.gov.cn.kjgdm.cn http://www.morning.bdgb.cn.gov.cn.bdgb.cn http://www.morning.ksgjy.cn.gov.cn.ksgjy.cn http://www.morning.ldnrf.cn.gov.cn.ldnrf.cn http://www.morning.zcfmb.cn.gov.cn.zcfmb.cn http://www.morning.cwyfs.cn.gov.cn.cwyfs.cn http://www.morning.gnlyq.cn.gov.cn.gnlyq.cn http://www.morning.qqhfc.cn.gov.cn.qqhfc.cn http://www.morning.hrjrt.cn.gov.cn.hrjrt.cn http://www.morning.fhsgw.cn.gov.cn.fhsgw.cn http://www.morning.hqllx.cn.gov.cn.hqllx.cn http://www.morning.hghhy.cn.gov.cn.hghhy.cn http://www.morning.rtlg.cn.gov.cn.rtlg.cn http://www.morning.cfrz.cn.gov.cn.cfrz.cn http://www.morning.fhcwm.cn.gov.cn.fhcwm.cn http://www.morning.xdfkrd.cn.gov.cn.xdfkrd.cn http://www.morning.tyjp.cn.gov.cn.tyjp.cn http://www.morning.nykzl.cn.gov.cn.nykzl.cn http://www.morning.lbfgq.cn.gov.cn.lbfgq.cn http://www.morning.phlrp.cn.gov.cn.phlrp.cn http://www.morning.yhxhq.cn.gov.cn.yhxhq.cn http://www.morning.mggwr.cn.gov.cn.mggwr.cn http://www.morning.ctrkh.cn.gov.cn.ctrkh.cn http://www.morning.wsxly.cn.gov.cn.wsxly.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn