先贴页面代码
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%><!doctype html><!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]--><!--[if IE 7]> <html class="ie7 oldie"> <![endif]--><!--[if IE 8]> <html class="ie8 oldie"> <![endif]--><!--[if gt IE 8]><!--><html class=""><!--<![endif]--><head><meta charset="utf-8"><jsp:include page="meta.jsp"/><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!-- HTTP 1.1 --><meta http-equiv="pragma" content="no-cache"><!-- HTTP 1.0 --><meta http-equiv="cache-control" content="no-cache"><META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <!-- Prevent caching at the proxy server --><meta http-equiv="expires" content="-1"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" /><title>订单支付-${seoTitle}</title><link href="${pageContext.request.contextPath}/css/style.css" rel="stylesheet" type="text/css"><link href="${pageContext.request.contextPath}/css/boilerplate.css" rel="stylesheet" type="text/css"><link href="${pageContext.request.contextPath}/css/common.css" rel="stylesheet" type="text/css"><!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--><script src="${pageContext.request.contextPath}/js/respond.min.js"></script></head><body> <div class="gridContainer clearfix"> <div class="orderPayment"> <!--页头--> <header class="header"> <div class="left pull-left"> <a href="javascript:history.go(-1);"><img src="${pageContext.request.contextPath}/images/header-arrow.png" /></a> </div> <div class="right pull-right"> <a href="${pageContext.request.contextPath}/home.shtml"><img src="${pageContext.request.contextPath}/images/header-home.png" /></a> </div> <div class="center">订单支付</div> </header> <!--内容--> <div class="content"> <div class="box1"> 订单号:<span class="color-black">${orderNum}</span> </div> <div class="box1"> 支付金额:<span class="color-blue">¥${price}元</span> </div> </div> <!--footer--> <footer class="footer"> <div class="btn"> <input type="button" οnclick="pay()" value="微信支付" /> </div> </footer> </div> </div> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.3.min.js"></script> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/js/share.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/js/common.js"></script> <script type="text/javascript">var appId = "${weiXinOrderRequset.appId}";var timeStamp =${weiXinOrderRequset.timeStamp};var nonceStr = "${weiXinOrderRequset.nonceStr}";var signature = "${weiXinOrderRequset.signature}";var paySign = "${weiXinOrderRequset.paySign}";var pkg = "${weiXinOrderRequset.get("package")}";var signType = "${weiXinOrderRequset.signType}"; shareData= { title : '****', desc : '${weiXinOrderRequset.msg}', link : '${weiXinOrderRequset.hostUrl}/home.shtml?userId=${weiXinOrderRequset.userId}', imgUrl : '${weiXinOrderRequset.hostUrl}/image/shareLogo.png' }; $(function () { wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: appId, // 必填,公众号的唯一标识 timestamp: timeStamp, // 必填,生成签名的时间戳 nonceStr: nonceStr, // 必填,生成签名的随机串 signature: signature,// 必填,签名,见附录1 jsApiList: ['chooseWXPay','onMenuShareTimeline', 'onMenuShareAppMessage','showOptionMenu'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function () { shareToFriend(); shareToFriends(); }); }); function pay() { wx.chooseWXPay({ "timestamp": timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 "nonceStr": nonceStr, // 支付签名随机串,不长于 32 位 "package": pkg, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) "signType": signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' "paySign": paySign, // 支付签名 complete: function (res) { // 支付成功后的回调函数 if(res.errMsg=='chooseWXPay:ok'){ location.href = "${pageContext.request.contextPath}/order/payResult.shtml?flag=true&orderId=${orderId}"; }else{ location.href = "${pageContext.request.contextPath}/order/payResult.shtml?flag=false&orderId=${orderId}"; } } }); }</script></body></html>
这个页面需要从一个controller跳过来 路径里面的orderId是我应用自己的订单id
@RequestMapping("/pay/{orderId}") public String pay(Model model, @PathVariable String orderId, HttpServletRequest request) throws GlobalException, ClassNotFoundException, IllegalAccessException, InstantiationException { String ip = HttpClientUtil.getIpAddr(request); Integer userId = super.getUserFromSession(request); User user = userService.findUserById(userId); String jsTicket = weiXinService.getJSTicket().getParamValue(); // User user = userService.findUserById(2); if (user != null) { Order order = orderService.findOrderById(orderId); model.addAttribute("orderNum", order.getOrderNum()); model.addAttribute("price", order.getOrderPrice().setScale(2)); // XStream xs = SerializeXmlUtil.createXstream(); // 在微信上生成订单 OrderResData orderResponse = weiXinService.createOrder(order, ip); System.out.println(orderResponse.toString()); if (orderResponse != null && orderResponse.getResult_code().equals("SUCCESS")) { Map<String, Object> payMap = new HashMap<String, Object>(); long timeStamp = System.currentTimeMillis() / 1000; payMap.put("appId", orderResponse.getAppid()); payMap.put("timeStamp", timeStamp); payMap.put("nonceStr", orderResponse.getNonce_str()); payMap.put("signType", "MD5"); payMap.put("package", "prepay_id=" + orderResponse.getPrepay_id()); String paySign = Signature.getSign(payMap); payMap.put("paySign", paySign); Util.log("paySign=" + paySign); // 生成微信签名 Map<String, Object> signatureMap = new HashMap<String, Object>(); signatureMap.put("noncestr", orderResponse.getNonce_str()); signatureMap.put("jsapi_ticket", jsTicket); signatureMap.put("timestamp", timeStamp); signatureMap.put("url", Configure.getHostUrl() + "/order/pay/" + orderId + ".shtml"); String signature = Signature.getJSSignature(signatureMap); payMap.put("signature", signature); payMap.put("pg", orderResponse.getPrepay_id()); model.addAttribute("weiXinOrderRequset", payMap); model.addAttribute("orderId", order.getId()); } } return "/prePay"; }
这里面调用了在微信上生成订单的方法:
@Override public OrderResData createOrder(Order order, String ip) throws GlobalException, ClassNotFoundException, IllegalAccessException, InstantiationException { PropertiesUtil propertiesUtil = PropertiesUtil.getInstance(); // 获取用户信息 OrderReqData orderRequset = new OrderReqData(); orderRequset.setAppid(Configure.getAppid()); orderRequset.setMch_id(Configure.getMchid()); orderRequset.setDevice_info("WEB"); orderRequset.setNonce_str(StringUtil.generateUUID()); // orderRequset.setSign(""); orderRequset.setBody("购买商品"); // orderRequset.setDetail(""); if(!StringUtils.isEmpty(order.getDes())){ orderRequset.setAttach(order.getDes());// } orderRequset.setOut_trade_no(order.getId()); orderRequset.setFee_type("CNY"); orderRequset.setTotal_fee( order.getOrderPrice().multiply(new BigDecimal(100)).setScale(0, RoundingMode.CEILING).toString()); orderRequset.setSpbill_create_ip(ip); orderRequset.setTime_start(DateFormatUtils.format(new Date(), "yyyyMMddHHmmss")); orderRequset.setTime_expire( DateFormatUtils.format(new Date(System.currentTimeMillis() + 15 * 60 * 1000), "yyyyMMddHHmmss")); // orderRequset.setGoods_tag("");//代金券标记 orderRequset.setNotify_url(Configure.getNotifyUrl()); orderRequset.setTrade_type("JSAPI"); // orderRequset.setLimit_pay(""); orderRequset.setOpenid(order.getUser().getWeiXinUser().getOpenId()) String sign = null; try { sign = Signature.getSign(orderRequset); } catch (Exception e) { e.printStackTrace(); throw new GlobalException(ExceptionCode.WeiXin.SIGN_ERROR, "签名错误"); } orderRequset.setSign(sign); // params.put("sign",sign); String orderResponseString = ""; weiXinOrderRequsetService = new WeiXinOrderRequsetService(Configure.CREATE_ORDER_API); orderResponseString = weiXinOrderRequsetService.request(orderRequset, Configure.getCertPassword()); OrderResData orderResData = (OrderResData) Util.getObjectFromXML(orderResponseString, OrderResData.class); return orderResData; }
然后这个方法里面又用到了一系列微信提供的工具类,这些类都可以在微信提供的java demo里面找到。