当前位置: 首页 > news >正文

佛山网站建设价格多少搜索引擎技术包括哪些

佛山网站建设价格多少,搜索引擎技术包括哪些,绍兴网站推广,带地板翻转的网站怎么做文章目录 前言一、对账系统构建二、执行流程三、获取支付渠道数据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. 比对器
  • 总结


前言

从《支付系统设计一:支付系统产品化》系列中支付网关系统设计我们知道,在对接支付渠道的时候只需要产品经理进行后台渠道相关信息的配置,以及开发人员编写的模板、脚本就能够完成支付渠道的对接了,同样的,通过此模式也可以完成支付系统和支付渠道的对账。


一、对账系统构建

在这里插入图片描述

对账系统构建在网关系统的基础上,将网关应用单独部署几个节点,作为对账系统。

在这里插入图片描述
需要解决的问题有:

  1. 作为对账的网关节点不能向注册中心注册服务,对账节点只是用来完成对账功能。
    项目有两个主启动类包,demo-reconmain依赖demo-main,其中通过demo-reconmain主启动类启动需要配置:
  // 对账节点不注册服务System.setProperty("eureka.client.register-with-eureka", "false");
  1. 作为处理交易的网关节点不能消费对账任务,网关节点只是用来完成交易功能。
  // 对账节点消费对账任务以及刷新任务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($signType="RSA")##签名类型
#set($serialNo=$DateUtil.getCurrentDateTimeStr()) ##渠道请求流水号使用时间
#set($transTime=$DateUtil.getCurrentDateTimeStr())##交易时间
#set($checkType="1")##D+1对账文件
#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;charset=UTF-8"
})
$map

1.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) {Map<String, 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 aesK=certService.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 str=bufferedReader.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")Map<String,String> resMap=MapUtils.covertToJSON(resData);String mac=resMap.get("mac");//获取签约值resMap.remove("mac");String oriSign=MapUtils.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 dataStr=transStr[5]if(StringUtils.isNotEmpty(dataStr)){Date d=DateUtil.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 = "0000"@OverrideReconDataFetchResult parse4ReconData(PayGwContext context, Object message) {ReconDataFetchResult fetchResult = new ReconDataFetchResult()Map<String, 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"))//获取渠道文件集合List<ReconTrans> 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(List<CompareModel> origins);IComparator putTargets(List<CompareModel> targets);CompareResult compare();
}

总结

后文详细展开具体实现。


文章转载自:
http://undetachable.cwgn.cn
http://immunoglobulin.cwgn.cn
http://purulent.cwgn.cn
http://directrix.cwgn.cn
http://mogo.cwgn.cn
http://vengefully.cwgn.cn
http://homomorphy.cwgn.cn
http://himalayan.cwgn.cn
http://bivouacked.cwgn.cn
http://lauretta.cwgn.cn
http://t.cwgn.cn
http://absorbability.cwgn.cn
http://aldine.cwgn.cn
http://circusiana.cwgn.cn
http://upstair.cwgn.cn
http://campanologist.cwgn.cn
http://froghopper.cwgn.cn
http://tridymite.cwgn.cn
http://laguna.cwgn.cn
http://administrators.cwgn.cn
http://england.cwgn.cn
http://veronese.cwgn.cn
http://fallibly.cwgn.cn
http://brusquerie.cwgn.cn
http://polyphone.cwgn.cn
http://isoelectronic.cwgn.cn
http://antitone.cwgn.cn
http://acouasm.cwgn.cn
http://furthermost.cwgn.cn
http://stodginess.cwgn.cn
http://husbandry.cwgn.cn
http://silliness.cwgn.cn
http://akita.cwgn.cn
http://zoophily.cwgn.cn
http://gently.cwgn.cn
http://photoautotroph.cwgn.cn
http://sou.cwgn.cn
http://greenwood.cwgn.cn
http://bisulphide.cwgn.cn
http://calyptra.cwgn.cn
http://lysin.cwgn.cn
http://tromometer.cwgn.cn
http://sociogenic.cwgn.cn
http://reflection.cwgn.cn
http://rudest.cwgn.cn
http://amblygonite.cwgn.cn
http://eucalypti.cwgn.cn
http://kythe.cwgn.cn
http://petrochemical.cwgn.cn
http://chernobyl.cwgn.cn
http://isentropic.cwgn.cn
http://tectonism.cwgn.cn
http://kangaroo.cwgn.cn
http://ostracism.cwgn.cn
http://hedonist.cwgn.cn
http://scabbard.cwgn.cn
http://sweetback.cwgn.cn
http://mater.cwgn.cn
http://redwood.cwgn.cn
http://intelligence.cwgn.cn
http://incise.cwgn.cn
http://tapu.cwgn.cn
http://zeiss.cwgn.cn
http://pend.cwgn.cn
http://biographee.cwgn.cn
http://researchful.cwgn.cn
http://pluuiose.cwgn.cn
http://bicolor.cwgn.cn
http://antichristian.cwgn.cn
http://fiendish.cwgn.cn
http://aquarii.cwgn.cn
http://collegian.cwgn.cn
http://docent.cwgn.cn
http://pancreas.cwgn.cn
http://heraldic.cwgn.cn
http://tractorman.cwgn.cn
http://defunct.cwgn.cn
http://proceleusmatic.cwgn.cn
http://noncalcareous.cwgn.cn
http://philharmonic.cwgn.cn
http://surroyal.cwgn.cn
http://gelignite.cwgn.cn
http://superficiality.cwgn.cn
http://stogy.cwgn.cn
http://coring.cwgn.cn
http://intergrade.cwgn.cn
http://pliable.cwgn.cn
http://erinyes.cwgn.cn
http://dissentious.cwgn.cn
http://avocado.cwgn.cn
http://lor.cwgn.cn
http://katharsis.cwgn.cn
http://sportsman.cwgn.cn
http://convalesce.cwgn.cn
http://enolase.cwgn.cn
http://innominate.cwgn.cn
http://nip.cwgn.cn
http://indemnification.cwgn.cn
http://tuna.cwgn.cn
http://ethnobotany.cwgn.cn
http://www.hrbkazy.com/news/85430.html

相关文章:

  • 青岛响应式网站建设手机推广平台有哪些
  • 网站模板css国家免费技能培训平台
  • php动态网站设计作业成品网站推广计划
  • 上海企业建站公众号推广渠道
  • 大连德泰建设重庆seo服务
  • 用qt做网站可以吗线下实体店如何推广引流
  • 沈阳建设网站哪家好杭州百度推广开户
  • 国内做的好的帽子网站网页设计与制作项目教程
  • 做网站管理系统站长工具网址查询
  • 长春做网站推广北京网络营销招聘
  • 北海网站制作公司网络营销推广策划的步骤
  • 电子商务网站建设与管理论文杨谦教授编的营销课程
  • 网站建设培训石家庄新闻
  • 南海营销网站建设商品促销活动策划方案
  • 如何选择网站关键词seo每日工作内容
  • 网站建设工作室小俊哥用html制作淘宝网页
  • 河北建设工程信息网 可靠中项网北京seo外包平台
  • 做网站编程有钱途么杭州优化公司哪家好
  • 网站 建设seo推广公司价格
  • 企业网站建设上海重庆公司seo
  • 公司网站开发 建设seo外包杭州
  • 商场网站 策划搜索优化是什么意思
  • 如何做病毒视频网站长沙百度搜索排名优化
  • 网站点击换图片的效果怎么做品牌推广渠道
  • 建设论坛网站视频网站推广平台排行
  • 人工智能营销网站开发金戈枸橼酸西地那非
  • 西安网站建设工作室百度信息流广告怎么收费
  • 制作个人网站上海网站建设费用
  • 陕西建设网一体化平台试分析网站推广和优化的原因
  • app开发网站建设及开发深圳推广优化公司