最近项目在做融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)发起 ...

  2. 传智播客--网上支付之易宝支付接入规范

    今天我们学习网上支付的实现.这个功能在网上商城等交易平台上是基本的功能.实现起来不难,却很实用.我们很有必要掌握好今天学习的知识.运用到我们今后 的工作中去. 1. 网上支付两种接入方案 --直接与银 ...

  3. 【SSH网上商城项目实战21】从Demo中看易宝支付的流程

    这一节我们先写一个简单点的Demo来测试易宝支付的流程,熟悉这个流程后,再做实际的开发,因为是一个Demo,所以我没有考虑一些设计模式的东西,就是直接实现支付功能.实现支付功能需要易宝给我们提供的AP ...

  4. java在线支付---09,10,11,12_在线支付_分析易宝支付网关的应答协议与处理代码,完成用于处理支付响应的Servlet的初步编写和调试,完成处理支付网关响应结果的Servlet,支付实现

    09_在线支付_分析易宝支付网关的应答协议与处理代码 创梦综合技术qq交流群:CreDream:251572072 对支付结果返回的数据加密生成md5-hmac public static boole ...

  5. 【CSDN英雄会】 易宝支付架构师、移动产品线技术负责人程超:走在Java的路上

    英雄会是CSDN旗下针对国内IT技术领域专家展示和交流的平台.通过线下线上的互动形式,为CSDN社区专家提供更多学习.合作.宣传的机会.英雄会后续将在北上广深等国内一二线城市建立分会,各个分会后期将组 ...

  6. java在线支付---03_分析易宝支付网关的请求协议

    03_分析易宝支付网关的请求协议 创梦综合技术qq交流群:CreDream:251572072 -------------------------------------- 1.buildHmac() ...

  7. java实现易宝支付

    易宝支付: 1.环境搭建: Java使用Servlet或者springMVC,使用maven进行环境搭建. 2.添加jar包: <dependencies> <dependency& ...

  8. 第三方支付平台:易宝支付

    国付宝国企 LianLianPay连连支付 这个比较好用,可以自己试试 我这里说的是易宝支付 两种在线支付的方式 在线支付一共有两种方式: 电商直接与银行对接: 电商通过第三方支付平台与银行对接: 电 ...

  9. 在线支付(易宝支付)

    第三方支付方式:易宝支付. 支付过程图解: 相关资料: 易宝支付产品通用接口帮助文档点击打开链接 使用步骤:     ①src下面放入支付测试用的merchantInfo.properties(包含商 ...

最新文章

  1. 前端工程化工具Fekit分析
  2. Python 技术篇-使用opencv读取图片实例演示,python安装opencv库
  3. hihocoder 1260
  4. apache日志 waf_WAF对WebShell流量检测的性能分析
  5. c++游戏代码坦克大作战_一红一蓝多种模式的双人小游戏:红蓝大作战
  6. 动态规划训练13 [Catch That Cow poj3278]
  7. c简单的链表错误及改正
  8. 【机器学习】sclearn分类算法-决策树、随机森林
  9. jQuery教程07-内容筛选选择器
  10. VS2015 中使用 MVC4
  11. python2和python3的默认编码_Python2和Python3中的字符串编码问题解决
  12. Atitit 发帖机实现(4 )- usbQBM1601 gui操作标准化规范与解决方案attilax总结
  13. python实例100例下载-Python的100个练习实例免费下载
  14. 文件后缀名查询(全)
  15. 通用能力-《即兴演讲》-樊登读书总结
  16. 如何通过努力出书,如何写有畅销资质的书,本文汇集了多位计算机图书作者的经验...
  17. 2021年N1叉车司机考试总结及N1叉车司机操作证考试
  18. 基于普中A2开发板(STC80C51单片机)呈现的中断小实验代码电路及其效果。
  19. ofo小黄车骑车券无条件领取,人人有份!
  20. 再Windows下 .Pages格式怎么保存为word或者PDF格式

热门文章

  1. 店盈通:拼多多一个店铺推几个产品最好
  2. 魔兽世界 Mangos Trinity TrinityCore 数据库 结构 大纲
  3. python比例图_python在地图上画比例的实例详解
  4. [面试题]自己边面试边总结的Java开发工程师笔记
  5. 使用Toad导入dmp数据
  6. 计算机网络管理技师代号,计算机网络管理技师复习资料.doc
  7. 生成一个简版导游地图
  8. 全国专业技术人员计算机应用能力考试广东,广东省人事厅关于全国专业技术人员计算机应用能力考试扩充科目(模块)有关问题的通知...
  9. 数据分析---常用业务运营指标
  10. 蜘蛛爬行html语言的顺序,搜索引擎蜘蛛爬行的规律是什么?