微信支付官方文档 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1# 1.java后台controller层php
package com.readygo.pet.controller; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.readygo.pet.common.Constant; import com.readygo.pet.common.ResultObject; import com.readygo.pet.service.WXPayService; import com.readygo.pet.utils.WXPayUtils; import com.readygo.pet.vo.WXPayVO; /** * 程序名 WXPaymentController.java * 程序功能 微信支付接口 * 做成者 xx * 做成日期 2016-04-27 * 修改履历 * 项目名 状态 做成者 做成日期 * -------------------------------------------- * pets 新规 xx 2016-04-27 */ @RestController @RequestMapping("/wechat") public class WXPaymentController { @Autowired private WXPayService wxPayService; /** * 发起微信支付 * * @param payVO * 订单信息 * @return 带签名的客户端支付信息 */ @RequestMapping(value = "/doWXPay", method = RequestMethod.POST) public ResultObject doWXPay(@RequestBody WXPayVO payVO, HttpServletRequest request){ ResultObject resultObject = new ResultObject(); try { resultObject = wxPayService.doWXPay(payVO, request); } catch (Exception e) { resultObject.setResultCode(Constant.ResultCode.FAILED.getType()); resultObject.setResultMsg(WXPayUtils.MSG_WXPAY_ORDER_FAILED); resultObject.setResultCount("0"); e.printStackTrace(); } return resultObject; } /** * 微信支付后供微信服务器端回调方法 * 根据返回的状态更新相关订单信息及生成消费码 * @param request 请求包 * * @return 成功/失败 */ @RequestMapping(value = "/callBackWXPay") public String callBackWXPay(HttpServletRequest request){ String retStr = ""; try { retStr = wxPayService.callBackWXPay(request); } catch (Exception e) { Map<String, Object> retMap = new HashMap<String, Object>(); retMap.put("return_code", "FAIL"); retMap.put("return_msg", "接接收异常"); retStr = WXPayUtils.map2xmlBody(retMap, "xml"); } System.out.println("微信支付回调开始"); return retStr; } /** * 微信支付查询 * @param orderId 商家订单编号 * @return 查询结果 */ @RequestMapping(value = "/searchWXPay", method = RequestMethod.POST) public ResultObject searchWXPay(@RequestParam String orderId){ ResultObject resultObject = new ResultObject(); try { resultObject = wxPayService.searchWXPay(orderId); } catch (Exception e) { resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(WXPayUtils.MSG_WXPAY_SEARCH_FAILED); resultObject.setResultCount("0"); e.printStackTrace(); } return resultObject; } /** * 关闭支付订单 * @param orderId 订单编号 * @param request 请求包 * @return 执行结果 */ @RequestMapping(value = "/closeWXPay", method = RequestMethod.POST) public ResultObject closeWXPay(@RequestBody String orderId){ ResultObject resultObject = new ResultObject(); try { resultObject = wxPayService.closeWXPay(orderId); } catch (Exception e) { resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(WXPayUtils.MSG_WXPAY_CLOSE_FAILED); resultObject.setResultCount("0"); e.printStackTrace(); } return resultObject; } /** * 微信支付退款 * @param payVO 退款订单信息 * @return 退款申请结果 */ @RequestMapping(value = "/refundWXPay", method = RequestMethod.POST) public ResultObject refundWXPay(@RequestBody WXPayVO payVO){ ResultObject resultObject = new ResultObject(); try { resultObject = wxPayService.refundWXPay(payVO); } catch (Exception e) { resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(WXPayUtils.MSG_WXPAY_CLOSE_FAILED); resultObject.setResultCount("0"); e.printStackTrace(); } return resultObject; } /** * 微信退款申请查询 * @param refundOrderId 退款单号 * @return 退款查询结果 */ @RequestMapping(value = "/searchRefundWXPay", method = RequestMethod.POST) public ResultObject searchRefundWXPay(@RequestBody String refundOrderId){ ResultObject resultObject = new ResultObject(); try { resultObject = wxPayService.searchRefundWXPay(refundOrderId); } catch (Exception e) { resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(WXPayUtils.MSG_WXPAY_CLOSE_FAILED); resultObject.setResultCount("0"); e.printStackTrace(); } return resultObject; } }
2.Service层以下前端
package com.readygo.pet.service; import javax.servlet.http.HttpServletRequest; import com.readygo.pet.common.ResultObject; import com.readygo.pet.vo.WXPayVO; /** * 程序名 WXPayService.java * 程序功能 微信支付处理接口 * 做成者 xx * 做成日期 2016-04-27 * 修改履历 * 项目名 状态 做成者 做成日期 * -------------------------------------------- * pets 新规 xx 2016-04-27 */ public interface WXPayService { /** * 发起微信支付 * @param payVO 支付订单信息 * @param request 发起支付的请求 * @return 带签名的客户端支付信息 */ ResultObject doWXPay(WXPayVO payVO, HttpServletRequest request) throws Exception; /** * 微信支付回调 * @param request 发起支付的请求 * @return 返给微信服务器接收结果 */ String callBackWXPay(HttpServletRequest request) throws Exception; /** * 查询微信支付结果 * @param orderId 内部订单ID(非微信支付id) * @param request 请求包 * @return 查询结果 * @throws Exception */ ResultObject searchWXPay(String orderId) throws Exception; /** * 关闭微信支付订单 * @param orderId 订单编号 * @param request 请求包 * @return 执行结果 * @throws Exception */ ResultObject closeWXPay(String orderId) throws Exception; /** * 申请退款 * @param payVO 退款信息 * @param request 请求包 * @return 操做结果 * @throws Exception */ ResultObject refundWXPay(WXPayVO payVO) throws Exception; /** * 退款查询 * 退款有必定延时,用零钱支付的退款20分钟内到帐,银行卡支付的退款3个工做往后从新查询退款状态 * @param refundOrderId 退款单号 * @return 退款详情 * @throws Exception */ ResultObject searchRefundWXPay(String refundOrderId) throws Exception; }
3.ServiceImp层java
package com.readygo.pet.service.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.readygo.pet.common.ConfigReader; import com.readygo.pet.common.Constant; import com.readygo.pet.common.ResultObject; import com.readygo.pet.mapper.WXPayCloseRecordMapper; import com.readygo.pet.mapper.WXPayOrderRecordMapper; import com.readygo.pet.mapper.WXPayRecordMapper; import com.readygo.pet.mapper.WXPayRefundRecordMapper; import com.readygo.pet.model.WXPayCloseRecord; import com.readygo.pet.model.WXPayOrderRecord; import com.readygo.pet.model.WXPayRecord; import com.readygo.pet.model.WXPayRefundRecord; import com.readygo.pet.service.WXPayDoService; import com.readygo.pet.service.WXPayService; import com.readygo.pet.utils.DesUtil; import com.readygo.pet.utils.HttpRequestUtils; import com.readygo.pet.utils.WXPayUniqueCodeUtils; import com.readygo.pet.utils.WXPayUtils; import com.readygo.pet.vo.WXPayOrderResponseParam; import com.readygo.pet.vo.WXPayRefundResponseParam; import com.readygo.pet.vo.WXPaySearchResponseParam; import com.readygo.pet.vo.WXPayVO; /** * 程序名 WXPayServiceImpl.java * 程序功能 微信支付处理实现 * 包含下预支付单、支付回调、查询支付结果、关闭支付单、申请退款、退款查询操做 * 做成者 xx * 做成日期 2016-04-27 * 修改履历 * 项目名 状态 做成者 做成日期 * -------------------------------------------- * pets 新规 xx 2016-04-27 */ @Service public class WXPayServiceImpl implements WXPayService{ private final static String PID = "WXP0001WBS001"; private Logger rootLogger=Logger.getRootLogger(); @Autowired private ConfigReader configReader; @Autowired private WXPayOrderRecordMapper wxPayOrderRecordMapper; @Autowired private WXPayRecordMapper wxPayRecordMapper; @Autowired private WXPayCloseRecordMapper wxPayCloseRecordMapper; @Autowired private WXPayRefundRecordMapper wxPayRefundRecordMapper; @Autowired private WXPayUniqueCodeUtils uniqueCodeUtils; @Autowired private WXPayDoService wxPayDoService; /** * 发起微信支付 * @param payVO 支付订单信息 * @param request 支付请求 * @return 带签名的客户端支付信息 */ public ResultObject doWXPay(WXPayVO payVO, HttpServletRequest request) throws Exception{ ResultObject resultObject = new ResultObject(); resultObject.setResultCount("1"); WXPayOrderResponseParam wxPayResponseParam = new WXPayOrderResponseParam(); WXPayOrderRecord wxPayOrderRecord = new WXPayOrderRecord(); SortedMap<String,Object> paramters = new TreeMap<String,Object>(); /**1 设置传递的参数 */ // 应用ID paramters.put("appid", configReader.getWxAppID()); // 商品描述 paramters.put("body", payVO.getGoodsName()); // 商户号 paramters.put("mch_id", configReader.getWxShopId()); // 随机字符串 paramters.put("nonce_str", WXPayUtils.getRandomString(32)); // 通知地址(回调) paramters.put("notify_url", configReader.getWxCallBackPath()); // 商户订单号 paramters.put("out_trade_no", payVO.getOrderId()); // 终端IP paramters.put("spbill_create_ip", WXPayUtils.getIpAddr(request)); // 交易类型 paramters.put("trade_type", "APP"); // 总金额(分) paramters.put("total_fee", payVO.getPrice()); /**1.1 设置签名sign */ paramters.put("sign", WXPayUtils.createSign("UTF-8", paramters, DesUtil.decrypt(configReader.getWxAPIKey()))); rootLogger.info("[微信支付][预支付]生成的签名为:" + paramters.get("sign")); // 设置发送时间 wxPayOrderRecord.setSendTime(WXPayUtils.getSysTime()); /**2 发送HTTPS请求获取带签名预支付信息 */ String requestParamterStr = WXPayUtils.map2xmlBody(paramters, "xml"); //.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""); rootLogger.info("[微信支付][预支付]申请微信预支付单参数为:" + requestParamterStr); HttpRequestUtils httpRequest = new HttpRequestUtils(); String responseStr = httpRequest.httpsRequest(configReader.getWxPayURL(), "POST", requestParamterStr); rootLogger.info("[微信支付][预支付]微信支付返回:" + responseStr); // 设置接收时间 wxPayOrderRecord.setRecvTime(WXPayUtils.getSysTime()); /** 3 将回传的数据转为map */ Map<String, String> responseMap = WXPayUtils.parseXml(responseStr); String return_code = responseMap.get("return_code"); /** 4设置记录到数据库的数据 */ wxPayOrderRecord.setSendAppid(configReader.getWxAppID()); wxPayOrderRecord.setSendBody(payVO.getGoodsName()); wxPayOrderRecord.setSendMchId(configReader.getWxShopId()); wxPayOrderRecord.setSendNonceStr(paramters.get("nonce_str").toString()); wxPayOrderRecord.setSendNotifyUrl(configReader.getWxCallBackPath()); wxPayOrderRecord.setSendOutTradeNo(payVO.getOrderId()); wxPayOrderRecord.setSendSpbillCreateIp(paramters.get("spbill_create_ip").toString()); wxPayOrderRecord.setSendTradeType("APP"); wxPayOrderRecord.setSendTotalFee(payVO.getPrice().toString()); wxPayOrderRecord.setSendSgin(paramters.get("sign").toString()); wxPayOrderRecord.setAddUid(payVO.getUserId()); wxPayOrderRecord.setUpdUid(payVO.getUserId()); wxPayOrderRecord.setRecvReturnCode(responseMap.get("return_code")); wxPayOrderRecord.setRecvReturnMsg(responseMap.get("return_msg")); // 判断下单是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ String return_msg = responseMap.get("return_msg"); if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][预支付]统一下单错误,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); resultObject.setResultCode(Constant.ResultCode.FAILED.getType()); resultObject.setResultMsg(responseMap.get("err_code_des")); resultObject.setData(wxPayResponseParam); // 插入预支付记录 if(!insertWXPayOrderRecord(wxPayOrderRecord)){ rootLogger.error("[微信支付][预支付]1统一下单预支付记录插入失败!"); } return resultObject; } }else{ rootLogger.error("[微信支付][预支付]统一下单错误,错误信息为:" + responseMap.get("return_msg")); resultObject.setResultCode(Constant.ResultCode.FAILED.getType()); resultObject.setResultMsg("统一下单错误.错误信息为:" + responseMap.get("return_msg")); resultObject.setData(wxPayResponseParam); // 插入预支付记录 if(!insertWXPayOrderRecord(wxPayOrderRecord)){ rootLogger.error("[微信支付][预支付]2统一下单预支付记录插入失败!"); } return resultObject; } wxPayOrderRecord.setRecvAppid(responseMap.get("appid")); wxPayOrderRecord.setRecvMchId(responseMap.get("mch_id")); wxPayOrderRecord.setRecvNonceStr(responseMap.get("nonce_str")); wxPayOrderRecord.setRecvSgin(responseMap.get("sign")); wxPayOrderRecord.setRecvResultCode(responseMap.get("result_code")); wxPayOrderRecord.setRecvErrCode(responseMap.get("err_code")); wxPayOrderRecord.setRecvErrCodeDes(responseMap.get("err_code_des")); wxPayOrderRecord.setRecvTradeType(responseMap.get("trade_type")); wxPayOrderRecord.setRecvPrepayId(responseMap.get("prepay_id")); if("SUCCESS".equals(responseMap.get("result_code"))){ // 应用ID wxPayResponseParam.setAppid(responseMap.get("appid")); // 商户号 wxPayResponseParam.setPartnerid(responseMap.get("mch_id")); // 预支付ID wxPayResponseParam.setPrepayid(responseMap.get("prepay_id")); // 扩展字段 wxPayResponseParam.setMyPackage("Sign=WXPay"); // 随机字符串 wxPayResponseParam.setNoncestr(WXPayUtils.getRandomString(32)); // 时间戳 wxPayResponseParam.setTimestamp(Long.toString(System.currentTimeMillis()/1000)); // 签名 SortedMap<String,Object> paramtersTmp = new TreeMap<String,Object>(); paramtersTmp.put("appid", responseMap.get("appid")); paramtersTmp.put("noncestr", wxPayResponseParam.getNoncestr()); paramtersTmp.put("package", "Sign=WXPay"); paramtersTmp.put("partnerid", responseMap.get("mch_id")); paramtersTmp.put("prepayid", responseMap.get("prepay_id")); paramtersTmp.put("timestamp", wxPayResponseParam.getTimestamp()); String outSign = WXPayUtils.createSign("UTF-8", paramtersTmp, DesUtil.decrypt(configReader.getWxAPIKey())); rootLogger.info("[微信支付][预支付]返回前台的签名为:" + outSign); wxPayResponseParam.setSign(outSign); resultObject.setResultCode(Constant.ResultCode.SUCCESS.getType()); resultObject.setResultMsg("[微信支付][预支付]统一下单成功。"); resultObject.setData(wxPayResponseParam); }else{ resultObject.setResultCode(Constant.ResultCode.FAILED.getType()); resultObject.setResultMsg("统一下单错误.错误信息为:" + responseMap.get("err_code_des")); resultObject.setData(wxPayResponseParam); } if(!insertWXPayOrderRecord(wxPayOrderRecord)){ rootLogger.error("[微信支付][预支付]4统一下单预支付记录插入失败!"); } /**4 返回前端 */ return resultObject; } /** * 微信支付回调 * @param request 发起支付的请求 * @return 返给微信服务器接收结果 */ public String callBackWXPay(HttpServletRequest request) throws Exception{ String inputLine; String notityXml = ""; Map<String, Object> retMap = new HashMap<String, Object>(); WXPayRecord wxPayRecord = new WXPayRecord(); // 取出回调中的数据 while ((inputLine = request.getReader().readLine()) != null) { notityXml += inputLine; } request.getReader().close(); rootLogger.info("[微信支付][回调]接收到的报文:" + notityXml); // 将传回数据转化成map方便读取 SortedMap<String, String> responseMap = WXPayUtils.parseXml(notityXml); String return_code = responseMap.get("return_code"); wxPayRecord.setRecvReturnCode(responseMap.get("return_code")); wxPayRecord.setRecvReturnMsg(responseMap.get("return_msg")); // 判断支付是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ String return_msg = responseMap.get("return_msg"); if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][回调]支付失败,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); // 正确接收到了返回,给微信服务器返回接收成功 retMap.put("return_code", "SUCCESS"); retMap.put("return_msg", "OK"); wxPayRecord.setSendReturnCode("SUCCESS"); wxPayRecord.setSendReturnMsg("OK"); // 将支付凭证等消息存入本地数据库以备用 if(!insertWXPayRecord(wxPayRecord)){ rootLogger.error("[微信支付][回调]1插入数据库失败,具体数据为:" + notityXml); } return WXPayUtils.map2xmlBody(retMap, "xml"); } }else{ System.err.println("[微信支付][回调]支付失败。失败缘由:" + responseMap.get("return_msg")); // 正确接收到了返回,给微信服务器返回接收成功 retMap.put("return_code", "SUCCESS"); retMap.put("return_msg", "OK"); wxPayRecord.setSendReturnCode("SUCCESS"); wxPayRecord.setSendReturnMsg("OK"); // 将支付凭证等消息存入本地数据库以备用 if(!insertWXPayRecord(wxPayRecord)){ rootLogger.error("[微信支付][回调]2插入数据库失败,具体数据库为:" + notityXml); } return WXPayUtils.map2xmlBody(retMap, "xml"); } // 微信规定,其余参数在return_code为SUCCESS的时候有返回,所以在以上判断OK的状况下进行如下操做 wxPayRecord = setParam(responseMap); // 将支付凭证等消息存入本地数据库以备用 if(!insertWXPayRecord(wxPayRecord)){ rootLogger.error("[微信支付][回调]插入数据库失败,具体数据库为:" + notityXml); } // 检查参数是否有效 String retMsg = ""; if(!checkCallBackValidate(wxPayRecord, responseMap, retMsg)){ // 正确接收到了返回,校验失败,以错误形式返给微信服务器 retMap.put("return_code", "FAIL"); retMap.put("return_msg", retMsg); wxPayRecord.setSendReturnCode("FAIL"); wxPayRecord.setSendReturnMsg(retMsg); rootLogger.error("[微信支付][回调]传递参数有效验证错误,错误信息为:" + retMsg); }else{ // 根据支付结果更新订单数据或其余相关表数据操做 if("SUCCESS".equals(wxPayRecord.getRecvResultCode())){ System.out.println("[微信支付][回调]微信支付成功。"); // TODO 这里根据支付结果添加业务处理 payOrderDo() if(!wxPayDoService.payOrderDo(wxPayRecord.getRecvOutTradeNo(), wxPayRecord)){ rootLogger.error("[微信支付][回调]业务处理失败。"); }else{ rootLogger.info("[微信支付][回调]业务处理成功。"); } }else{ rootLogger.error("[微信支付][回调]微信支付失败。错误码为:" + wxPayRecord.getRecvErrCode() + ",错误描述为:" + wxPayRecord.getRecvErrCodeDes()); // 支付失败,不更新订单信息 } // 正确接收到了返回,给微信服务器返回接收成功 retMap.put("return_code", "SUCCESS"); retMap.put("return_msg", "OK"); wxPayRecord.setSendReturnCode("SUCCESS"); wxPayRecord.setSendReturnMsg("OK"); } return WXPayUtils.map2xmlBody(retMap, "xml"); } /** * 查询微信支付结果 * @param orderId 内部订单ID(非微信支付id) * @param request 请求包 * @return 查询结果 * @throws Exception */ public ResultObject searchWXPay(String orderId) throws Exception{ rootLogger.info("[微信支付][查询]======开始"); ResultObject resultObject = new ResultObject(); // 查询所用的参数map SortedMap<String,Object> paramters = new TreeMap<String,Object>(); WXPaySearchResponseParam wxPaySearchResponseParam = new WXPaySearchResponseParam(); /**1 设置传递的参数 */ // 应用ID paramters.put("appid", configReader.getWxAppID()); // 商户号 paramters.put("mch_id", configReader.getWxShopId()); // 商户订单号 paramters.put("out_trade_no", orderId); // 随机字符串 paramters.put("nonce_str", WXPayUtils.getRandomString(32)); /**1.1 设置签名sign */ paramters.put("sign", WXPayUtils.createSign("UTF-8", paramters, DesUtil.decrypt(configReader.getWxAPIKey()))); rootLogger.info("[微信支付][查询]生成的签名为:" + paramters.get("sign")); /**2 发送HTTPS请求获取支付详细信息 */ String requestParamterStr = WXPayUtils.map2xmlBody(paramters, "xml"); //.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""); rootLogger.info("[微信支付][查询]支付订单查询参数为:" + requestParamterStr); HttpRequestUtils httpRequest = new HttpRequestUtils(); String responseStr = httpRequest.httpsRequest(configReader.getWxPaySearchURL(), "POST", requestParamterStr); rootLogger.info("[微信支付][查询]支付订单查询结果为:" + responseStr); /** 3 将回传的数据转为map */ Map<String, String> responseMap = WXPayUtils.parseXml(responseStr); String return_code = responseMap.get("return_code"); // 判断查询是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ String return_msg = responseMap.get("return_msg"); if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][查询]支付订单查询失败,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(responseMap.get("err_code_des")); resultObject.setData(wxPaySearchResponseParam); rootLogger.error("[微信支付][查询]======结束(错误1)"); return resultObject; } }else{ rootLogger.error("[微信支付][查询]支付订单查询错误,错误信息为:" + responseMap.get("return_msg")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg("支付订单查询错误.错误信息为:" + responseMap.get("return_msg")); resultObject.setData(wxPaySearchResponseParam); rootLogger.error("[微信支付][查询]======结束(错误2)"); return resultObject; } // 设置返回数据 // 应用ID wxPaySearchResponseParam.setAppid(responseMap.get("appid")); wxPaySearchResponseParam.setMch_id(responseMap.get("mch_id")); wxPaySearchResponseParam.setNonce_str(responseMap.get("nonce_str")); wxPaySearchResponseParam.setSign(responseMap.get("sign")); wxPaySearchResponseParam.setResult_code(responseMap.get("result_code")); wxPaySearchResponseParam.setErr_code(responseMap.get("err_code")); wxPaySearchResponseParam.setErr_code_des(responseMap.get("err_code_des")); String result_code = responseMap.get("result_code"); if("SUCCESS".equals(result_code)){ wxPaySearchResponseParam.setOpenid(responseMap.get("openid")); wxPaySearchResponseParam.setTrade_type(responseMap.get("trade_type")); wxPaySearchResponseParam.setTrade_state(responseMap.get("trade_state")); wxPaySearchResponseParam.setBank_type(responseMap.get("bank_type")); wxPaySearchResponseParam.setTotal_fee(responseMap.get("total_fee")); wxPaySearchResponseParam.setFee_type(responseMap.get("fee_type")); wxPaySearchResponseParam.setCash_fee(responseMap.get("cash_fee")); wxPaySearchResponseParam.setCash_fee_type(responseMap.get("cash_fee_type")); wxPaySearchResponseParam.setTransaction_id(responseMap.get("transaction_id")); wxPaySearchResponseParam.setOut_trade_no(responseMap.get("out_trade_no")); wxPaySearchResponseParam.setTime_end(responseMap.get("time_end")); wxPaySearchResponseParam.setTrade_state_desc(responseMap.get("trade_state_desc")); } // TODO 这里能够根据查询结果进行其余处理 searchOrderDo() if(!wxPayDoService.searchOrderDo(orderId, wxPaySearchResponseParam)){ rootLogger.error("[微信支付][查询]业务处理失败。"); }else{ rootLogger.info("[微信支付][查询]业务处理成功。"); } /**4 返回前端 */ resultObject.setResultCode(WXPayUtils.ResultCode.SUCCESS.getType()); resultObject.setResultMsg("[微信支付][查询]支付订单查询成功。"); resultObject.setData(wxPaySearchResponseParam); rootLogger.info("[微信支付][查询]======结束"); return resultObject; } /** * 关闭微信支付订单 * 如下状况须要调用关单接口:商户订单支付失败须要生成新单号从新发起支付,要对原订单号调用关单, * 避免重复支付;系统下单后,用户支付超时,系统退出再也不受理,避免用户继续,请调用关单接口 * 注意:订单生成后不能立刻调用关单接口,最短调用时间间隔为5分钟 * @param orderId 订单编号 * @param request 请求包 * @return 执行结果 * @throws Exception */ public ResultObject closeWXPay(String orderId) throws Exception{ rootLogger.info("[微信支付][关闭]======开始"); ResultObject resultObject = new ResultObject(); resultObject.setResultCount("0"); // 查询所用的参数map SortedMap<String,Object> paramters = new TreeMap<String,Object>(); WXPayCloseRecord wxPayCloseRecord = new WXPayCloseRecord(); /**1 设置传递的参数 */ // 应用ID paramters.put("appid", configReader.getWxAppID()); wxPayCloseRecord.setSendAppid(configReader.getWxAppID()); // 商户号 paramters.put("mch_id", configReader.getWxShopId()); wxPayCloseRecord.setSendMchId(configReader.getWxShopId()); // 商户订单号 paramters.put("out_trade_no", orderId); wxPayCloseRecord.setSendOutTradeNo(orderId); // 随机字符串 paramters.put("nonce_str", WXPayUtils.getRandomString(32)); wxPayCloseRecord.setSendNonceStr(paramters.get("nonce_str").toString()); /**1.1 设置签名sign */ paramters.put("sign", WXPayUtils.createSign("UTF-8", paramters, DesUtil.decrypt(configReader.getWxAPIKey()))); wxPayCloseRecord.setSendSgin(paramters.get("sign").toString()); rootLogger.info("[微信支付][关闭]生成的签名为:" + paramters.get("sign")); // 设置发送时间 wxPayCloseRecord.setSendTime(WXPayUtils.getSysTime()); /**2 发送HTTPS请求获取关闭支付信息 */ String requestParamterStr = WXPayUtils.map2xmlBody(paramters, "xml"); //.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""); rootLogger.info("[微信支付][关闭]支付订单关闭参数为:" + requestParamterStr); HttpRequestUtils httpRequest = new HttpRequestUtils(); String responseStr = httpRequest.httpsRequest(configReader.getWxPayCloseURL(), "POST", requestParamterStr); rootLogger.info("[微信支付][关闭]支付订单关闭结果为:" + responseStr); // 设置发送时间 wxPayCloseRecord.setRecvTime(WXPayUtils.getSysTime()); /** 3 将回传的数据转为map */ Map<String, String> responseMap = WXPayUtils.parseXml(responseStr); String return_code = responseMap.get("return_code"); wxPayCloseRecord.setRecvReturnCode(return_code); wxPayCloseRecord.setRecvReturnMsg(responseMap.get("return_msg")); // 判断支付订单关闭是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ String return_msg = responseMap.get("return_msg"); if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][关闭]支付订单关闭失败,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(responseMap.get("err_code_des")); resultObject.setData(wxPayCloseRecord); wxPayCloseRecord.setRecvErrCode(responseMap.get("err_code")); wxPayCloseRecord.setRecvErrCodeDes(responseMap.get("err_code_des")); // 插入微信关闭记录 if(!insertWXPayCloseRecord(wxPayCloseRecord)){ rootLogger.error("[微信支付][关闭]1支付关闭记录插入失败!"); } rootLogger.error("[微信支付][关闭]======结束(错误1)"); return resultObject; } }else{ rootLogger.error("[微信支付][关闭]支付订单关闭错误,错误信息为:" + responseMap.get("return_msg")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg("支付订单关闭错误.错误信息为:" + responseMap.get("return_msg")); resultObject.setData(wxPayCloseRecord); // 插入微信关闭记录 if(!insertWXPayCloseRecord(wxPayCloseRecord)){ rootLogger.error("[微信支付][关闭]2支付关闭记录插入失败!"); } rootLogger.error("[微信支付][关闭]======结束(错误2)"); return resultObject; } // 设置返回数据 wxPayCloseRecord.setRecvAppid(responseMap.get("appid")); wxPayCloseRecord.setRecvMchId(responseMap.get("mch_id")); wxPayCloseRecord.setRecvNonceStr(responseMap.get("nonce_str")); wxPayCloseRecord.setRecvSgin(responseMap.get("sign")); wxPayCloseRecord.setRecvErrCode(responseMap.get("err_code")); wxPayCloseRecord.setRecvErrCodeDes(responseMap.get("err_code_des")); // 插入微信关闭记录 if(!insertWXPayCloseRecord(wxPayCloseRecord)){ rootLogger.error("[微信支付][关闭]3支付关闭记录插入失败!"); } // TODO 这里能够根据关闭结果进行订单处理 closeOrderDo() if(!wxPayDoService.closeOrderDo(orderId, wxPayCloseRecord)){ rootLogger.error("[微信支付][关闭]业务处理失败。"); }else{ rootLogger.info("[微信支付][关闭]业务处理成功。"); } /**4 返回前端 */ resultObject.setResultCode(WXPayUtils.ResultCode.SUCCESS.getType()); resultObject.setResultMsg("支付订单关闭成功。"); resultObject.setResultCount("1"); resultObject.setData(wxPayCloseRecord); rootLogger.info("[微信支付][关闭]======结束"); return resultObject; } /** * 申请退款 * 注意:一、交易时间超过一年的订单没法提交退款; * 二、微信支付退款支持单笔交易分屡次退款,屡次退款须要提交原支付订单的商户订单号和设置不一样的退款单号。 * 一笔退款失败后从新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 * @param payVO 退款信息 * @param request 请求包 * @return 操做结果 * @throws Exception */ public ResultObject refundWXPay(WXPayVO payVO) throws Exception{ rootLogger.info("[微信支付][退款]======开始"); ResultObject resultObject = new ResultObject(); resultObject.setResultCount("0"); WXPayRefundRecord wxPayRefundRecord = new WXPayRefundRecord(); // 查询所用的参数map SortedMap<String,Object> paramters = new TreeMap<String,Object>(); // 应用ID paramters.put("appid", configReader.getWxAppID()); wxPayRefundRecord.setSendAppid(configReader.getWxAppID()); // 商户号 paramters.put("mch_id", configReader.getWxShopId()); wxPayRefundRecord.setSendMchId(configReader.getWxShopId()); // 随机字符串 paramters.put("nonce_str", WXPayUtils.getRandomString(32)); wxPayRefundRecord.setSendNonceStr(paramters.get("nonce_str").toString()); // 商户订单号 paramters.put("out_trade_no", payVO.getOrderId()); wxPayRefundRecord.setSendOutTradeNo(payVO.getOrderId()); // 商户退款单号 paramters.put("out_refund_no", payVO.getRefundOrderId()); wxPayRefundRecord.setSendOutRefundNo(payVO.getRefundOrderId()); // 总金额(分) paramters.put("total_fee", payVO.getPrice()); wxPayRefundRecord.setSendTotalFee(String.valueOf(payVO.getPrice())); // 退款金额(分) paramters.put("refund_fee", payVO.getRefundPrice()); wxPayRefundRecord.setSendRefundFee(String.valueOf(payVO.getRefundPrice())); // 货币种类 paramters.put("refund_fee_type", "CNY"); wxPayRefundRecord.setSendRefundFeeType("CNY"); // 操做员(默认为商户号) paramters.put("op_user_id", configReader.getWxShopId()); wxPayRefundRecord.setSendOpUserId(configReader.getWxShopId()); /**1.1 设置签名sign */ paramters.put("sign", WXPayUtils.createSign("UTF-8", paramters, DesUtil.decrypt(configReader.getWxAPIKey()))); wxPayRefundRecord.setSendSgin(paramters.get("sign").toString()); rootLogger.info("[微信支付][退款]生成的签名为:" + paramters.get("sign")); // 设置发送时间 wxPayRefundRecord.setSendTime(WXPayUtils.getSysTime()); /**2 发送HTTPS请求获取退款结果信息 */ String requestParamterStr = WXPayUtils.map2xmlBody(paramters, "xml"); //.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""); rootLogger.info("[微信支付][退款]订单退款参数为:" + requestParamterStr); // 该请求须要证书,需放置本地p12证书 String responseStr = WXPayUtils.httpsRequestWithCert(configReader.getWxPayRefundURL() , requestParamterStr, configReader.getWxCertPath(), configReader.getWxShopId()); rootLogger.info("[微信支付][退款]订单退款结果为:" + responseStr); // 设置接收时间 wxPayRefundRecord.setRecvTime(WXPayUtils.getSysTime()); /** 3 将回传的数据转为map */ Map<String, String> responseMap = WXPayUtils.parseXml(responseStr); String return_code = responseMap.get("return_code"); wxPayRefundRecord.setRecvReturnCode(return_code); wxPayRefundRecord.setRecvReturnMsg(responseMap.get("return_msg")); // 判断退款是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ String return_msg = responseMap.get("return_msg"); if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][退款]支付订单退款失败,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(responseMap.get("err_code_des")); resultObject.setData(wxPayRefundRecord); wxPayRefundRecord.setRecvErrCode(responseMap.get("err_code")); wxPayRefundRecord.setRecvErrCodeDes(responseMap.get("err_code_des")); // 插入微信退款记录 if(!insertWXPayRefundRecord(wxPayRefundRecord)){ rootLogger.error("[微信支付][退款]1支付退款记录插入失败!"); } rootLogger.error("[微信支付][退款]======结束(错误1)"); return resultObject; } }else{ rootLogger.error("[微信支付][退款]订单退款错误,错误信息为:" + responseMap.get("return_msg")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg("支付订单退款错误.错误信息为:" + responseMap.get("return_msg")); resultObject.setData(wxPayRefundRecord); // 插入微信退款记录 if(!insertWXPayRefundRecord(wxPayRefundRecord)){ rootLogger.error("[微信支付][退款]2支付退款记录插入失败!"); } rootLogger.info("[微信支付][退款]======结束(错误2)"); return resultObject; } // 设置返回数据 wxPayRefundRecord.setRecvAppid(responseMap.get("err_code")); wxPayRefundRecord.setRecvAppid(responseMap.get("mch_id")); wxPayRefundRecord.setRecvAppid(responseMap.get("nonce_str")); wxPayRefundRecord.setRecvAppid(responseMap.get("sign")); wxPayRefundRecord.setRecvAppid(responseMap.get("transaction_id")); wxPayRefundRecord.setRecvAppid(responseMap.get("out_trade_no")); wxPayRefundRecord.setRecvAppid(responseMap.get("out_refund_no")); wxPayRefundRecord.setRecvAppid(responseMap.get("refund_id")); wxPayRefundRecord.setRecvAppid(responseMap.get("refund_channel")); wxPayRefundRecord.setRecvAppid(responseMap.get("refund_fee")); wxPayRefundRecord.setRecvAppid(responseMap.get("total_fee")); wxPayRefundRecord.setRecvAppid(responseMap.get("fee_type")); wxPayRefundRecord.setRecvAppid(responseMap.get("cash_fee")); wxPayRefundRecord.setRecvAppid(responseMap.get("cash_refund_fee")); // 插入微信退款记录 if(!insertWXPayRefundRecord(wxPayRefundRecord)){ rootLogger.error("[微信支付][退款]3支付退款记录插入失败!"); } // TODO 这里能够根据退款申请结果进行订单处理 refundOrderDo() if(!wxPayDoService.refundOrderDo(payVO.getRefundOrderId(), wxPayRefundRecord)){ rootLogger.error("[微信支付][退款]业务处理失败。"); }else{ rootLogger.info("[微信支付][退款]业务处理成功。"); } /**4 返回前端 */ resultObject.setResultCode(WXPayUtils.ResultCode.SUCCESS.getType()); resultObject.setResultMsg("订单退款成功。"); resultObject.setResultCount("1"); resultObject.setData(wxPayRefundRecord); rootLogger.info("[微信支付][退款]======结束"); return resultObject; } /** * 退款查询 * 退款有必定延时,用零钱支付的退款20分钟内到帐,银行卡支付的退款3个工做往后从新查询退款状态 * @param refundOrderId 退款单号 * @return 退款详情 * @throws Exception */ public ResultObject searchRefundWXPay(String refundOrderId) throws Exception{ rootLogger.info("[微信支付][退款查询]======开始"); ResultObject resultObject = new ResultObject(); resultObject.setResultCount("0"); WXPayRefundResponseParam wxPayRefundResponseParam = new WXPayRefundResponseParam(); // 查询所用的参数map SortedMap<String,Object> paramters = new TreeMap<String,Object>(); paramters.put("appid", configReader.getWxAppID()); paramters.put("mch_id", configReader.getWxShopId()); paramters.put("nonce_str", WXPayUtils.getRandomString(32)); paramters.put("out_refund_no", refundOrderId); /**1.1 设置签名sign */ paramters.put("sign", WXPayUtils.createSign("UTF-8", paramters, DesUtil.decrypt(configReader.getWxAPIKey()))); rootLogger.info("[微信支付][退款查询]生成的签名为:" + paramters.get("sign")); /**2 发送HTTPS请求获取退款信息 */ String requestParamterStr = WXPayUtils.map2xmlBody(paramters, "xml"); //.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", ""); rootLogger.info("[微信支付][退款查询]订单退款查询参数为:" + requestParamterStr); HttpRequestUtils httpRequest = new HttpRequestUtils(); String responseStr = httpRequest.httpsRequest(configReader.getWxPayRefundSearchURL(), "POST", requestParamterStr); rootLogger.info("[微信支付][退款查询]订单退款查询结果为:" + responseStr); /** 3 将回传的数据转为map */ Map<String, String> responseMap = WXPayUtils.parseXml(responseStr); String return_code = responseMap.get("return_code"); String return_msg = responseMap.get("return_msg"); wxPayRefundResponseParam.setReturn_code(return_code); wxPayRefundResponseParam.setReturn_msg(return_msg); // 判断退款是否成功 if(StringUtils.isNotEmpty(return_code) && "SUCCESS".equals(return_code)){ if(StringUtils.isNotEmpty(return_msg) && !"OK".equals(return_msg)){ rootLogger.error("[微信支付][退款查询]订单退款查询失败,错误码是:" + responseMap.get("err_code") + ",错误信息为:" + responseMap.get("err_code_des")); wxPayRefundResponseParam.setResult_code(responseMap.get("result_code")); wxPayRefundResponseParam.setErr_code(responseMap.get("err_code")); wxPayRefundResponseParam.setErr_code_des(responseMap.get("err_code_des")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg(responseMap.get("err_code_des")); resultObject.setData(wxPayRefundResponseParam); rootLogger.error("[微信支付][退款查询]======结束(错误1)"); return resultObject; } }else{ rootLogger.error("[微信支付][退款查询]订单退款查询错误,错误信息为:" + responseMap.get("return_msg")); resultObject.setResultCode(WXPayUtils.ResultCode.FAILED.getType()); resultObject.setResultMsg("订单退款查询错误.错误信息为:" + responseMap.get("return_msg")); resultObject.setData(wxPayRefundResponseParam); rootLogger.error("[微信支付][退款查询]======结束(错误2)"); return resultObject; } // 设置返回类属性值 wxPayRefundResponseParam.setResult_code(responseMap.get("result_code")); wxPayRefundResponseParam.setErr_code(responseMap.get("err_code_des")); wxPayRefundResponseParam.setResult_code(responseMap.get("result_code")); if("SUCCESS".equals(responseMap.get("result_code"))){ wxPayRefundResponseParam.setAppid(responseMap.get("appid")); wxPayRefundResponseParam.setMch_id(responseMap.get("mch_id")); wxPayRefundResponseParam.setNonce_str(responseMap.get("nonce_str")); wxPayRefundResponseParam.setSign(responseMap.get("sign")); wxPayRefundResponseParam.setTransaction_id(responseMap.get("transaction_id")); wxPayRefundResponseParam.setOut_trade_no(responseMap.get("out_trade_no")); wxPayRefundResponseParam.setTotal_fee(responseMap.get("total_fee")); wxPayRefundResponseParam.setFee_type(responseMap.get("fee_type")); wxPayRefundResponseParam.setCash_fee(responseMap.get("cash_fee")); String refundCount = responseMap.get("refund_count"); wxPayRefundResponseParam.setRefund_count(refundCount); if(!StringUtils.isEmpty(refundCount)){ List<WXPayRefundResponseParam.refundInfo> infoList = new ArrayList<WXPayRefundResponseParam.refundInfo>(); for (int i = 0; i < Integer.valueOf(refundCount); i++) { WXPayRefundResponseParam.refundInfo info = new WXPayRefundResponseParam().new refundInfo(); info.setOut_refund_no(responseMap.get("out_refund_no_"+ String.valueOf(i))); info.setRefund_id(responseMap.get("refund_id_"+ String.valueOf(i))); info.setRefund_channel(responseMap.get("refund_channel_"+ String.valueOf(i))); info.setRefund_fee(responseMap.get("refund_fee_"+ String.valueOf(i))); info.setRefund_status(responseMap.get("refund_status_"+ String.valueOf(i))); info.setRefund_recv_accout(responseMap.get("refund_recv_accout_"+ String.valueOf(i))); infoList.add(info); } wxPayRefundResponseParam.setRefundInfoList(infoList); } } // TODO 这里能够根据查询结果进行其余处理 searchRefundOrderDo() if(!wxPayDoService.searchRefundOrderDo(refundOrderId, wxPayRefundResponseParam)){ rootLogger.error("[微信支付][退款]业务处理失败。"); }else{ rootLogger.info("[微信支付][退款]业务处理成功。"); } /**4 返回前端 */ resultObject.setResultCode(WXPayUtils.ResultCode.SUCCESS.getType()); resultObject.setResultMsg("订单退款查询成功。"); resultObject.setResultCount("1"); resultObject.setData(wxPayRefundResponseParam); rootLogger.info("[微信支付][退款查询]======结束"); return resultObject; } /** ===========================如下是内部私有方法=========================== */ /** * 对必须返回项进行验证 * 对签名进行校验 * @param wxPayCallBackParam 接收支付数据数据类 * @param errMeg 校验结果信息 * @return 校验结果(TRUE/FALSE) */ private boolean checkCallBackValidate(WXPayRecord wxPayRecord, SortedMap<String, String> responseMap ,String errMeg){ boolean isOK = true; if(StringUtils.isEmpty(wxPayRecord.getRecvAppid())){ errMeg += "appid为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvMchId())){ errMeg += "mch_id为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvDeviceInfo())){ errMeg += "nonce_str为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvSgin())){ errMeg += "sign为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvResultCode())){ errMeg += "result_code为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvOpeId())){ errMeg += "openid为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvTradeType())){ errMeg += "trade_type为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvBankType())){ errMeg += "bank_type为空|"; isOK = false; } if(wxPayRecord.getRecvTotalFee() == 0){ errMeg += "total_fee为0|"; isOK = false; } if(wxPayRecord.getRecvCashFee() == 0){ errMeg += "cash_fee为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvTransactionId())){ errMeg += "transaction_id为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvOutTradeNo())){ errMeg += "out_trade_no为空|"; isOK = false; } if(StringUtils.isEmpty(wxPayRecord.getRecvTimeEnd())){ errMeg += "time_end为空|"; isOK = false; } // 签名验证 return isOK; } /** * 装载数据库须要更新的数据(支付回调用) * @param responseMap 回传值 * @return 实体类 */ private WXPayRecord setParam(Map<String, String> responseMap){ WXPayRecord wxPayRecord = new WXPayRecord(); // 设置属性 wxPayRecord.setRecvAppid(responseMap.get("appid")); wxPayRecord.setRecvMchId(responseMap.get("mch_id")); wxPayRecord.setRecvDeviceInfo(responseMap.get("device_info")); wxPayRecord.setRecvNonceStr(responseMap.get("nonce_str")); wxPayRecord.setRecvSgin(responseMap.get("sign")); wxPayRecord.setRecvResultCode(responseMap.get("result_code")); wxPayRecord.setRecvErrCode(responseMap.get("err_code")); wxPayRecord.setRecvErrCodeDes(responseMap.get("err_code_des")); wxPayRecord.setRecvIsSubscribe(responseMap.get("is_subscribe")); wxPayRecord.setRecvTradeType(responseMap.get("trade_type")); wxPayRecord.setRecvBankType(responseMap.get("bank_type")); wxPayRecord.setRecvTotalFee(StringUtils.isEmpty(responseMap.get("total_fee"))?0:Integer.parseInt(responseMap.get("total_fee"))); wxPayRecord.setRecvFeeType(responseMap.get("fee_type")); wxPayRecord.setRecvCashFee(StringUtils.isEmpty(responseMap.get("cash_fee"))?0:Integer.parseInt(responseMap.get("cash_fee"))); wxPayRecord.setRecvCashFeeType(responseMap.get("cash_fee_type")); wxPayRecord.setRecvCouponFee(StringUtils.isEmpty(responseMap.get("coupon_fee"))?0:Integer.parseInt(responseMap.get("coupon_fee"))); wxPayRecord.setRecvCouponCount(StringUtils.isEmpty(responseMap.get("coupon_count"))?0:Integer.parseInt(responseMap.get("coupon_count"))); wxPayRecord.setRecvTransactionId(responseMap.get("transaction_id")); wxPayRecord.setRecvOutTradeNo(responseMap.get("out_trade_no")); wxPayRecord.setRecvAttach(responseMap.get("attach")); return wxPayRecord; } /** * 插入预支付收发记录 * @param wxPayOrderRecord 记录信息 * @return 操做结果 */ private boolean insertWXPayOrderRecord(WXPayOrderRecord wxPayOrderRecord){ boolean isOK = true; wxPayOrderRecord.setAddPid(PID); wxPayOrderRecord.setUpdPid(PID); wxPayOrderRecord.setWxPayOrderRecordId(uniqueCodeUtils.getUniqueCode(WXPayUtils.TableType.T_WXPAY_ORDER_RECORD)); if(wxPayOrderRecordMapper.insert(wxPayOrderRecord) != 1){ // 插入不成功 isOK = false; } return isOK; } /** * 插入支付记录 * @param wxPayCallBackParam 须要插入的数据 * @return 操做结果 */ private boolean insertWXPayRecord(WXPayRecord wxPayRecord){ boolean isOK = true; if(wxPayRecordMapper.selectCountByTransactionId(wxPayRecord.getRecvTransactionId()) > 0){ // 该数据已经处理过,跳过插入 rootLogger.warn("[微信支付]该微信支付数据已经插入,跳过处理。微信支付单号为:" + wxPayRecord.getRecvTransactionId()); return isOK; } wxPayRecord.setAddPid(PID); wxPayRecord.setUpdPid(PID); wxPayRecord.setWxPayRecordId(uniqueCodeUtils.getUniqueCode(WXPayUtils.TableType.T_WXPAY_RECORD)); if(wxPayRecordMapper.insert(wxPayRecord) != 1){ isOK = false; } return isOK; } /** * 插入支付关闭记录 * @param wxPayCloseRecord 须要插入的数据 * @return 操做结果 */ private boolean insertWXPayCloseRecord(WXPayCloseRecord wxPayCloseRecord){ boolean isOK = true; wxPayCloseRecord.setAddPid(PID); wxPayCloseRecord.setUpdPid(PID); wxPayCloseRecord.setWxPayCloseRecordId(uniqueCodeUtils.getUniqueCode(WXPayUtils.TableType.T_WXPAY_CLOSE_RECORD)); if(wxPayCloseRecordMapper.insert(wxPayCloseRecord) != 1){ // 插入不成功 isOK = false; } return isOK; } /** * 插入支付退款记录 * @param wxPayRefundRecord 须要插入的数据 * @return 操做结果 */ private boolean insertWXPayRefundRecord(WXPayRefundRecord wxPayRefundRecord){ boolean isOK = true; wxPayRefundRecord.setAddPid(PID); wxPayRefundRecord.setUpdPid(PID); wxPayRefundRecord.setWxPayRefundRecordId(uniqueCodeUtils.getUniqueCode(WXPayUtils.TableType.T_WXPAY_REFUND_RECORD)); if(wxPayRefundRecordMapper.insert(wxPayRefundRecord) != 1){ // 插入不成功 isOK = false; } return isOK; } }
4.微信处理调用接口web
package com.readygo.pet.service; import com.readygo.pet.model.WXPayCloseRecord; import com.readygo.pet.model.WXPayRecord; import com.readygo.pet.model.WXPayRefundRecord; import com.readygo.pet.vo.WXPayRefundResponseParam; import com.readygo.pet.vo.WXPaySearchResponseParam; /** * 程序名 WXPayDoService.java * 程序功能 微信处理后调用业务处理接口 * 做成者 xx * 做成日期 2016-05-04 * 修改履历 * 项目名 状态 做成者 做成日期 * -------------------------------------------- * pets 新规 xx 2016-05-04 */ public interface WXPayDoService { /** * 微信支付成功后回调时,须要作的业务处理接口 * @param orderId 商家订单号 * @param wxPayRecord 支付回传结果详情 * @return 处理成功或失败(TRUE/FALSE) */ boolean payOrderDo(String orderId, WXPayRecord wxPayRecord) throws Exception; /** * 查询支付结果后,根据查询结果须要作的业务处理接口 * @param orderId 订单编号 * @param wxPaySearchResponseParam 查询结果详情 * @return 处理成功或失败(TRUE/FALSE) */ boolean searchOrderDo(String orderId, WXPaySearchResponseParam wxPaySearchResponseParam) throws Exception; /** * 关闭支付订单后的业务处理接口 * @param orderId 订单编号 * @param wxPayCloseRecord 关闭结果详情 * @return 处理成功或失败(TRUE/FALSE) */ boolean closeOrderDo(String orderId, WXPayCloseRecord wxPayCloseRecord) throws Exception; /** * 支付订单退款申请后的业务处理接口 * @param refundOrderId 商家退款单编号 * @param wxPayRefundRecord 退款申请详情 * @return 处理成功或失败(TRUE/FALSE) */ boolean refundOrderDo(String refundOrderId, WXPayRefundRecord wxPayRefundRecord) throws Exception; /** * 订单退款查询结果后,根据查询结果须要作的业务处理接口 * @param refundOrderId * @param wxPayRefundResponseParam 查询详情 * @return 处理成功或失败(TRUE/FALSE) */ boolean searchRefundOrderDo(String refundOrderId, WXPayRefundResponseParam wxPayRefundResponseParam) throws Exception; }
5.微信接口处理实现类spring
package com.readygo.pet.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.readygo.pet.common.ConfigReader; import com.readygo.pet.common.Constant; import com.readygo.pet.mapper.CustomerOrderMapper; import com.readygo.pet.mapper.PaymentCodeMapper; import com.readygo.pet.mapper.WXPayRecordMapper; import com.readygo.pet.model.CustomerOrder; import com.readygo.pet.model.PaymentCode; import com.readygo.pet.model.WXPayCloseRecord; import com.readygo.pet.model.WXPayRecord; import com.readygo.pet.model.WXPayRefundRecord; import com.readygo.pet.service.WXPayDoService; import com.readygo.pet.utils.UniqueCodeUtils; import com.readygo.pet.utils.Utils; import com.readygo.pet.utils.WXPayUniqueCodeUtils; import com.readygo.pet.utils.WXPayUtils; import com.readygo.pet.vo.AddOrUpdOrderParmVO; import com.readygo.pet.vo.WXPayRefundResponseParam; import com.readygo.pet.vo.WXPaySearchResponseParam; import com.sun.xml.internal.ws.util.StringUtils; /** * 程序名 WXPayDoServiceImpl.java * 程序功能 微信处理后调用业务处理实现类 * 做成者 xx * 做成日期 2016-05-04 * 修改履历 * 项目名 状态 做成者 做成日期 * -------------------------------------------- * pets 新规 xx 2016-05-04 */ @Service @SuppressWarnings("unused") public class WXPayDoServiceImpl implements WXPayDoService { @Autowired private ConfigReader configReader; @Autowired private WXPayRecordMapper wxPayRecordMapper; @Autowired private CustomerOrderMapper customerOrderMapper; @Autowired private PaymentCodeMapper paymentCodeMapper; @Autowired private UniqueCodeUtils uniqueCodeUtils; @Autowired private WXPayUniqueCodeUtils wxPayUniqueCodeUtils; private final static String PID = "WBS0301WBS001"; /** * 微信支付成功后回调时,须要作的业务处理 * * @param wxPayRecord * 支付回传结果详情 * @return 处理成功或失败(TRUE/FALSE) */ public boolean payOrderDo(String orderId, WXPayRecord wxPayRecord) throws Exception { boolean isOK = true; //回调执行操做 isOK = this.checkPay(orderId, wxPayRecord); return isOK; } /** * 查询支付结果后,根据查询结果须要作的业务处理 * * @param orderId * 订单编号 * @param wxPaySearchResponseParam * 查询结果详情 * @return 处理成功或失败(TRUE/FALSE) */ public boolean searchOrderDo(String orderId, WXPaySearchResponseParam wxPaySearchResponseParam) throws Exception { boolean isOK = true; // 1.接收和保存支付信息--向微信支付记录表插入数据 // 2.更新订单/支付码等信息 // 2.1更新订单表中的付款状态、付款日期、支付方式、支付凭证单号、同时向订单支付表中插入数据 WXPayRecord wxPayRecord = new WXPayRecord(); // 支付记录id--系统生成 wxPayRecord.setWxPayRecordId(wxPayUniqueCodeUtils.getUniqueCode(WXPayUtils.TableType.T_WXPAY_RECORD)); // 接收返回状态码 wxPayRecord.setRecvReturnCode(wxPaySearchResponseParam.getReturn_code()); // 接收返回信息 wxPayRecord.setRecvReturnMsg(wxPaySearchResponseParam.getReturn_msg()); // 接收应用id wxPayRecord.setRecvAppid(wxPaySearchResponseParam.getAppid()); // 接收商户号 wxPayRecord.setRecvMchId(wxPaySearchResponseParam.getMch_id()); // 接收设备号 // 接收随机字符串 wxPayRecord.setRecvNonceStr(wxPaySearchResponseParam.getNonce_str()); // 接收签名 wxPayRecord.setRecvSgin(wxPaySearchResponseParam.getSign()); // 接收业务结果 wxPayRecord.setRecvResultCode(wxPaySearchResponseParam.getResult_code()); // 接收错误代码 wxPayRecord.setRecvErrCode(wxPaySearchResponseParam.getErr_code()); // 接收错误代码描述 wxPayRecord.setRecvErrCodeDes(wxPaySearchResponseParam.getErr_code_des()); // 接收用户标识 wxPayRecord.setRecvOpeId(wxPaySearchResponseParam.getOpenid()); // 接收关注公众帐号 // 接收交易类型 wxPayRecord.setRecvTradeType(wxPaySearchResponseParam.getTrade_type()); // 接收付款银行 wxPayRecord.setRecvBankType(wxPaySearchResponseParam.getBank_type()); // 接收总金额 if (!org.apache.commons.lang.StringUtils.isEmpty(wxPaySearchResponseParam.getTotal_fee())) { wxPayRecord.setRecvTotalFee(Integer.parseInt(wxPaySearchResponseParam.getTotal_fee())); } // 接收货币类型 wxPayRecord.setRecvFeeType(wxPaySearchResponseParam.getFee_type()); // 接收现金支付金额 if (!org.apache.commons.lang.StringUtils.isEmpty(wxPaySearchResponseParam.getCash_fee())) { wxPayRecord.setRecvCashFee(Integer.parseInt(wxPaySearchResponseParam.getCash_fee())); } // 接收现金支付货币类型 wxPayRecord.setRecvCashFeeType(wxPaySearchResponseParam.getCash_fee_type()); // 代金券 // 代金券使用量 // 支付订单号 wxPayRecord.setRecvTransactionId(wxPaySearchResponseParam.getTransaction_id()); // 商家订单号 wxPayRecord.setRecvOutTradeNo(wxPaySearchResponseParam.getOut_trade_no()); // 商家服务包 // 支付完成时间 wxPayRecord.setRecvTimeEnd(wxPaySearchResponseParam.getTime_end()); // 接收时间 // …… // 添加时间 wxPayRecord.setAddTime(Utils.getSysTime()); // 更新时间 wxPayRecord.setUpdTime(Utils.getSysTime()); //查询微信支付结果执行操做 isOK = this.checkPay(orderId, wxPayRecord); return isOK; } /** * 关闭支付订单后的业务处理 * * @param orderId * 订单编号 * @param wxPayCloseRecord * 关闭结果详情 * @return 处理成功或失败(TRUE/FALSE) */ public boolean closeOrderDo(String orderId, WXPayCloseRecord wxPayCloseRecord) throws Exception { boolean isOK = true; return isOK; } /** * 支付订单退款申请后的业务处理 * * @param refundOrderId * 商家退款单编号 * @param wxPayRefundRecord * 退款申请详情 * @return 处理成功或失败(TRUE/FALSE) */ public boolean refundOrderDo(String refundOrderId, WXPayRefundRecord wxPayRefundRecord) throws Exception { boolean isOK = true; return isOK; } /** * 订单退款查询结果后,根据查询结果须要作的业务处理 * * @param refundOrderId * * @param wxPayRefundResponseParam * 查询详情 * @return 处理成功或失败(TRUE/FALSE) */ public boolean searchRefundOrderDo(String refundOrderId, WXPayRefundResponseParam wxPayRefundResponseParam) throws Exception { boolean isOK = true; return isOK; } /** * 添加支付码 * * @param customerOrderInfo * @return 成功/失败 */ public void creatPayMentcode(CustomerOrder customerOrder) { int i; PaymentCode paymentCode = new PaymentCode(); String groupCode = uniqueCodeUtils.getUniqueCode(Constant.TableType.T_PAYMENT_CODE); paymentCode.setGroupCode(groupCode); for (i = 0; i < customerOrder.getNumber(); i++) { // 支付码9位,数据库是10位 Integer code = Integer.parseInt(uniqueCodeUtils.getPaymentCode()); paymentCode.setAddPid(PID); paymentCode.setAddUid(customerOrder.getCustomerId()); paymentCode.setCustomerId(customerOrder.getCustomerId()); // TODO 有效期不肯定 paymentCode.setInvaildDate(""); paymentCode.setInvaildFlag(Constant.ValidFlagType.VALID_FLAG.getType()); paymentCode.setOrderId(customerOrder.getOrderId()); paymentCode.setPaymentCode(code); paymentCode.setPrice(customerOrder.getPrice()); // TODO 没有发起退款没有退款编号 paymentCode.setRefoundAppId(""); paymentCode.setRefundFlag(Constant.RefundFlag.blank.getType()); paymentCode.setRemarks(customerOrder.getRemarks()); paymentCode.setServiceId(customerOrder.getServiceId()); paymentCode.setShopId(customerOrder.getShopId()); paymentCode.setUpdPid(PID); paymentCode.setUpdUid(customerOrder.getCustomerId()); paymentCode.setUseFlag(Constant.UseFlag.USE.getFlag()); // TODO 开始时间不肯定 paymentCode.setValidBeginTime(""); // TODO 结束时间不肯定 paymentCode.setValidEndTime(""); paymentCode.setValidFlag(Constant.ValidFlagType.VALID_FLAG.getType()); paymentCodeMapper.insertSelective(paymentCode); } // 支付码没有所有生成手动回滚 if (i != customerOrder.getNumber()) { throw new RuntimeException("支付码生成失败"); } } /** * 支付成功向数据库插入数据 * **/ public boolean checkPay(String orderId, WXPayRecord wxPayRecord) { boolean isOK = false; // 1.先拿orderId查询状态是否已经改变 // 2.若是已经改成已付款,则不须要执行重复更新操做;不然,执行更新操做 CustomerOrder customerOrderTem = customerOrderMapper.selectByPrimaryKey(orderId); if (customerOrderTem == null) { isOK = false; } else if (customerOrderTem.getPayFlag() == Constant.PayFlag.UNPAY.getType()) { // 插入数据 int success = wxPayRecordMapper.insertSelective(wxPayRecord); if (success == 1) { // 插入成功 // 更新订单表 CustomerOrder customerOrder = new CustomerOrder(); customerOrder.setOrderId(orderId); customerOrder.setPayFlag(1); customerOrder.setPayDate(Utils.getSysTime()); // 支付方式 customerOrder.setPayType(Constant.PayType.WEIXIN.getType()); // 支付凭证 customerOrder.setPayCredenceId(wxPayRecord.getRecvTransactionId()); int success2 = customerOrderMapper.updateByPrimaryKeySelective(customerOrder); if (success2 == 1) { // 向订单支付表插入数据 CustomerOrder customerOrderInfo = customerOrderMapper.selectByPrimaryKey(orderId); this.creatPayMentcode(customerOrderInfo); } else { // 更新失败,抛出异常 isOK = false; // 抛出异常 throw new RuntimeException(); } } else { isOK = false; } } return isOK; } }