微信支付-掃碼支付、小程序支付和微信h5支付

今年做了微信支付項目包括微信掃碼支付、微信小程序支付和微信h5支付。

現在總結如下:

1、pom.xml

<?xml version="1.0"?>

<dependency>

<groupId>com.github.wxpay</groupId>

<artifactId>wxpay-sdk</artifactId>

<version>0.0.3</version>

</dependency>

2、配置文件

2.1 掃碼支付配置文件

public class PayConfigUtil implements Serializable {
	//初始化
	public final static String APP_ID = "==============";//公衆賬號appid(改爲自己實際的)
	//public final static String APP_SECRET = "";//"";
	public final static String MCH_ID = "===========";//商戶號(改爲自己實際的)
	public final static String API_KEY = "=================";//(改爲自己實際的)key設置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置
	
	//有關url
	public final static String UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	public final static String NOTIFY_URL = "https://=====================/Wxpay/weixinNotify.do"; //微信支付回調接口,就是微信那邊收到(改爲自己實際的)
	
	public static String CREATE_IP = "";//發起支付ip(改爲自己實際的)
}

2.2 微信小程序配置文件

public class XcxPayConfig {
    //小程序appid
    public static final String appid = "===============";
    //微信支付的商戶id
    public static final String mch_id = "==================";
    //微信支付的商戶密鑰
    public static final String key = "====================";
    //小程序secret
    public static final String secret="===================";
    //支付成功後的服務器回調url
    public static final String notify_url = "https://====================/Wxpay/xcxNotify";
    //簽名方式,固定值
    public static final String SIGNTYPE = "MD5";
    //交易類型,小程序支付的固定值爲JSAPI
    public static final String TRADETYPE = "JSAPI";
    //微信統一下單接口地址
    public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
}

2.3 微信H5支付配置文件

public class H5payConfig {
    //初始化
    public final static String APP_ID = "wx============";//; //公衆賬號appid(改爲自己實際的)
    public final static String APP_SECRET = "=============";//;
    public final static String MCH_ID = "==========";//; //商戶號(改爲自己實際的)
    public final static String API_KEY = "================";//; //(改爲自己實際的)key設置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置

    //有關url
    public final static String UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//統一下單
    public final static String QURODER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";//訂單查詢
    public final static String NOTIFY_URL = "https://========/Wxpay/h5Notify"; //微信支付回調接口,就是微信那邊收到(改爲自己實際的)
    public final static String REDIRECT_URL = "https://========/Wxpay/h5Redirect"; //微信支付回調接口,就是微信那邊收到(改爲自己實際的)
}

3、Controller

3.1、掃碼支付

/**
     * 掃碼支付 生成二維碼
     * @param request
     * @param response
     * @param modelMap
     */
    @ResponseBody
    @RequestMapping("/qrcode.do")
    public void qrcode(HttpServletRequest request, HttpServletResponse response,
                       ModelMap modelMap) {
        try {
            String amount = request.getParameter("amount");
            String productId = request.getParameter("productId");
            String userId= request.getParameter("userId");
            String businessId = request.getParameter("businessId");
            String userType = request.getParameter("userType");
            String ip = getIpAddress(request);
            String text = codeService.weixinPay(ip,amount, productId,userId,businessId,userType);

            int width = 300;
            int height = 300;
            //二維碼的圖片格式
            String format = "gif";
            Hashtable hints = new Hashtable();
            //內容所使用編碼
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            BitMatrix bitMatrix = null;
            try {
                bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
                QRUtil.writeToStream(bitMatrix, format, response.getOutputStream());
            } catch (WriterException e) {
                e.printStackTrace();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 掃碼支付 獲取IP本機IP地址
     * @param request
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.contains(",")) {
            return ip.split(",")[0];
        } else {
            return ip;
        }
    }
    /**
     * 掃碼支付 是否支付成功
     * @param request
     * @param response
     * @param modelMap
     * @return
     */
    @ResponseBody
    @RequestMapping("/hadPay.do")
    public Map<String, Object> hadPay(HttpServletRequest request, HttpServletResponse response,
                                      ModelMap modelMap) {
        try {
            //簡單的業務邏輯:在微信的回調接口裏面,已經定義了,回調返回成功的話,那麼 _PAY_RESULT 不爲空
            if(request.getSession().getAttribute("_PAY_RESULT") != null ){
                return success("支付成功!");
            }
            return error("沒成功");
        } catch (Exception e) {
            return error(e);
        }
    }
    /**
     * 掃碼支付 成功信息
     * @param request
     * @param response
     * @param modelMap
     * @return
     */
    protected Map<String, Object> success(Object data) {
        return toMap("data", data, "result", ConstantBean.SUCCESS);
    }
	/**
     * 掃碼支付 失敗信息
     * @param request
     * @param response
     * @param modelMap
     * @return
     */
    protected Map<String, Object> error(Object data) {
        return toMap("data", data, "result", ConstantBean.ERROR);
    }
    /**
     * 掃碼支付 Object轉換爲Map
     * @param request
     * @param response
     * @param modelMap
     * @return
     */
    public static Map toMap(Object... params) {
        Map map = new LinkedHashMap();
        Assert.notNull(params);
        Assert.isTrue(params.length % 2 == 0);
        for (int i = 0; i < params.length; i++) {
            map.put(params[i++], params[i]);
        }
        return map;
    }
    /**
     * 掃碼支付
     * 微信平臺發起的回調方法,
     * 調用我們這個系統的這個方法接口,將掃描支付的處理結果告知我們系統
     * @throws JDOMException
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/weixinNotify.do")
    public void weixinNotify(HttpServletRequest request, HttpServletResponse response) throws JDOMException, Exception{
        //讀取參數
        InputStream inputStream ;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s ;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null){
            sb.append(s);
        }
        in.close();
        inputStream.close();

        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil4jdom.doXMLParse(sb.toString());

        //過濾空 設置 TreeMap
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        if(m==null){
            logger.error("參數爲空值!");
            throw new RuntimeException("參數爲空值!");
        }
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);

            String v = "";
            if(null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 賬號信息
        String key = PayConfigUtil.API_KEY; //key

        //判斷簽名是否正確
        if(PayToolUtil.isTenpaySign("UTF-8", packageParams,key)) {
            //------------------------------
            //處理業務開始
            //------------------------------
            String resXml = "";
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
                // 這裏是支付成功
                //////////執行自己的業務邏輯////////////////
                int i = codeService.updateRechargeInfo(packageParams,"success",(String)packageParams.get("result_code"),"wxPay");
                //////////執行自己的業務邏輯////////////////
                //暫時使用最簡單的業務邏輯來處理:只是將業務處理結果保存到session中
                //(根據自己的實際業務邏輯來調整,很多時候,我們會操作業務表,將返回成功的狀態保留下來)
                request.getSession().setAttribute("_PAY_RESULT", "OK");
                if(i>0){
                    //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    logger.debug("支付成功");
                }else{
                    //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
                    logger.debug("支付失敗");
                }
            } else {
                codeService.updateRechargeInfo(packageParams,"fail",(String)packageParams.get("result_code"),"wxPay");
                //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
            }
            //------------------------------
            //處理業務完畢
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } else{
            logger.debug("通知簽名驗證失敗");
			//System.out.println("通知簽名驗證失敗");
        }

    }

3.2 小程序微信支付

/**
     * 小程序支付
     * 下單支付
     * @param openid
     * @param request
     * @return
     */
    @RequestMapping("xcxPay")
    @ResponseBody
    public JsonMsg xcxPay(String openid, HttpServletRequest request){
        JsonMsg json = new JsonMsg();
        try{
            if(openid == null || ("").equals(openid)){
                json.setSuccess(false);
                json.setMsg("參數openid不能爲空!");
                return json;
            }
            //商品名稱
            String body = request.getParameter("body");
            //支付金額,單位:分,這邊需要轉成字符串類型,否則後面的簽名會失敗
            String money = request.getParameter("money");
            if(money == null || ("").equals(money)){
                json.setSuccess(false);
                json.setMsg("參數money不能爲空!");
                return json;
            }
            String businessId = request.getParameter("businessId");
            String userType = request.getParameter("userType");
            String userId = request.getParameter("userId");
            String orderCode = request.getParameter("orderCode");

            //插入 PrechargeRecords 表,並生成 out_trade_no
            String orderNo = codeService.getOrderNo(openid,body,money,businessId,userType,userId,orderCode);
            //生成的隨機字符串
            String nonce_str = StringUtils.getRandomStringByLength(32);
            //獲取本機的ip地址
            String spbill_create_ip = IpUtils.getIpAddr(request);

            Map<String, String> packageParams = new HashMap<String, String>();
            packageParams.put("appid", XcxPayConfig.appid);
            packageParams.put("mch_id", XcxPayConfig.mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", orderNo.split(",")[0]);//商戶訂單號
            packageParams.put("total_fee", getAmount(money).toString());//支付金額,這邊需要轉成字符串類型,否則後面的簽名會失敗
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", XcxPayConfig.notify_url);
            packageParams.put("trade_type", XcxPayConfig.TRADETYPE);
            packageParams.put("openid", openid);

            // 除去數組中的空值和簽名參數
            packageParams = PayUtil.paraFilter(packageParams);
            String prestr = PayUtil.createLinkString(packageParams); // 把數組所有元素,按照“參數=參數值”的模式用“&”字符拼接成字符串

            //MD5運算生成簽名,這裏是第一次簽名,用於調用統一下單接口
            String mysign = PayUtil.sign(prestr, XcxPayConfig.key, "utf-8").toUpperCase();
            logger.info("=======================第一次簽名:" + mysign + "=====================");

            //拼接統一下單接口使用的xml數據,要將上一步生成的簽名一起拼接進去
            String xml = "<xml>" + "<appid>" + XcxPayConfig.appid + "</appid>"
                    + "<body><![CDATA[" + body + "]]></body>"
                    + "<mch_id>" + XcxPayConfig.mch_id + "</mch_id>"
                    + "<nonce_str>" + nonce_str + "</nonce_str>"
                    + "<notify_url>" + XcxPayConfig.notify_url + "</notify_url>"
                    + "<openid>" + openid + "</openid>"
                    + "<out_trade_no>" + orderNo.split(",")[0] + "</out_trade_no>"
                    + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
                    + "<total_fee>" + getAmount(money).toString() + "</total_fee>"
                    + "<trade_type>" + XcxPayConfig.TRADETYPE + "</trade_type>"
                    + "<sign>" + mysign + "</sign>"
                    + "</xml>";

            System.out.println("調試模式_統一下單接口 請求XML數據:" + xml);

            //調用統一下單接口,並接受返回的結果
            String result = PayUtil.httpRequest(XcxPayConfig.pay_url, "POST", xml);

            System.out.println("調試模式_統一下單接口 返回XML數據:" + result);

            // 將解析結果存儲在HashMap中
            Map map = PayUtil.doXMLParse(result);

            String return_code = (String) map.get("return_code");//返回狀態碼

            //返回給移動端需要的參數
            Map<String, Object> response = new HashMap<String, Object>();
            if(return_code == "SUCCESS" || return_code.equals("SUCCESS")){
                // 業務結果
                String prepay_id = (String) map.get("prepay_id");//返回的預付單信息
                response.put("nonceStr", nonce_str);
                response.put("package", "prepay_id=" + prepay_id);
                Long timeStamp = System.currentTimeMillis() / 1000;
                response.put("timeStamp", timeStamp + "");//這邊要將返回的時間戳轉化成字符串,不然小程序端調用wx.requestPayment方法會報簽名錯誤

                String stringSignTemp = "appId=" + XcxPayConfig.appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id+ "&signType=" + XcxPayConfig.SIGNTYPE + "&timeStamp=" + timeStamp;
                //再次簽名,這個簽名用於小程序端調用wx.requesetPayment方法
                String paySign = PayUtil.sign(stringSignTemp, XcxPayConfig.key, "utf-8").toUpperCase();
                logger.info("=======================第二次簽名:" + paySign + "=====================");
                response.put("signType",XcxPayConfig.SIGNTYPE);
                response.put("paySign", paySign);
//                response.put("appid", XcxPayConfig.appid);

                if(orderCode!=null&&!orderCode.equals("")) {//繼續支付
                    if(orderNo.split(",")[0].length()>0&&orderNo.split(",")[1].length()>0){
                        json.setSuccess(true);
                        json.setData(response);
                        return json;
                    }else{
                        json.setSuccess(false);
                        json.setData("orderNo不正確!");
                        return json;
                    }
                }else{//支付
                    //更新訂單信息
                    FinWeixinRecord f = new FinWeixinRecord();
                    f.setAppId(packageParams.get("appid"));
                    f.setMchId(packageParams.get("mch_id"));
                    f.setNonchStr(packageParams.get("nonce_str"));
                    f.setOutTradeNo(packageParams.get("out_trade_no"));
                    f.setTradeType("JSAPI");
                    f.setPrePayId(prepay_id);
                    f.setTotalFee(Long.parseLong(packageParams.get("total_fee")));
                    f.setBody("xcxPay");
                    f.setOpenId(packageParams.get("openid"));
                    f.setSpbllCreateIp(packageParams.get("spbill_create_ip"));
                    f.setGmtCreate(new Date());
                    f.setCreateUser(userId);
                    f.setOrderId(orderNo.split(",")[1]);
                    int i = codeService.xcxPay(f);

                    //業務邏輯代碼
                    if(i>0){
                        json.setSuccess(true);
                        json.setData(response);
                        return json;
                    }else{
                        json.setSuccess(false);
                        json.setData("更新訂單信息出錯!");
                        return json;
                    }
                }

            }
            json.setSuccess(false);
            json.setData("returnCode FAIL");
            return json;
        }catch(Exception e){
            e.printStackTrace();
            json.setSuccess(false);
            json.setMsg("發起失敗");
        }
        return null;
    }
    /**
     * 小程序支付 金額單位轉換爲分
     * 更新訂單信息
     * @String recAmount
     */
    private Integer getAmount(String recAmount){
        return new BigDecimal(recAmount).multiply(new BigDecimal(100)).intValue();
    }
    /**
     * 小程序支付
     * 更新訂單信息
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value="/xcxNotify")
    @ResponseBody
    public void xcxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
            sb.append(line);
        }
        br.close();
        //sb爲微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        //System.out.println("接收到的報文:" + notityXml);
        logger.info("接收到的報文:" + notityXml);

        Map map = PayUtil.doXMLParse(notityXml);
        String returnCode = null;
        String sign = map.get("sign").toString();
        map.remove("sign");
        if(map!=null){
            returnCode = (String) map.get("return_code");
        }
        if(returnCode != null && "SUCCESS".equals(returnCode)){
            //驗證簽名是否正確
            if(PayUtil.verify(PayUtil.createLinkString(map), sign, XcxPayConfig.key, "utf-8")){
                /**此處添加自己的業務邏輯代碼start**/
                int i = codeService.updateRechargeInfo(map,"SUCCESS",(String)map.get("return_code"),"xcxPay");
                /**此處添加自己的業務邏輯代碼end**/
                if(i>0){
                    //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    logger.info("支付成功");
                }else{
                    //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
                    logger.info("支付失敗");
                }
                //                //通知微信服務器已經支付成功
                //                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                //                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }else{
                logger.info("小程序驗籤失敗!");
            }
        }else{
            if(map!=null) {
                codeService.updateRechargeInfo(map, "FAIL", (String) map.get("result_code"), "xcxPay");
            }
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
        }
        //        System.out.println(resXml);
        //        System.out.println("微信支付回調數據結束");
        logger.info(resXml);
        logger.info("微信支付回調數據結束");

        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    /**
     * 小程序支付
     * 小程序登錄獲取openId
     * @param code
     * @param request
     * @return
     * @throws WeixinException
     * @throws IOException
     */
    @RequestMapping("login")
    @ResponseBody
    public Map<String, Object> login(String code, HttpServletRequest request) throws WeixinException, IOException {
        if (code == null || code.equals("")) {
            throw new WeixinException("invalid null, code is null.");
        }

        Map<String, Object> ret = new HashMap<String, Object>();
        //拼接參數
        String param = "?grant_type=" + grant_type + "&appid=" + XcxPayConfig.appid + "&secret=" + XcxPayConfig.secret + "&js_code=" + code;

        //創建請求對象
        HttpsClient http = new HttpsClient();
        //調用獲取access_token接口
        Response res = http.get("https://api.weixin.qq.com/sns/jscode2session" + param);
        //根據請求結果判定,是否驗證成功
        JSONObject jsonObj = res.asJSONObject();
        if (jsonObj != null) {
            Object errcode = jsonObj.get("errcode");
            if (errcode != null) {
                //返回異常信息
                throw new WeixinException(errcode.toString());
            }

            ObjectMapper mapper = new ObjectMapper();
            OAuthJsToken oauthJsToken = mapper.readValue(jsonObj.toJSONString(),OAuthJsToken.class);

            logger.info("openid=" + oauthJsToken.getOpenid());
            ret.put("openid", oauthJsToken.getOpenid());
        }
        return ret;
    }

3.3 微信H5支付

/**
     * 微信H5支付
     * @param request
     * @param response
     * @param model
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/h5Pay")
    public JsonMsg h5Pay(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
        JsonMsg json = new JsonMsg();
        int tag = 0;//初始化
        //商品名稱
        String subject = request.getParameter("body");//前端上送的支付主題
        if("小順管家代發快遞充值".equals(subject)){
            tag = 1;
        }else if("小順管家驛站短信充值".equals(subject)){
            tag = 2;
        }else{
            tag = 3;//缺少主題
        }
        //支付金額,單位:分,這邊需要轉成字符串類型,否則後面的簽名會失敗
        String total_amount = request.getParameter("money");//前端上送的支付金額
        if(total_amount == null || ("").equals(total_amount)){
            json.setSuccess(false);
            json.setMsg("參數money不能爲空!");
            return json;
        }
        String businessId = request.getParameter("businessId");
        String userType = request.getParameter("userType");
        String userId = request.getParameter("userId");
        String token = request.getParameter("token");
        if(token == null || ("").equals(token)){
            json.setSuccess(false);
            json.setMsg("參數token不能爲空!");
            return json;
        }
        logger.info("pay_toke="+token);
        String orderCode = request.getParameter("orderCode");//繼續支付

        String APPID = H5payConfig.APP_ID;
        String MERID = H5payConfig.MCH_ID;
        String SIGNKEY = H5payConfig.APP_SECRET;
        String spbill_create_ip = getIpAddress(request);//生產
        logger.info("spbill_create_ip="+spbill_create_ip);
        //String spbill_create_ip = "";//測試地址,也就是本地真是ip,用於本地測試用
        String scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"www.rrsjk.com\",\"wap_name\": \"樂農支付\"}}";//我這裏是網頁入口,app入口參考文檔的安卓和ios寫法
        String tradeType = "MWEB";//H5支付標記
        String MD5 = "MD5";//雖然官方文檔不是必須參數,但是不送有時候會驗籤失敗
        //金額轉化爲分爲單位 微信支付以分爲單位
        String finalmoney = com.haier.util.h5pay.StringUtils.getMoney(total_amount);
        //插入 PrechargeRecords 表,並生成 out_trade_no
        String orderNo = codeService.getOrderNo(null,subject,total_amount,businessId,userType,userId,orderCode);
        String out_trade_no = orderNo.split(",")[0];
        //隨機數
        String nonce_str= com.haier.util.h5pay.MD5Utils.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
        //簽名數據
        StringBuilder sb = new StringBuilder();
        sb.append("appid="+APPID);
        sb.append("&body="+subject);
        sb.append("&mch_id="+MERID);
        sb.append("&nonce_str="+nonce_str);
        sb.append("&notify_url="+H5payConfig.NOTIFY_URL);
        sb.append("&out_trade_no="+out_trade_no);
        sb.append("&scene_info="+scene_info);
        sb.append("&sign_type="+"MD5");
        sb.append("&spbill_create_ip="+spbill_create_ip);
        sb.append("&total_fee="+finalmoney);
        sb.append("&trade_type="+tradeType);
        sb.append("&key="+H5payConfig.API_KEY);
        logger.info("sb="+sb);
        //簽名MD5加密
        String sign = com.haier.util.wxpay.MD5Util.MD5Encode(sb.toString(),"utf-8").toUpperCase();
        logger.info("sign="+sign);
        logger.info("簽名數據:"+sign);
        //封裝xml報文
        String xml="<xml>"+
                "<appid>"+ APPID+"</appid>"+
                "<body>"+subject+"</body>"+//
                "<mch_id>"+ MERID+"</mch_id>"+
                "<nonce_str>"+nonce_str+"</nonce_str>"+
                "<notify_url>"+H5payConfig.NOTIFY_URL+"</notify_url>"+
                "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                "<scene_info>"+scene_info+"</scene_info>"+
                "<sign>"+sign+"</sign>"+
                "<sign_type>MD5</sign_type>"+
                "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
                "<total_fee>"+Integer.parseInt(finalmoney)+"</total_fee>"+//
                "<trade_type>"+tradeType+"</trade_type>"+
                "</xml>";

        String createOrderURL = H5payConfig.UFDODER_URL;//微信統一下單接口
        String mweb_url = "";
        Map map = new HashMap();
        String callBackUrl = H5payConfig.REDIRECT_URL;
        logger.info("微信支付回調鏈接爲:" + callBackUrl);
        try {
             //預下單 獲取接口地址
            map = com.haier.util.h5pay.WebUtils.getMwebUrl(createOrderURL, xml);
            String return_code  = (String) map.get("return_code");
            String return_msg = (String) map.get("return_msg");
            if("SUCCESS".equals(return_code) && "OK".equals(return_msg)){

                FinWeixinRecord f = new FinWeixinRecord();
                f.setAppId(APPID);
                f.setMchId(MERID);
                f.setNonchStr(nonce_str);
                f.setOutTradeNo(out_trade_no);
                f.setTradeType(tradeType);
                f.setPrePayId((String) map.get("prepay_id"));
                f.setTotalFee(Long.parseLong(finalmoney));
                f.setBody(subject);
                f.setSpbllCreateIp(spbill_create_ip);
                f.setGmtCreate(new Date());
                f.setCreateUser(userId);
                f.setOrderId(orderNo.split(",")[1]);
                int i = codeService.h5Pay(f);
                if(i>0) {
                    mweb_url = (String) map.get("mweb_url");//調微信支付接口地址
                    if (!"".equals(callBackUrl)) {
                        callBackUrl += "?out_trade_no="+out_trade_no+"&token="+token+"&tag="+tag;
                        callBackUrl = URLEncoder.encode(callBackUrl, "UTF-8");
                        mweb_url = mweb_url + "&redirect_url=" + callBackUrl;
                    }
                    logger.info("mweb_url=" + mweb_url);

                    json.setSuccess(true);
                    json.setMsg("<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ");
                    json.setData(mweb_url);
                    logger.info(return_msg);
                }else{
                    json.setSuccess(false);
                    json.setMsg("插入數據庫訂單失敗,out_trade_no="+out_trade_no);
                    json.setData(i);
                    logger.info("插入數據庫訂單失敗");
                }
                return json;

            }else{
                logger.info("統一支付接口獲取預支付訂單出錯");
                json.setSuccess(false);
                json.setMsg(return_msg);
                json.setData(return_code);
                return json;
            }
        } catch (Exception e) {
            logger.info("統一支付接口獲取預支付訂單出錯");
            json.setSuccess(false);
            json.setMsg("支付錯誤!");
            json.setData(e.getMessage());
            return json;
        }
    }

    /**
     * 微信H5支付回調
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/h5Notify")
    public void h5Notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader reader = request.getReader();
        String line = "";
        Map map = new HashMap();
        String xml = "<xml><return_code><![CDATA[FAIL]]></xml>";;
        JSONObject dataInfo = new JSONObject();
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        request.getReader().close();
        logger.info("----接收到的報文---"+inputString.toString());
        if(inputString.toString().length()>0){
            map = com.haier.util.h5pay.XMLUtils.parseXmlToList(inputString.toString());
        }else{
            logger.info("接受微信報文爲空");
        }
        logger.info("map="+map);
        if(map!=null && "SUCCESS".equals(map.get("result_code"))){
            //成功的業務。。。
            int i = codeService.updateRechargeInfo(map,"SUCCESS",(String)map.get("return_code"),"h5Pay");
            /**此處添加自己的業務邏輯代碼end**/
            if(i>0){
                //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                xml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>"
                        + "<out_trade_no>"+ map.get("out_trade_no") +"</out_trade_no>"
                        + "<transaction_id>"+ map.get("transaction_id") +"</transaction_id>"
                        + "<total_fee>"+ map.get("total_fee") +"</total_fee>"
                        + "</xml> ";
                logger.info("支付成功");
            }else{
                //通知微信.異步確認成功.必寫.不然會一直通知後臺.八次之後就認爲交易失敗了.
                xml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[報文爲空]]></return_msg>"
                        + "<out_trade_no>"+ map.get("out_trade_no") +"</out_trade_no>"
                        + "<transaction_id>"+ map.get("transaction_id") +"</transaction_id>"
                        + "<total_fee>"+ map.get("total_fee") +"</total_fee>"
                        + "</xml> ";
                logger.info("支付失敗");
            }
        }else{
            //失敗的業務。。。
            if(map!=null) {
                codeService.updateRechargeInfo(map, "FAIL", (String) map.get("result_code"), "h5Pay");
            }
            xml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> ";
            logger.info("支付失敗");
        }
        //告訴微信端已經確認支付成功
        response.getWriter().write(xml);
    }

    @RequestMapping(value = "/h5Result/{totalFee}")
    public ModelAndView h5Result(@PathVariable("totalFee") String totalFee){
        ModelAndView mav = new ModelAndView();
        mav.getModel().put("totalFee", totalFee);
        mav.getModel().put("num",-2);
        mav.setViewName("page/paySuccess");
        return mav;
    }

    @RequestMapping(value = "/h5Query")
    @ResponseBody
    public JsonMsg h5Query(HttpServletRequest request, HttpServletResponse response) throws Exception {
        JsonMsg json = new JsonMsg();
        Map map = new HashMap();
        map.put("body",java.net.URLDecoder.decode(request.getParameter("body"),"utf-8"));
        map.put("result_code",request.getParameter("result_code"));
        map.put("return_code",request.getParameter("return_code"));
        map.put("out_trade_no",request.getParameter("out_trade_no"));
        map.put("transaction_id",request.getParameter("transaction_id"));
        map.put("total_fee",request.getParameter("total_fee"));
        logger.info("map="+map);
        if(map!=null && "SUCCESS".equals(map.get("return_code"))){
            json.setSuccess(true);
            json.setMsg("<xml>"
                    + "<result_code>"+map.get("result_code")+"</result_code>"
                    + "<return_code>"+map.get("return_code")+"</return_code>"
                    + "<total_fee>"+ map.get("total_fee") +"</total_fee>"
                    +"</xml> ");
            json.setData("支付成功");
        }else if(map!=null){
            String nonce_str = com.haier.util.h5pay.MD5Utils.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
            //簽名數據
            StringBuilder sb = new StringBuilder();
            sb.append("appid="+H5payConfig.APP_ID);
            sb.append("&mch_id="+H5payConfig.MCH_ID);
            sb.append("&nonce_str="+nonce_str);
            sb.append("&out_trade_no="+map.get("out_trade_no"));
            sb.append("&transaction_id="+map.get("transaction_id"));
            sb.append("&key="+H5payConfig.API_KEY);
            logger.info("sb="+sb);
            //簽名MD5加密
            String sign = com.haier.util.wxpay.MD5Util.MD5Encode(sb.toString(),"utf-8").toUpperCase();
            String xml="<xml>"+
                    "<appid>"+ H5payConfig.APP_ID+"</appid>"+
                    "<mch_id>"+ H5payConfig.MCH_ID+"</mch_id>"+
                    "<nonce_str>"+nonce_str+"</nonce_str>"+
                    "<out_trade_no>"+map.get("out_trade_no")+"</out_trade_no>"+
                    "<transaction_id>"+map.get("transaction_id")+"</transaction_id>"+
                    "<sign>"+sign+"</sign>"+
                    "</xml>";
            String queryOrderURL = H5payConfig.QURODER_URL;
            try{
                Map qmap = new HashMap();
                //查詢訂單
                qmap = com.haier.util.h5pay.WebUtils.getMwebUrl(queryOrderURL, xml);
                if(qmap!=null&&"SUCCESS".equals(qmap.get("return_code"))){
                    if("SUCCESS".equals(qmap.get("result_code"))){
                        if("SUCCESS".equals(qmap.get("trade_state"))){
                            json.setSuccess(true);
                            json.setMsg("<xml>"
                                    + "<body>"+map.put("body",java.net.URLDecoder.decode(request.getParameter("body"),"utf-8"))+"</body>"
                                    + "<trade_state>"+qmap.get("trade_state")+"</trade_state>"
                                    + "<out_trade_no>"+qmap.get("out_trade_no")+"</out_trade_no>"
                                    + "<total_fee>"+ qmap.get("total_fee") +"</total_fee>"
                                    +"</xml> ");
                            json.setData("支付成功");
                        }else{
                            //out_trade_no必須傳回
                            json.setSuccess(true);
                            json.setMsg("<xml>"
                                    + "<body>"+map.put("body",java.net.URLDecoder.decode(request.getParameter("body"),"utf-8"))+"</body>"
                                    + "<trade_state>"+qmap.get("trade_state")+"</trade_state>"
                                    + "<out_trade_no>"+qmap.get("out_trade_no")+"</out_trade_no>"
                                    + "<total_fee>"+ qmap.get("total_fee") +"</total_fee>"
                                    +"</xml> ");
                            json.setData(qmap.get("trade_state"));
                        }
                    }else{
                        //傳回err_code和err_code_des
                        json.setSuccess(false);
                        json.setMsg("<xml>"
                                + "<body>"+map.put("body",java.net.URLDecoder.decode(request.getParameter("body"),"utf-8"))+"</body>"
                                + "<err_code>"+qmap.get("err_code")+"</err_code>"
                                + "<err_code_des>"+qmap.get("err_code_des")+"</err_code_des>"
                                +"</xml> ");
                        json.setData(qmap.get("err_code_des"));
                    }
                }else{
                    json.setSuccess(false);
                    json.setMsg((String) qmap.get("return_msg"));
                    json.setData(new Date());
                }
            }catch (Exception e){
                json.setSuccess(false);
                json.setMsg(e.getMessage());
                json.setData("產生異常");
            }
        }else{
            json.setSuccess(false);
            json.setMsg("報文爲空");
            json.setData("報文爲空");
        }
        return json;
    }

    @RequestMapping(value = "/h5Redirect")
    public ModelAndView h5Redirect(HttpServletRequest request, HttpServletResponse response) throws Exception{
        ModelAndView mav = new ModelAndView();
        Map map = new HashMap();
        String outTradeNo = request.getParameter("out_trade_no").toString();
        String token = URLEncoder.encode(request.getParameter("token").toString());
        String tag = request.getParameter("tag").toString();
        logger.info("redirect_token="+token);
        if(!"".equals(outTradeNo)){
            logger.info("outTradeNo:"+outTradeNo);
            try {
                int index = 0;
                final int count = 8;
                do{
                    index++;
                    logger.info(""+index+" time "+new Date());
                    FinWeixinRecord f = codeService.getFinWeixinRecord(outTradeNo);
                    if("SUCCESS".equals(f.getReturnCode())){
                        String totalFee = f.getTotalFee().toString();
                        Double d = Double.parseDouble(totalFee)/100;
                        BigDecimal b = BigDecimal.valueOf(d).setScale(2,BigDecimal.ROUND_HALF_DOWN);
                        totalFee = b.toString();
                        mav.getModel().put("totalFee", totalFee);
                        mav.getModel().put("body",f.getBody());
                        mav.getModel().put("token",token);
                        mav.getModel().put("num",-1);
                        mav.setViewName("page/paySuccess");
                        index=8;
                    }else{
                        String totalFee = f.getTotalFee().toString();
                        Double d = Double.parseDouble(totalFee)/100;
                        BigDecimal b = BigDecimal.valueOf(d).setScale(2,BigDecimal.ROUND_HALF_DOWN);
                        totalFee = b.toString();
                        mav.getModel().put("return_code",f.getReturnCode());
                        mav.getModel().put("out_trade_no",f.getOutTradeNo());
                        mav.getModel().put("transaction_id",f.getTransactionId());
                        mav.getModel().put("total_fee",totalFee);
                        mav.getModel().put("token",token);
                        if("1".equals(tag)){
                            mav.getModel().put("body","充值");
                        }else if("2".equals(tag)){
                            mav.getModel().put("body","充值");
                        }else{
                            mav.getModel().put("body","充值沒有主題!請聯繫管理員");
                        }
                        mav.getModel().put("num",-2);
                        if(index==8) {
                            mav.setViewName("page/waiting");
                        }
                    }
                    Thread.sleep(5*1000);
                }while(index<count);
            } catch (InterruptedException e) {
                logger.info(e.getMessage());
                mav.getModel().put("num",-2);
                mav.getModel().put("token",token);
                if("1".equals(tag)){
                    mav.getModel().put("body","充值");
                }else if("2".equals(tag)){
                    mav.getModel().put("body","充值");
                }else{
                    mav.getModel().put("body","充值沒有主題!請聯繫管理員");
                }
                mav.setViewName("page/waiting");
                e.printStackTrace();
            }
        }else{
            logger.info("outTradeNo爲空");
            mav.getModel().put("num",-2);
            mav.getModel().put("token",token);
            if("1".equals(tag)){
                mav.getModel().put("body","充值");
            }else if("2".equals(tag)){
                mav.getModel().put("body","充值");
            }else{
                mav.getModel().put("body","充值沒有主題!請聯繫管理員");
            }
            mav.setViewName("page/waiting");
        }
        return mav;
    }

4、微信服務接口

4.1微信接口

public interface CodeService {
    
    //數據庫操作
    //根據交易號獲取微信記錄表
    FinWeixinRecord getFinWeixinRecord(String out_trade_no) throws Exception;
    //更新微信記錄
    int updateFinWeixinRecode(FinWeixinRecord weixinRecord) throws Exception;
    //更新交易信息
    int updateRechargeInfo(Map<Object, Object> params, String result, String tradeStatus,String orign) throws Exception;
    
    //微信支付
    String weixinPay(String ip,String amount, String productId,String userId,String businessId,String userType) throws Exception;

    //小程序支付
    int xcxPay(FinWeixinRecord weixinRecord) throws Exception;
    //小程序獲取Out_trade_No
    String getOrderNo(String openid,String body,String money,String businessId,String userType,String userId,String orderCode);

    //h5支付
    int h5Pay(FinWeixinRecord f);
}

4.2 接口實現類

@Service
public class CodeServiceImpl implements CodeService {
    Logger logger = LoggerFactory.getLogger(CodeServiceImpl.class);
    @Autowired
    private FinWeixinRecordDao finWeixinRecordDao;
    @Autowired
    private PrechargeRecordsDao prechargeRecordsDao;
    @Autowired
    private PrechargeInfoDao prechargeInfoDao;
    @Autowired
    private FinSettleCustDetailDao finSettleCustDetailDao;
    @Override
    public String weixinPay(String ip,String amount, String productId,String userId,String businessId,String userType) throws Exception {
        BigDecimal totalFee = null;
        if(amount == null || "".equals(amount)){
            totalFee = new BigDecimal("0");
        }
        else{
            totalFee = new BigDecimal(Double.valueOf(amount) * 100);

            BigDecimal feevalue = new BigDecimal("100");
            BigDecimal totalFee2 = new BigDecimal(amount).multiply(feevalue);
            logger.info("微信參數" + totalFee.intValue() + "," + totalFee2.intValue());
        }

        String out_trade_no = getOutTradeNo(amount,userId,businessId,userType); //訂單號 (調整爲自己的生產邏輯)
        if(out_trade_no==null||"".equals(out_trade_no)){
            throw new RuntimeException("out_trade_no 爲空值");
        }

        // 賬號信息
        String appid = PayConfigUtil.APP_ID;  // appid
        //String appsecret = PayConfigUtil.APP_SECRET; // appsecret
        String mch_id = PayConfigUtil.MCH_ID; // 商業號
        String key = PayConfigUtil.API_KEY; // key

        String currTime = PayToolUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayToolUtil.buildRandom(4) + "";
        String nonce_str = strTime + strRandom;

        // 獲取發起電腦 ip
        String spbill_create_ip = ip;
        // 回調接口
        String notify_url = PayConfigUtil.NOTIFY_URL;
        String trade_type = "NATIVE";

        FinWeixinRecord f = new FinWeixinRecord();
        f.setAppId(appid);
        f.setMchId(mch_id);
        f.setNonchStr(nonce_str);
        f.setSpbllCreateIp(spbill_create_ip);
        f.setTradeType(trade_type);
        f.setOutTradeNo(out_trade_no);
        f.setTotalFee(Long.parseLong(totalFee.toString()));
        f.setBody("wxPay");
        f.setGmtCreate(new Date());
        f.setCreateUser(userId);
        int j = finWeixinRecordDao.insert(f);
        if(j>0){
            //nothing to do
        }else{
            throw new RuntimeException("插入記錄出錯");
        }

        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", "CCT");  //(調整爲自己的名稱)
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("total_fee", totalFee.toString()); //價格的單位爲分
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);

        String sign = PayToolUtil.createSign("UTF-8", packageParams,key);
        packageParams.put("sign", sign);

        String requestXML = PayToolUtil.getRequestXml(packageParams);
//        System.out.println(requestXML);
        logger.info(requestXML);
        String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);
//        System.out.println(resXml);
        logger.info(resXml);
        Map map = XMLUtil4jdom.doXMLParse(resXml);
        String urlCode = (String) map.get("code_url");
//        System.out.println(urlCode);
        logger.info(urlCode);
        return urlCode;
    }
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    private String getOutTradeNo(String amount, String userId, String businessId, String userType) {
        String orderCode = SNUtil.create15();
        PrechargeRecords prechargeRecords = new PrechargeRecords();
        prechargeRecords.setBusinessId(businessId);
        prechargeRecords.setUserType(userType);
        prechargeRecords.setPrechargeValue(getAmount(amount));
        prechargeRecords.setPrechargeType("01");//充值
        prechargeRecords.setComefromId(userId);
        prechargeRecords.setCreateUser(userId);
        prechargeRecords.setPrechargeState("00");
        prechargeRecords.setGmtCreate(new Date());
        prechargeRecords.setPrechargeOrderCode(orderCode);
        prechargeRecords.setPayType("wxPay");
        //t_precharge_info
        prechargeRecordsDao.insert(prechargeRecords);
        //生成 SELECT GETOUTTRADENO()  from DUAL
        String outTradeNo = finWeixinRecordDao.getKey();
        return outTradeNo;
    }

    @Override
    public FinWeixinRecord getFinWeixinRecord(String out_trade_no) throws Exception {
        FinWeixinRecord weixinRecord = finWeixinRecordDao.selectByOutTradeNo(out_trade_no);
        return weixinRecord;
    }

    @Override
    public int updateFinWeixinRecode(FinWeixinRecord weixinRecord) throws Exception {
        return finWeixinRecordDao.updateNotifyPay(weixinRecord);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public int updateRechargeInfo(Map<Object, Object> packageParams, String result, String tradeStatus,String orign) throws Exception {
        String mch_id = (String)packageParams.get("mch_id");
        String openid = (String)packageParams.get("openid");
        String is_subscribe = (String)packageParams.get("is_subscribe");
        String out_trade_no = (String)packageParams.get("out_trade_no");
        String nostr = (String)packageParams.get("nonce_str");
        String body = (String)packageParams.get("body");
        String spbill = (String)packageParams.get("spbill_create_ip");
        String prepayid = (String)packageParams.get("prepay_id");
        String tradetype = (String)packageParams.get("trade_type");
        String transaction_id = (String)packageParams.get("transaction_id");
        String result_code = (String)packageParams.get("result_code");
        String return_code = (String)packageParams.get("return_code");
        String time_end = (String)packageParams.get("time_end");
        String err_code = (String)packageParams.get("err_code");
        String err_code_des = (String)packageParams.get("err_code_des");
        //驗證價格是否正確
        FinWeixinRecord finWeixinRecord = finWeixinRecordDao.selectByOutTradeNo(out_trade_no);//來自數據庫
        String total_fee = (String)packageParams.get("total_fee");//來自服務器返回
        logger.info("服務器返回total_fee="+total_fee+";數據庫返回fee="+finWeixinRecord.getTotalFee().toString());
        if(Math.abs(Integer.parseInt(total_fee)-Integer.parseInt(finWeixinRecord.getTotalFee().toString()))<=1){
            logger.info(finWeixinRecord.getTotalFee().toString() + "===支付金額" + Integer.parseInt(total_fee));
            updateRechargeOrderInfo(finWeixinRecord, packageParams, "01",orign);//支付成功
        }else{
            updateRechargeOrderInfo(finWeixinRecord, packageParams, "02",orign);//支付成功金額對應不上
        }
        FinWeixinRecord weixinRecord = new FinWeixinRecord();
        weixinRecord.setMchId(mch_id);
        weixinRecord.setOpenId(openid);
        weixinRecord.setOutTradeNo(out_trade_no);
        weixinRecord.setTotalFee(finWeixinRecord.getTotalFee());
        weixinRecord.setNonchStr(nostr);
        weixinRecord.setBody(body);
        weixinRecord.setSpbllCreateIp(spbill);
        weixinRecord.setPrePayId(prepayid);
        weixinRecord.setTradeType(tradetype);
        weixinRecord.setReturnCode(return_code);
        weixinRecord.setErrorCode(err_code);
        weixinRecord.setErrorCodeDes(err_code_des);
        weixinRecord.setTransactionId(transaction_id);
        weixinRecord.setTimeEnd(time_end);
        weixinRecord.setModifiedUser("微信回調");
        weixinRecord.setGmtModified(new Date());
        int num = 0;
        if("FAIL".equals(result)){
            weixinRecord.setErrorCode(tradeStatus);
            weixinRecord.setErrorCodeDes(return_code);
            updateRechargeOrderInfo(weixinRecord, packageParams, "02",orign);//支付失敗
        }
        else{
            num = finWeixinRecordDao.updateNotify(weixinRecord);
        }
        return num;
    }

    @Override
    public int xcxPay(FinWeixinRecord weixinRecord) throws Exception {
        return finWeixinRecordDao.insert(weixinRecord);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public String getOrderNo(String openid,String body,String money,String businessId,String userType,String userId,String tempOrderCode) {
        String orderCode = SNUtil.create15();
        if(tempOrderCode!=null&&!tempOrderCode.equals("")){//繼續支付
            orderCode = tempOrderCode;
            FinWeixinRecord finWeixinRecord = finWeixinRecordDao.selectByOrderCode(orderCode);
            String outTradeNo = finWeixinRecord.getOutTradeNo();
            return outTradeNo+","+orderCode;
        }else{//支付
            PrechargeRecords prechargeRecords = new PrechargeRecords();
            prechargeRecords.setBusinessId(businessId);
            prechargeRecords.setUserType(userType);
            prechargeRecords.setPrechargeValue(getAmount(money));
            prechargeRecords.setPrechargeType("01");//充值
            prechargeRecords.setComefromId(userId);
            prechargeRecords.setCreateUser(userId);
            prechargeRecords.setPrechargeState("00");
            prechargeRecords.setGmtCreate(new Date());
            prechargeRecords.setPrechargeOrderCode(orderCode);
            if(openid==null){
                prechargeRecords.setPayType("h5Pay");
            }else {
                prechargeRecords.setPayType("xcxPay");
            }
            //t_precharge_info
            prechargeRecordsDao.insert(prechargeRecords);
            //生成 SELECT GETOUTTRADENO()  from DUAL
            String outTradeNo = finWeixinRecordDao.getKey();
            return outTradeNo+","+orderCode;
        }
    }

    @Override
    public int h5Pay(FinWeixinRecord f) {
        return finWeixinRecordDao.insert(f);
    }

    private Integer getAmount(String recAmount){
        return new BigDecimal(recAmount).multiply(new BigDecimal(100)).intValue();
    }
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    private int updateRechargeOrderInfo(FinWeixinRecord weixinRecord, Map<Object, Object> packageParams, String payState,String orign) {
        int upNum = 0;
        Map<String, Object> map = new HashMap<>();
        map.put("outTradeNo", weixinRecord.getOutTradeNo());
        List<FinWeixinRecord> list = (List<FinWeixinRecord>)finWeixinRecordDao.selectForList("selectByNO",map);
        for(FinWeixinRecord finWeixinRecord : list){
            PrechargeRecords prechargeRecordsParam = new PrechargeRecords();
            prechargeRecordsParam.setPrechargeOrderCode(finWeixinRecord.getOrderId());
            PrechargeRecords prechargeRecords = prechargeRecordsDao.getPrechargeRecordsByOrderCode(prechargeRecordsParam);
            if("01".equals(payState)){
                if(null != prechargeRecords && "00".equals(prechargeRecords.getPrechargeState())){

                    //更新客戶可用額度
                    PrechargeInfo prechargeInfoParm = new PrechargeInfo();
                    prechargeInfoParm.setBusinessId(prechargeRecords.getBusinessId());
                    prechargeInfoParm.setUserType(prechargeRecords.getUserType());
                    PrechargeInfo prechargeInfo = prechargeInfoDao.get4UpdAmount(prechargeInfoParm);
                    Integer availableAmount = 0;
                    if(null != prechargeInfo){
                        availableAmount = prechargeInfo.getAvailableValue() + Integer.parseInt(weixinRecord.getTotalFee().toString());
                        prechargeInfo.setAvailableValue(availableAmount);
                        prechargeInfo.setPrechargeValue(prechargeInfo.getPrechargeValue() + Integer.parseInt(weixinRecord.getTotalFee().toString()));
                        prechargeInfo.setModifiedUser(orign);
                        prechargeInfo.setGmtModified(new Date());
                        prechargeInfoDao.update(prechargeInfo);
                        logger.info("updateRechargeOrderInfo 更新t_precharge_info");
                    }else{
                        availableAmount = 0+Integer.parseInt(weixinRecord.getTotalFee().toString());
                        prechargeInfoParm.setAvailableValue(availableAmount);
                        prechargeInfoParm.setPrechargeValue(0+Integer.parseInt(weixinRecord.getTotalFee().toString()));
                        prechargeInfoParm.setCreateUser(orign);
                        prechargeInfoParm.setGmtCreate(new Date());
                        if("h5Pay".equals(orign)){
                            prechargeInfoParm.setDepostValue(10000);
                        }
                        int z = prechargeInfoDao.insert("insertSelective",prechargeInfoParm);
                        if(z>0){
                            logger.info("insertRechargeOrderInfo 插入t_precharge_info成功");
                        }else{
                            logger.info("insertRechargeOrderInfo 插入t_precharge_info失敗");
                        }
                    }

                    //更新充值記錄狀態
                    prechargeRecords.setBusinessId(prechargeRecords.getBusinessId());
                    prechargeRecords.setPrechargeState("01");
                    prechargeRecords.setModifiedUser(orign);
                    prechargeRecords.setGmtModified(new Date());
                    prechargeRecords.setCurrentAvailableValue(availableAmount);
                    prechargeRecordsDao.update(prechargeRecords);
                }
            }else if("02".equalsIgnoreCase(payState)){
                if(null != prechargeRecords && "00".equals(prechargeRecords.getPrechargeState())){
                    prechargeRecords.setPrechargeState("02");
                    prechargeRecords.setModifiedUser(orign);
                    prechargeRecords.setGmtModified(new Date());
                    prechargeRecordsDao.update(prechargeRecords);
                }
            }
            upNum++;
            //更新結算收款明細付款渠道
            FinSettleCustDetail fin = new FinSettleCustDetail();
            fin.setOrderCode(finWeixinRecord.getOrderId());
            FinSettleCustDetail dbcustdetail = (FinSettleCustDetail) finSettleCustDetailDao.select("selectByPrimaryKey",finWeixinRecord.getOrderId());
            if(null != dbcustdetail){
                FinSettleCustDetail custdetail = new FinSettleCustDetail();
                custdetail.setOrderCode(finWeixinRecord.getOrderId());
                custdetail.setPayChannel(orign);//付款渠道
                finSettleCustDetailDao.update(custdetail);
            }
        }
        if(upNum != list.size()){
            logger.error("未將全部訂單支付狀態更新");
        }
        return upNum;
    }


}

5、代碼片段

代碼片段

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章