package com.kk.pay.weixin.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.kk.pay.base.model.PayResult; import com.kk.pay.base.model.enums.ResultCode; import com.kk.pay.util.*; import com.kk.pay.weixin.model.PayOrderParam; import com.kk.pay.weixin.model.PayOrderResult; import com.kk.pay.weixin.model.enums.PayOrderField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; 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.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 在微信浏览器中,h5页面调起 */ @Controller @RequestMapping("/kk/weixin/h5pay") public class WeixinH5PayController { private static Log logger = LogFactory.getLog(WeixinH5PayController.class); // pay 微信支付商户号 String mchId = WebPropertiesUtil.getInstance().getValue("weixin.mchid"); //mp.weixin 微信公共账号 appId String appId = WebPropertiesUtil.getInstance().getValue("weixin.appid"); // 申请开通微信支付后,发给开发者。用于计算签名 String apiKey = WebPropertiesUtil.getInstance().getValue("weixin.pay.apikey"); // 微信支付 统一下单接口 String payOrderUrl = WebPropertiesUtil.getInstance().getValue("weixin.pay.unifiedorder"); // 支付 回调url String notifyUrl = WebPropertiesUtil.getInstance().getValue("server.url") + "/kk/weixin/scan/notify"; /** * 测试 微信openId kk * <p/> * voucherId 客户订单号 */ String openId = ""; @RequestMapping(value = "", method = RequestMethod.GET) public String pay(HttpServletRequest request, HttpServletResponse response, Model model) { String x = DateUtil.format(new Date(), new SimpleDateFormat("yyyyMMddHHmmss")); String voucherId = "test_kk_" + x; int total = 1;// 1分钱 model.addAttribute("voucherId", voucherId); model.addAttribute("total", total); return "weixin/pay"; } @RequestMapping(value = "do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public String payDo(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("voucherId") String voucherId, @RequestParam("total") int total) { PayOrderParam param = new PayOrderParam(); // 基本信息 param.setAppid(appId); param.setMchId(mchId); param.setTradeType("JSAPI"); // 公众号支付 param.setOpenid(openId); // openId!! param.setSpbillCreateIp(LocalIPUtil.getLocalAddr()); //param.setLimitPay("no_credit"); // 禁止用信用卡 param.setNotifyUrl(notifyUrl); // 支付成功回调url // 业务相关参数 JSONObject atach = new JSONObject(); atach.put("order_id", 11); param.setAttach(atach.toString()); param.setBody("支付测试订单"); param.setTotalFee(total); param.setOutTradeNo(voucherId); // 客户订单号 //签名 param.setNonceStr(EncryptUtil.random()); Map<String, Object> data = BeanUtil.object2Map(param); // 参数列表 param.setSign(SignUtil.sign(data, apiKey)); // 计算sign data.put(PayOrderField.SIGN.getField(), param.getSign()); // sign放到map中,为后续转xml // 校验参数是否齐全 try { ValidateUtil.validate(PayOrderField.values(), data); } catch (Exception e) { return JsonUtil.getJson(1, e.getMessage()).toString(); } // 转成xml格式 String xml = XmlUtil.toXml(data); logger.info("post.xml=" + xml); // 发送支付请求 String resultStr = WeixinUtil.postXml(payOrderUrl, xml); logger.info("result=" + resultStr); // 校验返回结果 签名 Map<String, Object> resultMap = XmlUtil.parseXml(resultStr); String resultSign = SignUtil.sign(resultMap, apiKey); if (resultMap.get("sign") == null || !resultMap.get("sign").equals(resultSign)) { logger.info("sign is not correct, " + resultMap.get("sign") + " " + resultSign); throw new RuntimeException("签名校验不通过"); } PayOrderResult result = BeanUtil.map2Object(PayOrderResult.class, resultMap); PayResult payResult = new PayResult(); if (ResultCode.SUCCESS.getCode().equals(result.getReturnCode()) && ResultCode.SUCCESS.getCode().equals(result.getResultCode())) { payResult.setResultCode(ResultCode.SUCCESS.getCode()); } else { payResult.setResultCode(ResultCode.FAIL.getCode()); } payResult.setMessage(result.getReturnMsg()); payResult.setErrCode(result.getErrCode()); payResult.setErrorMessage(result.getErrCodeDes()); payResult.setPrepayId(result.getPrepayId()); payResult.setCodeUrl(result.getCodeUrl()); JSONObject ret = JsonUtil.getOkJson(); ret.put("reslt", payResult); ret.put("param", genJsParam(payResult)); return ret.toString(); } private JSONObject genJsParam(PayResult payResult) { long timestamp = System.currentTimeMillis() / 1000; String nonceStr = EncryptUtil.random(); Map<String, Object> data = new HashMap<String, Object>(); data.put("appId", appId); data.put("timeStamp", timestamp); data.put("nonceStr", nonceStr); data.put("package", "prepay_id=" + payResult.getPrepayId()); data.put("signType", "MD5"); data.put("paySign", SignUtil.sign(data, apiKey)); // 计算sign JSONObject ret = JSONObject.parseObject(JSON.toJSONString(data)); return ret; } }