前几天刚做了微信公众号的支付功能,总结下。
下载sdk,放入代码中
安装操作证书
api密钥
查看接口文档
查看开发文档
java 代码
-
@RequestMapping(value = “/getCarPay”, method = RequestMethod.GET)
@ApiOperation(value = "微信支付", notes = "微信支付") @ParamValid public Map getCarPayInfor(HttpServletRequest request, HttpSession httpSession) throws Exception { //TODO 测试 //httpSession.setAttribute(tenantKey, "TEST1"); //String openId = "*"; String ordernumber = request.getParameter("ordernumber"); logger.info("订单号=" + ordernumber); String productinter = request.getParameter("productinter"); logger.info("金额=" + productinter); String tenantId2 = CookieUtil.getCookiesByKey(request, tenantKey); String openId = request.getHeader(InformationConstant.HEADER_OPENID); logger.info("openID>>>>>>>>>>>>>" + openId); //logger.info(" tenantId2 = " + tenantId2); httpSession.setAttribute(tenantKey, tenantId2); Map<String, String> payMap = new HashMap<String, String>(); try { Map<String, String> paraMap = new HashMap<String, String>(); //获取请求ip地址 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.indexOf(",")!=-1){ String[] ips = ip.split(","); ip = ips[0].trim(); } paraMap.put("appid", "*"); paraMap.put("body", "订单结算");//所支付的名称 paraMap.put("mch_id", "*"); //商户号 paraMap.put("nonce_str", WXPayUtil.generateNonceStr());//生成UUID paraMap.put("openid", openId); paraMap.put("out_trade_no", ordernumber);//订单号 paraMap.put("spbill_create_ip", ip); paraMap.put("total_fee",productinter); paraMap.put("trade_type", "JSAPI"); paraMap.put("notify_url","http://*:9997/information/api/v1/changeinter");// 这个地址做我们业务处理如:修改订单状态,赠送积分等 String sign = WXPayUtil.generateSignature(paraMap, "*"); paraMap.put("sign", sign); String xml = WXPayUtil.mapToXml(paraMap);//将所有参数(map)转xml格式 // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String xmlStr = HttpRequest.sendPost(unifiedorder_url, xml);//发送post请求"统一下单接口"返回预支付id:prepay_id //以下内容是返回前端页面的json数据 String prepay_id = "";//预支付id if (xmlStr.indexOf("SUCCESS") != -1) { Map<String, String> map = WXPayUtil.xmlToMap(xmlStr); prepay_id = (String) map.get("prepay_id"); } payMap.put("appId", "*"); payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+""); payMap.put("nonceStr", WXPayUtil.generateNonceStr()); payMap.put("signType", "MD5"); payMap.put("package", "prepay_id=" + prepay_id); String paySign = WXPayUtil.generateSignature(payMap, "*"); payMap.put("paySign", paySign); } catch (Exception e) { logger.error("查询状态出现异常", e); } finally { logger.info("支付成功==>end..."); } return payMap; }
HTML代码
function pay() {
$.ajax({
type: "GET",
//url: "http://localhost:9997/information/api/v1/getCarPay?ordernumber="+orderNo,
url: rootPath + "/information/api/v1/getCarPay?ordernumber="+orderNo+"&productinter="+productinter,
dataType: "json",
//contentType: "application/json",
success: function (res) {
appId = res.appId;
timeStamp = res.timeStamp;
nonceStr = res.nonceStr;
package = res.package;
signType = res.signType;
paySign = res.paySign;
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady',
onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady',
onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady',
onBridgeReady);
}
} else {
onBridgeReady();
}
},
error: function (data) {
}
});
}
function onBridgeReady(){
WeixinJSBridge.invoke( 'getBrandWCPayRequest', {
"appId":appId, //公众号名称,由商户传入
"timeStamp":timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":nonceStr, //随机串
"package":package,
"signType":signType, //微信签名方式:
"paySign":paySign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
console.log('支付成功');
//支付成功后跳转的页面
}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
console.log('支付取消');
}else if(res.err_msg == "get_brand_wcpay_request:fail"){
console.log('支付失败');
WeixinJSBridge.call('closeWindow');
} //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
);
}
前台页面在微信支付中注册
参照官方文档
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
开发过程中遇到的问题:
a.当前页面的URL未注册
在商户平台配置该url,产品中心—开发配置—支付授权目录
配置url的时候保留最后一个斜线
b.支付未获取total_fee值
这个值只能为整数,而且默认以分为单位。
c.notify_url回调总是失败
这个url必须为80端口下面,而且外网可以访问。我们这个项目所有请求都是通过getWeChat模块通过zuul转发的,所以要看配置文件中如何配置的。而且在getWeChat模块写了拦截器的,拦截了所有请求进行处理了,所以我用postman请求,总是报502,在这个类中做处理后,就可以外网访问了。