易宝支付Demo,生产中封装成简洁的代付接口,不用request如何获取项目运行时的真实路径...
最近项目在做融360引流,涉及到了易宝支付的代扣和代付。易宝官方给出的demo只能简单运行,而且都是通过form表单的形式提交,返回XML格式。同时接口代码都写在了JSP中看起来不友好。项目在生成中想要用,必须修改整合到自己的项目工程中(文末附我修改的源码下载地址)。
首先说明易宝的版本号:易宝支付-代付代发-商户接入包-V3.3
言归正传,相信易宝官方的demo大家都能获取到,所以这里不再赘述demo的难看点。在这里直接截图给大家说明我修改后的代码。有不好的地方请大家看了代码后及时在下方评论
上图是通过request获取项目的真实路径,以便下面用于获取证书地址,但是实际我们在封装成自己的代码时,传入request是不太好的,因为有可能在我们用的时候,无法获取到request对象。而且这里的功能单一,所以我用下面的方法进行了修改,以便获取到证书真实路径(urlss这里需要替换成自己的当前类全限定名称,TransferParamResolver这个都要替换。下面有可Cp代码)
这里代替为用静态代码块获取证书的真实路径,这里的System.Properties功能还是很多的
// System.err.println(sysPath);
// Properties props = System.getProperties();
// propertis = props.getProperty("user.dir")+"文件分隔符:" + //props.getProperty("file.separator");
// System.out.println("操作系统的名称:" + props.getProperty("os.name"));
// System.out.println("操作系统的构架:" + props.getProperty("os.arch"));
// System.out.println("操作系统的版本号:" + props.getProperty("os.version"));
// System.out.println("文件分隔符:" + props.getProperty("file.separator"));
// //在 unix 系统中是"/"
// System.out.println("路径分隔符:" + props.getProperty("path.separator"));
// //在 unix 系统中是":"
// System.out.println("行分隔符:" + props.getProperty("line.separator"));
// //在 unix 系统中是"/n"
// System.out.println("用户的账户名称:" + props.getProperty("user.name"));
// System.out.println("用户的主文件夹:" + props.getProperty("user.home"));
// System.out.println("用户的当前工作文件夹:" + props.getProperty("user.dir"));// 操作系统的名称:Windows 8.1
// 操作系统的构架:amd64
// 操作系统的版本号:6.3
// 文件分隔符:\
// 路径分隔符:;
// 行分隔符:
// 用户的账户名称:雷神
// 用户的主文件夹:C:\Users\雷神
// 用户的当前工作文件夹:D:\JAVAInstall\intelIdeaWorkSpace\TestProject1
剩下的就是传参和返回值的获取,这里直接放入所有代码
package com.ssm.yibaoPay.yeepay.common.transfer;import com.cfca.util.pki.api.CertUtil; import com.cfca.util.pki.api.KeyUtil; import com.cfca.util.pki.api.SignatureUtil; import com.cfca.util.pki.cert.X509Cert; import com.cfca.util.pki.cipher.JCrypto; import com.cfca.util.pki.cipher.JKey; import com.cfca.util.pki.cipher.Session; import com.ssm.yibaoPay.yeepay.common.securityplatform.Digest; import com.ssm.yibaoPay.yeepay.common.utils.CallbackUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element;import java.io.File; import java.util.LinkedHashMap; import java.util.List; import java.util.Map;/*** com.fastx.cooperate.threeInterface.yeepay.common.transfer;* 功能:;** @author 李冉 Email:1828581413@qq.com* Time:2018/7/11 10:56*/ public class TransferParamResolver {private static String sysPath;static {String urlss = "com.fastx.cooperate.threeInterface.yeepay.common.transfer.TransferParamResolver";urlss = "classes/" + urlss.substring(0, urlss.indexOf("TransferParamResolver")).replace(".", "/");java.net.URL url = TransferParamResolver.class.getResource("");sysPath = (System.getProperties().getProperty("os.name").toUpperCase().startsWith("WIN") ? "" :System.getProperties().getProperty("file.separator"))+ String.valueOf(url).substring(String.valueOf(url).indexOf("file:/")+ 6, String.valueOf(url).indexOf(urlss)) + "lib/";}//protected final static Log log = Log.getLog(TransferParamResolver.class); //添加日志/*** 单笔打款xml请求报文** @param transferSingle* @return* @throws Exception*/public static Map transferSingle(TransferSingle transferSingle) throws Exception {//TranferSingle 这个实体类 是传参的实体,对应文档自己查看,生产中把下面amount对应修改成自己的实际金额即可String xml = "<data>\n" +"\t<cmd>TransferSingle</cmd>\n" +"\t<version>1.1</version>\n" +"\t<mer_Id>10022581269</mer_Id>\n" +"\t<group_Id>10022581269</group_Id>\n" +"\t<batch_No>" + transferSingle.getBatch_no() + "</batch_No>\n" +"\t<order_Id>" + transferSingle.getOrder_id() + "</order_Id>\n" +"\t<bank_Code>" + transferSingle.getBank_code() + "</bank_Code>\n" +"\t<cnaps>100123123123</cnaps>\n" +"\t<bank_Name>" + transferSingle.getBank_name() + "</bank_Name>\n" +"\t<branch_Bank_Name>农业银行北京市朝阳支行</branch_Bank_Name>\n" +"\t<amount>" + "0.01" + "</amount>\n" +"\t<account_Name>" + transferSingle.getAccount_name() + "</account_Name>\n" +"\t<account_Number>" + transferSingle.getAccount_number() + "</account_Number>\n" +"\t<province>110000</province>\n" +"\t<city>110000</city>\n" +"\t<fee_Type>SOURCE</fee_Type>\n" +"\t<payee_Email></payee_Email>\n" +"\t<payee_Mobile></payee_Mobile>\n" +"\t<leave_Word></leave_Word>\n" +"\t<abstractInfo></abstractInfo>\n" +"\t<remarksInfo></remarksInfo>\n" +"\t<urgency>0</urgency>\n" +"\t<hmac></hmac>\n" +"</data>";//需要参加签名的参数:其中(hmacKey)指的是商户自己的密钥String todigestValues = "cmd,mer_Id,batch_No,order_Id,amount,account_Number,hmacKey";//验证返回参数签名的参数:其中(hmacKey)指的是商户自己的密钥String tobackDigestValues = "cmd,ret_Code,mer_Id,batch_No,total_Amt,total_Num,r1_Code,hmacKey";try {return DoTransferSingle(xml, todigestValues, tobackDigestValues);} catch (Exception e) {e.printStackTrace();// log.info("单笔打款异常---------------->" + e.getMessage());// log.info("异常输入的参数---------------->" + transferSingle.toString());throw e;}}/*** 打款明细查询xml请求报文** @param betchNo 订单批次号* @param orderId 订单ID号* @return* @throws Exception*/public static Map singlePayQuery(String betchNo, String orderId) throws Exception {String xml = "<data>\n" +"\t<cmd>BatchDetailQuery</cmd>\n" +"\t<version>1.1</version>\n" +"\t<group_Id>10022581269</group_Id>\n" +"\t<mer_Id>10022581269</mer_Id>\n" +"\t<query_Mode>1</query_Mode>\n" +"\t<batch_No>" + betchNo + "</batch_No>\n" +"\t<order_Id>" + orderId + "</order_Id>\n" +"\t<page_No>1</page_No>\n" +"\t<hmac></hmac>\n" +"</data>";//需要参加签名的参数:其中(hmacKey)指的是商户自己的密钥String todigestValues = "cmd,mer_Id,batch_No,order_Id,page_No,hmacKey";//验证返回参数签名的参数:其中(hmacKey)指的是商户自己的密钥String tobackDigestValues = "cmd,ret_Code,batch_No,total_Num,end_Flag,hmacKey";try {return DoTransferSingle(xml, todigestValues, tobackDigestValues);} catch (Exception e) {e.printStackTrace();//log.info("单笔打款查询异常---------------->" + e.getMessage());// log.info("异常输入的参数---------------->" + "betchNo" + betchNo + "orderId" + orderId);throw e;}}private static Map DoTransferSingle(String xml, String todigestValues, String tobackDigestValues) throws Exception {//商户密钥String hmacKey = "02Ji5At46r9BwZ8TVW7aFHox1pNm9N0n8c7DsA8e5813IEu74T50i901F762";Map result = new LinkedHashMap();Map xmlMap = new LinkedHashMap();Map xmlBackMap = new LinkedHashMap();//需要参加签名的参数:其中(hmacKey)指的是商户自己的密钥String[] digestValues = todigestValues.split(",");//验证返回参数签名的参数:其中(hmacKey)指的是商户自己的密钥String[] backDigestValues = tobackDigestValues.split(",");//String xml = request.getParameter("xml");//第一步:将请求的数据和商户自己的密钥拼成一个字符串,Document document = null;try {document = DocumentHelper.parseText(xml);} catch (DocumentException e) {}Element rootEle = document.getRootElement();String cmdValue = rootEle.elementText("cmd");List list = rootEle.elements();for (int i = 0; i < list.size(); i++) {Element ele = (Element) list.get(i);String eleName = ele.getName();if (!eleName.equals("list")) {xmlMap.put(eleName, ele.getText().trim());} else {continue;}}String hmacStr = "";for (int i = 0; i < digestValues.length; i++) {if (digestValues[i].equals("hmacKey")) {hmacStr = hmacStr + hmacKey;continue;}hmacStr = hmacStr + xmlMap.get(digestValues[i]);}System.out.println("签名之前的源数据为---||" + hmacStr + "||");//下面用数字证书进行签名Session tempsession = null;String ALGORITHM = SignatureUtil.SHA1_RSA;JCrypto jcrypto = null;if (tempsession == null) {try {//初始化加密库,获得会话session//多线程的应用可以共享一个session,不需要重复,只需初始化一次//初始化加密库并获得session。//系统退出后要jcrypto.finalize(),释放加密库jcrypto = JCrypto.getInstance();jcrypto.initialize(JCrypto.JSOFT_LIB, null);tempsession = jcrypto.openSession(JCrypto.JSOFT_LIB);} catch (Exception ex) {System.out.println(ex.toString());}}String sysPath = TransferParamResolver.sysPath;System.out.println("------" + sysPath + "------" + File.separator + "------");JKey jkey = KeyUtil.getPriKey(sysPath + File.separator + "7.3.pfx", "123456");X509Cert cert = CertUtil.getCert(sysPath + File.separator + "7.3.pfx", "123456");System.out.println(cert.getSubject());X509Cert[] cs = new X509Cert[1];cs[0] = cert;String signMessage = "";SignatureUtil signUtil = null;try {// 第二步:对请求的串进行MD5对数据进行签名 String yphs = Digest.hmacSign(hmacStr);signUtil = new SignatureUtil();byte[] b64SignData;// 第三步:对MD5签名之后数据调用CFCA提供的api方法用商户自己的数字证书进行签名b64SignData = signUtil.p7SignMessage(true, yphs.getBytes(), ALGORITHM, jkey, cs, tempsession);if (jcrypto != null) {jcrypto.finalize(JCrypto.JSOFT_LIB, null);}signMessage = new String(b64SignData, "UTF-8");} catch (Exception e) {}System.out.println("经过md5和数字证书签名之后的数据为---||" + signMessage + "||");Element r = rootEle.element("hmac");r.setText(signMessage);result.put("xml", xml);document.setXMLEncoding("GBK");System.out.println("完整xml请求报文:" + document.asXML());String textHost = "http://cha.yeepay.com/app-merchant-proxy/groupTransferController.action";System.out.println("请求地址为:" + textHost);//第四步:发送https请求String responseMsg = CallbackUtils.httpRequest(textHost, document.asXML(), "POST", "gbk", "text/xml ;charset=gbk", false);// out.println( // "<html><body><textarea rows=\"23\" cols=\"120\" name=\"xml\" id=\"xml\">" + // responseMsg + // "</textarea></body></html>"); // System.out.println("服务器响应xml报文:" + responseMsg);try {document = DocumentHelper.parseText(responseMsg);} catch (DocumentException e) {}rootEle = document.getRootElement();cmdValue = rootEle.elementText("hmac");//第五步:对服务器响应报文进行验证签名boolean sigerCertFlag = false;if (cmdValue != null) {sigerCertFlag = signUtil.p7VerifySignMessage(cmdValue.getBytes(), tempsession);String backmd5hmac = xmlBackMap.get("hmac") + "";if (sigerCertFlag) {System.out.println("证书验签成功");backmd5hmac = new String(signUtil.getSignedContent());System.out.println("证书验签获得的MD5签名数据为----" + backmd5hmac);System.out.println("证书验签获得的证书dn为----" + new String(signUtil.getSigerCert()[0].getSubject()));//第六步.将验签出来的结果数据与自己针对响应数据做MD5签名之后的数据进行比较是否相等Document backDocument = null;try {backDocument = DocumentHelper.parseText(responseMsg);} catch (DocumentException e) {System.out.println(e);}Element backRootEle = backDocument.getRootElement();List backlist = backRootEle.elements();for (int i = 0; i < backlist.size(); i++) {Element ele = (Element) backlist.get(i);String eleName = ele.getName();if (!eleName.equals("list")) {xmlBackMap.put(eleName, ele.getText().trim());} else {continue;}}String backHmacStr = "";for (int i = 0; i < backDigestValues.length; i++) {if (backDigestValues[i].equals("hmacKey")) {backHmacStr = backHmacStr + hmacKey;continue;}String tempStr = (String) xmlBackMap.get(backDigestValues[i]);backHmacStr = backHmacStr + ((tempStr == null) ? "" : tempStr);}String newmd5hmac = Digest.hmacSign(backHmacStr);System.out.println("提交返回源数据为---||" + backHmacStr + "||");System.out.println("经过md5签名后的验证返回hmac为---||" + newmd5hmac + "||");System.out.println("提交返回的hmac为---||" + backmd5hmac + "||");if (newmd5hmac.equals(backmd5hmac)) {System.out.println("md5验签成功");//第七步:判断该证书DN是否为易宝if (signUtil.getSigerCert()[0].getSubject().toUpperCase().indexOf("OU=YEEPAY,") > 0) {System.out.println("证书DN是易宝的");if (todigestValues.equals("cmd,mer_Id,batch_No,order_Id,page_No,hmacKey")) {return resolve(responseMsg);}return xmlBackMap;} else {System.out.println("证书DN不是易宝的");}// } else {System.out.println("md5验签失败");}} else {System.out.println("证书验签失败....");}}return null;}private static Map resolve(String responseMsg) {Map xmlBackMap = new LinkedHashMap();Map listBackMap = new LinkedHashMap();Document backDocument;try {backDocument = DocumentHelper.parseText(responseMsg);Element backRootEle = backDocument.getRootElement();List backlist = backRootEle.elements();for (int i = 0; i < backlist.size(); i++) {Element ele = (Element) backlist.get(i);String eleName = ele.getName();if (!eleName.equals("list")) {xmlBackMap.put(eleName, ele.getText().trim());} else {List backList = ((Element) (((Element) (((Element) backlist.get(i)).elements().get(0))).elements().get(0))).elements();for (int j = 0; j < backList.size(); j++) {Element e1111 = (Element) backList.get(j);listBackMap.put(e1111.getName(), e1111.getText().trim());}}}xmlBackMap.put("listBackMap", listBackMap);return xmlBackMap;} catch (DocumentException e) {//log.info("易宝解析返回XML参数错误----->" + e.getMessage());return null;}}/*** 根据易宝代付订单批次号和订单号查询支付状态** @param betch_no* @param order_Id* @return*/public static Integer getPayStatus(String betch_no, String order_Id) {//代付状态/1 代付中 /2 代付成功/ 3 代付失败try {Map transferMap = TransferParamResolver.singlePayQuery(betch_no, order_Id);if (transferMap == null || transferMap.get("listBackMap") == null) {return 3;}Map listBackMap = (Map) transferMap.get("listBackMap");if (transferMap.get("ret_Code") != null && listBackMap.get("r1_Code") != null && listBackMap.get("bank_Status") != null) {if ("1".equals(String.valueOf(transferMap.get("ret_Code"))) && "0026".equals(String.valueOf(listBackMap.get("r1_Code"))) && "S".equals(String.valueOf(listBackMap.get("bank_Status")))) {return 2;}//失败情况if ("1".equals(String.valueOf(transferMap.get("ret_Code"))) && ("0026".equals(String.valueOf(listBackMap.get("r1_Code"))) || "0027".equals(String.valueOf(listBackMap.get("r1_Code")))) && "F".equals(String.valueOf(listBackMap.get("bank_Status")))) {return 3;}//正在进行中if ("1".equals(String.valueOf(transferMap.get("ret_Code"))) && ("0026".equals(String.valueOf(listBackMap.get("r1_Code")))) || "0025".equals(String.valueOf(listBackMap.get("r1_Code")))) {return 1;}} else {return 3;}} catch (Exception e) {e.printStackTrace();//log部分 }return 3;}}
这里附上源码下载地址(源码在TestProject中):链接:https://pan.baidu.com/s/1UVUCG4zNYDJmJl9q5twrkw 密码:32gw
易宝支付Demo,生产中封装成简洁的代付接口,不用request如何获取项目运行时的真实路径...相关推荐
- 支付入门-易宝支付实践
无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点这里可以跳转到教程. 易宝支付的规范和流程 1)发起 ...
- 传智播客--网上支付之易宝支付接入规范
今天我们学习网上支付的实现.这个功能在网上商城等交易平台上是基本的功能.实现起来不难,却很实用.我们很有必要掌握好今天学习的知识.运用到我们今后 的工作中去. 1. 网上支付两种接入方案 --直接与银 ...
- 【SSH网上商城项目实战21】从Demo中看易宝支付的流程
这一节我们先写一个简单点的Demo来测试易宝支付的流程,熟悉这个流程后,再做实际的开发,因为是一个Demo,所以我没有考虑一些设计模式的东西,就是直接实现支付功能.实现支付功能需要易宝给我们提供的AP ...
- java在线支付---09,10,11,12_在线支付_分析易宝支付网关的应答协议与处理代码,完成用于处理支付响应的Servlet的初步编写和调试,完成处理支付网关响应结果的Servlet,支付实现
09_在线支付_分析易宝支付网关的应答协议与处理代码 创梦综合技术qq交流群:CreDream:251572072 对支付结果返回的数据加密生成md5-hmac public static boole ...
- 【CSDN英雄会】 易宝支付架构师、移动产品线技术负责人程超:走在Java的路上
英雄会是CSDN旗下针对国内IT技术领域专家展示和交流的平台.通过线下线上的互动形式,为CSDN社区专家提供更多学习.合作.宣传的机会.英雄会后续将在北上广深等国内一二线城市建立分会,各个分会后期将组 ...
- java在线支付---03_分析易宝支付网关的请求协议
03_分析易宝支付网关的请求协议 创梦综合技术qq交流群:CreDream:251572072 -------------------------------------- 1.buildHmac() ...
- java实现易宝支付
易宝支付: 1.环境搭建: Java使用Servlet或者springMVC,使用maven进行环境搭建. 2.添加jar包: <dependencies> <dependency& ...
- 第三方支付平台:易宝支付
国付宝国企 LianLianPay连连支付 这个比较好用,可以自己试试 我这里说的是易宝支付 两种在线支付的方式 在线支付一共有两种方式: 电商直接与银行对接: 电商通过第三方支付平台与银行对接: 电 ...
- 在线支付(易宝支付)
第三方支付方式:易宝支付. 支付过程图解: 相关资料: 易宝支付产品通用接口帮助文档点击打开链接 使用步骤: ①src下面放入支付测试用的merchantInfo.properties(包含商 ...
最新文章
- 前端工程化工具Fekit分析
- Python 技术篇-使用opencv读取图片实例演示,python安装opencv库
- hihocoder 1260
- apache日志 waf_WAF对WebShell流量检测的性能分析
- c++游戏代码坦克大作战_一红一蓝多种模式的双人小游戏:红蓝大作战
- 动态规划训练13 [Catch That Cow poj3278]
- c简单的链表错误及改正
- 【机器学习】sclearn分类算法-决策树、随机森林
- jQuery教程07-内容筛选选择器
- VS2015 中使用 MVC4
- python2和python3的默认编码_Python2和Python3中的字符串编码问题解决
- Atitit 发帖机实现(4 )- usbQBM1601 gui操作标准化规范与解决方案attilax总结
- python实例100例下载-Python的100个练习实例免费下载
- 文件后缀名查询(全)
- 通用能力-《即兴演讲》-樊登读书总结
- 如何通过努力出书,如何写有畅销资质的书,本文汇集了多位计算机图书作者的经验...
- 2021年N1叉车司机考试总结及N1叉车司机操作证考试
- 基于普中A2开发板(STC80C51单片机)呈现的中断小实验代码电路及其效果。
- ofo小黄车骑车券无条件领取,人人有份!
- 再Windows下 .Pages格式怎么保存为word或者PDF格式
热门文章
- 店盈通:拼多多一个店铺推几个产品最好
- 魔兽世界 Mangos Trinity TrinityCore 数据库 结构 大纲
- python比例图_python在地图上画比例的实例详解
- [面试题]自己边面试边总结的Java开发工程师笔记
- 使用Toad导入dmp数据
- 计算机网络管理技师代号,计算机网络管理技师复习资料.doc
- 生成一个简版导游地图
- 全国专业技术人员计算机应用能力考试广东,广东省人事厅关于全国专业技术人员计算机应用能力考试扩充科目(模块)有关问题的通知...
- 数据分析---常用业务运营指标
- 蜘蛛爬行html语言的顺序,搜索引擎蜘蛛爬行的规律是什么?