Maven整合SSM和建行龙支付

  之前也用PHP对接建行的H5龙之付,但建行的支付手册对于PHP版本仅支持windows2003的服务器环境,所以处理到建行支付回调时便搁浅了,这次Java开发的商品支付分期同样需要跟建行龙支付对接,换汤不换药

开发前准备
建行龙支付需要先下载E路护航软件,然后安装相应的证书文件,最后登陆建行网站支付设置后台,
安全证书
登陆后设置建行支付网页回调和服务器回调
网页回调和服务器回调
建行龙支付需要引入建行自带的第三方jar包用于支付回掉的签名认证

mvn install:install-file -Dfile=C:\Users\Administrator\Desktop\netpay.jar -DgroupId=CCBSign -DartifactId=RSASig -Dversion=1.0 -Dpackaging=jar
其中,-Dfile参数指你自定义JAR包文件所在的路径,并依次指定了自定义的GroupId、ArtifactId和Version信息
可以看到本地maven包路径中生成


建行支付回调签名jar包
pom.xml
        
        
            CCBSign
            RSASig
            1.0
        
建行支付工具类
package com.shadmin.common.util;

public class CCBPayUtil {
    private static String BANKURL = "https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain"; //龙支付url
    //无论有无值都需要参与mac运算的参数
    private static String MERCHANTID = "必填"; //商户代码 //注意,这里有坑,MERCHANTID需要传的值,文档写的是商户代码,网上找有demo也是传商户代码,找建行技术员咨询也是跟我说传商户代码,但经过多次测试,这里需要传递的却是商户编号
    private static String POSID = "必填"; //商户柜台代码
    private static String BRANCHID = "必填"; //分行代码
    private static String ORDERID = "必填"; //支付编号
    private static String PAYMENT = "必填"; //付款金额
    private static String CURCODE = "01"; //币种01为人民币
    private static String TXCODE = "520100"; //交易码 由建行统一分配为520100
    private static String REMARK1 = "";
    private static String REMARK2 = "";
    private static String TYPE = "1"; //接口类型
    private static String PUB = "必填"; //公钥后30位
    private static String GATEWAY = ""; //网关类型
    private static String CLIENTIP = "";//客户端IP
    private static String REGINFO = ""; //客户注册信息
    private static String PROINFO = ""; //客户注册信息
    private static String REFERER = ""; //商品信息
    //无论有无值都需要参与mac运算的参数-完

    //有值时才参与mac运算的参数
    private static String INSTALLNUM = null;//信用卡支付分期期数,必须为大于1的整数,当分期期数为空或无该字段上送时,则视为普通的网上支付
    private static String TIMEOUT = "";//订单超时时间 格式:YYYYMMDDHHMMSS 银行系统时间> TIMEOUT时拒绝交易,若送空值则不判断超时。
    private static String ISSINSCODE = ""; //银行代码 仅对PC跨行生效,手机跨行无需上送该字段

    //二级商户信息,若上送二级商户信息则八个二级商户信息字段必须都送值
    private static String SMERID = ""; //二级商户代码
    private static String SMERNAME = ""; //二级商户名称
    private static String SMERTYPEID = ""; //二级商户类别代码
    private static String SMERTYPE = ""; //二级商户类别名称
    private static String TRADECODE = ""; //交易类型代码
    private static String TRADENAME = ""; //交易类型名称
    private static String SMEPROTYPE = ""; //商品类别代码
    private static String PRONAME = ""; //商品类别名称

    private String THIRDAPPINFO = "android时必需填,可以是任意字符串,获取支付结果时会用到";//当该字段有值时,则会优先启动建行APP支付,否则优先启动h5页面支付。
    //有值时才参与mac运算的参数-完

    /**
     * 类初始化函数
     */
    public CCBPayUtil(String merchant_id,String post_id, String branch_id, String pub){

        MERCHANTID = merchant_id;   //商户代码(由建行统一分配)
        POSID = post_id;                //商户柜台代码(由建行统一分配)
        BRANCHID = branch_id;       //分行代码(由建行统一分配)
        PUB = pub.substring(pub.length()-30);                   //公钥后30位(仅作为源串参加MD5摘要,不作为参数传递)

    }

    /**
     * 参数校验生成MAC
     * @return string 生成的MAC码
     */
    private static String makeMAC(){
       String param = "MERCHANTID="+MERCHANTID+"&POSID="+POSID+"&BRANCHID="+BRANCHID+"&ORDERID="+ORDERID
                +"&PAYMENT="+PAYMENT+"&CURCODE="+CURCODE+"&TXCODE="+TXCODE+"&REMARK1="+REMARK1+"&REMARK2="+REMARK2
               +"&TYPE="+TYPE+"&PUB="+PUB+"&GATEWAY="+GATEWAY+"&CLIENTIP="+CLIENTIP+"®INFO="+REGINFO+"&PROINFO="+PROINFO
               +"&REFERER="+REFERER;
       //选填参数,分期
        if(INSTALLNUM != null && !INSTALLNUM.equals("")){
           param += "&INSTALLNUM="+INSTALLNUM;
       }

        return Md5Util.md5(param);
    }

    /**
     * 参数校验拼接url
     * @param  mac 编码
     * @return [type] [description]
     */
    private static String buildUrlParam(String mac){
        String param = "MERCHANTID="+MERCHANTID+"&POSID="+POSID+"&BRANCHID="+BRANCHID+"&ORDERID="+ORDERID
                +"&PAYMENT="+PAYMENT+"&CURCODE="+CURCODE+"&TXCODE="+TXCODE+"&REMARK1="+REMARK1+"&REMARK2="+REMARK2
                +"&TYPE="+TYPE+"&GATEWAY="+GATEWAY+"&CLIENTIP="+CLIENTIP+"®INFO="+REGINFO+"&PROINFO="+PROINFO
                +"&REFERER="+REFERER;
        //选填参数,分期
        if(INSTALLNUM != null && !INSTALLNUM.equals("")){
            param += "&INSTALLNUM="+INSTALLNUM;
        }
        param += "&MAC="+mac;
        return param;

    }

    /**
     *
     * @param order_id 订单编号(由商户提供,最长30位)
     * @param pay_ment 支付金额
     * @param install_num 建行跳转到的url
     * @return
     */
    public static String CCBOrder(String order_id,String pay_ment, String install_num){

        ORDERID = order_id;
        PAYMENT = pay_ment;
        INSTALLNUM = install_num;
        //生成MAC
        String mac = makeMAC();
        //构建url参数
        String urlParam = buildUrlParam(mac);
        //建行H5跳转网址

        String url = BANKURL+"?"+urlParam;

        return url;

    }
}
生成支付页面的H5链接
    /**
     *  添加分期订单
     */
    @RequestMapping(value = "doAddStagingOrder.htm", method = RequestMethod.POST)
    public @ResponseBody JSONObject doAddStagingOrder(HttpServletRequest request){
        Map params = new HashMap();
        String ext_code = request.getParameter("ext_code");
        params.put("ext_code", ext_code);
        String pro_info = request.getParameter("pro_info"); //订单信息
        params.put("pro_info", pro_info);
        String pay_ment = request.getParameter("pay_ment"); //分期金额
        params.put("pay_ment", pay_ment);
        String install_num = request.getParameter("install_num");   //分期期数
        params.put("install_num", install_num);
        String date = String.valueOf(new Date().getTime());
        String random = String.valueOf((int)(Math.random()*10000000));
        String order_no = date.concat(random);
        params.put("order_no", order_no);
        //写入到分期订单表
        int res = jiangxiStagingOrderService.addStagingOrder(params);
        JSONObject jsonObject = new JSONObject();
        if(res>0){
            new CCBPayUtil(你的Merchant_id, 你的getPost_id, 你的getBranch_id, 你的getPub_key);
            String url = CCBPayUtil.CCBOrder(order_no, pay_ment, install_num);
            jsonObject.put("code", 1);
            jsonObject.put("message","生成订单成功");
            jsonObject.put("data", url);
        }else{
            //生成订单失败
            jsonObject.put("code", -1);
            jsonObject.put("message", "生成订单失败");
        }

        return jsonObject;
    }
建行龙支付服务器回调
package com.shadmin.web.jiangxi;

import CCBSign.RSASig;
import com.alibaba.fastjson.JSONObject;
import com.shadmin.common.util.CCBPayUtil;
import com.shadmin.common.util.Md5Util;
import com.shadmin.entity.JiangxiMerchant;
import com.shadmin.entity.JiangxiStagingOrder;
import com.shadmin.service.jiangxi.JiangxiMerchantService;
import com.shadmin.service.jiangxi.JiangxiStagingOrderService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
@RequestMapping("/jiangxi/")
public class MobileJiangxiController{
    private static org.apache.log4j.Logger logger = Logger.getLogger(MobileJiangxiController.class);
    /**
     * 分期订单回调修改订单状态
     */
    @RequestMapping("updateStagingOrder.htm")
    public @ResponseBody JSONObject updateStagingOrder(HttpServletRequest request){
        //枚举的形式打印所有的reques返回值,并记录日志
        Enumeration parameterNames = request.getParameterNames();
        StringBuffer stringBuffer = new StringBuffer();
        while (parameterNames.hasMoreElements()){
            String parameter = parameterNames.nextElement();
            stringBuffer.append(parameter + "=" + request.getParameter(parameter)+"———");
        }
        logger.info("龙支付回调传参:"+stringBuffer);

        //获取request龙支付传参POSID...参数和sign,并拼接校验的strSrc串
        StringBuffer strSrc = new StringBuffer();
        strSrc.append("POSID=" + request.getParameter("POSID"));
        strSrc.append("&BRANCHID=" + request.getParameter("BRANCHID"));
        strSrc.append("&ORDERID=" + request.getParameter("ORDERID"));
        strSrc.append("&PAYMENT=" + request.getParameter("PAYMENT"));
        strSrc.append("&CURCODE=" + request.getParameter("CURCODE"));
        strSrc.append("&REMARK1=" + request.getParameter("REMARK1"));
        strSrc.append("&REMARK2=" + request.getParameter("REMARK2"));
        strSrc.append("&ACC_TYPE=" + request.getParameter("ACC_TYPE"));
        strSrc.append("&SUCCESS=" + request.getParameter("SUCCESS"));
        strSrc.append("&TYPE=" + request.getParameter("TYPE"));
        strSrc.append("&REFERER=" + request.getParameter("REFERER"));
        strSrc.append("&CLIENTIP=" + request.getParameter("CLIENTIP"));
        strSrc.append("&ACCDATE=" + request.getParameter("ACCDATE"));
        if (request.getParameter("INSTALLNUM") != null) {
            strSrc.append("&INSTALLNUM=" + request.getParameter("INSTALLNUM"));
        }
        String strSign=request.getParameter("SIGN");

//        //将龙支付的src(query string)转成map
//        String[] strs = strSrc.split("&");
//        Map map = new HashMap();
//        for (String s : strs) {
//            String[] ms = s.split("=");
//            map.put(ms[0], ms[1]);
//        }

        //以下基于龙支付返回以上strSrc和strPubKey字符串数据处理
        Map params = new HashMap();
        String status = "0";
        params.put("status", status);
        String order_no = request.getParameter("ORDERID");   //获取strSrc中的ORDERID
        params.put("order_no", order_no);
        List orderList = jiangxiStagingOrderService.getStagingOrderList(params);
        JSONObject jsonObject = new JSONObject();
        if(orderList != null && orderList.size() > 0){
            //第一步:订单有效,调用银行三方类校验签名
            String ext_code = orderList.get(0).getExt_code();   //获取该订单的推广码
            List merchant = jiangxiMerchantService.getMerchantListToJiangxi(new HashMap() {{
                put("ext_code", ext_code);
            }});
            String pub_key = merchant.get(0).getPub_key();  //获取商户的龙支付密钥
            //引入银行第三方类用来校验签名
            RSASig rsa = new RSASig();
            rsa.setPublicKey(pub_key);
            if(rsa.verifySigature(strSign, strSrc.toString())&& request.getParameter("SUCCESS").equals("Y")){
                //第二步:比较strSrc中的PAYMENT是否与数据库中的金额一致
                if (Double.parseDouble(orderList.get(0).getPay_ment()) == Double.parseDouble(request.getParameter("PAYMENT"))) {
                    params.put("status", "1");
                    jiangxiStagingOrderService.updateStagingOrder(params);
                    jsonObject.put("code", 1);
                    jsonObject.put("message", "order_no:" + order_no + "龙支付成功");
                    logger.info("龙支付:成功修改订单order_no:" + order_no);
                } else {
                    jsonObject.put("code", 0);
                    jsonObject.put("message", "订单价格被篡改:数据库价格pay_ment=" + orderList.get(0).getPay_ment() + ";龙支付回调价格PAYMENT:" + request.getParameter("PAYMENT") + ";或者订单回调SUCCESS=" + request.getParameter("SUCCESS"));
                    logger.info("龙支付:订单价格被篡改:数据库价格pay_ment=" + orderList.get(0).getPay_ment() + ";龙支付回调价格PAYMENT:" + request.getParameter("PAYMENT") + ";或者订单回调SUCCESS=" + request.getParameter("SUCCESS"));
                }
            }else {
                jsonObject.put("code", 0);
                jsonObject.put("message", "签名校验失败");
                logger.info("龙支付:签名校验失败");
            }
        }else{
            jsonObject.put("code", 0);
            jsonObject.put("message", "无效订单或已完成订单");
            logger.info("龙支付:无效订单或已完成订单");
        }

        return jsonObject;
    }
}
参考路径

本来是由1,2,3的指导,目前只剩下3了
android 建行龙支付教程3:从建行app获取支付结果
maven怎么 引入(或引用/使用) 自定义(或本地/第三方) jar的三种方式 图文教程

你可能感兴趣的:(Maven整合SSM和建行龙支付)