//微信支付依赖
<dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency>
package com.ruoyi.web.controller.app; import ch.qos.logback.core.joran.spi.XMLUtil; import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayUtil; import com.ruoyi.common.config.VxConfig; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.VxPayUtil; import com.ruoyi.system.domain.SvcOrder; import com.ruoyi.system.domain.SysUser; import com.ruoyi.system.domain.WXPayConstants; import com.ruoyi.system.domain.WXPayXmlUtil; import com.ruoyi.system.service.ISvcOrderService; import com.ruoyi.system.service.ISysUserService; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.jdom.JDOMException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; /**微信小程序支付**/ @Controller @RequestMapping("/app/vxPay") public class AppVxPayController { @Autowired private ISvcOrderService iSvcOrderService; @Autowired private ISysUserService iSysUserService; @PostMapping("/pay") @ResponseBody public AjaxResult doUnifiedOrder(Long orderId,Long userId){ SvcOrder svcOrder = iSvcOrderService.selectSvcOrderById(orderId); if(userId==null){ return AjaxResult.error("缺少userId参数"); } SysUser sysUser = iSysUserService.selectUserById(userId); Map resultMap=new HashMap(); //String openid = baseRequest.getRequestData().getOpenId(); VxConfig config = null; WXPay wxpay =null; try { config = new VxConfig(); wxpay= new WXPay(config); } catch (Exception e) { e.printStackTrace(); } //生成的随机字符串 String nonce_str = WXPayUtil.generateNonceStr(); //获取客户端的ip地址 //获取本机的ip地址 InetAddress addr = null; try { addr = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } String spbill_create_ip = addr.getHostAddress(); //支付金额,需要转成字符串类型,否则后面的签名会失败 int total_fee=1; //商品描述 String body = "服务支付"; //商户订单号 String out_trade_no= WXPayUtil.generateNonceStr(); //统一下单接口参数 HashMap<String, String> data = new HashMap<String, String>(); String sign = null; data.put("appid", config.getAppID()); data.put("attach", String.valueOf(svcOrder.getOrderId())); data.put("body", body); data.put("mch_id", config.getMchID()); data.put("nonce_str", nonce_str); data.put("notify_url", config.getNotifyUrl()); data.put("out_trade_no",out_trade_no); data.put("spbill_create_ip", spbill_create_ip); data.put("total_fee", String.valueOf((new Double(svcOrder.getOrderMoney()*100d)).intValue())); data.put("trade_type","JSAPI"); data.put("openid", sysUser.getWechatOpenId()); try { sign = WXPayUtil.generateSignature(data, config.getKey()); } catch (Exception e) { e.printStackTrace(); } data.put("sign",sign); try { Map<String, String> rMap = wxpay.unifiedOrder(data); System.out.println("统一下单接口返回: " + rMap); String return_code = (String) rMap.get("return_code"); String result_code = (String) rMap.get("result_code"); String nonceStr = WXPayUtil.generateNonceStr(); resultMap.put("nonceStr", nonceStr); Long timeStamp = System.currentTimeMillis() / 1000; if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) { String prepayid = rMap.get("prepay_id"); resultMap.put("package", "prepay_id="+prepayid); resultMap.put("signType", "MD5"); //这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误 resultMap.put("timeStamp", timeStamp + ""); //再次签名,这个签名用于小程序端调用wx.requesetPayment方法 resultMap.put("appId",config.getAppID()); sign = WXPayUtil.generateSignature(resultMap, config.getKey()); resultMap.put("paySign", sign); System.out.println("生成的签名paySign : "+ sign); return AjaxResult.success(resultMap); }else{ return AjaxResult.success(resultMap); } } catch (Exception e) { e.printStackTrace(); return AjaxResult.success(resultMap); } } @PostMapping("/vxNotify") @ResponseBody public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("进入微信支付回调接口-----------------------------"); VxConfig config = new VxConfig(); BufferedReader br = new BufferedReader(new InputStreamReader(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(); System.out.println("微信回调数据==============="+notityXml); String resXml = ""; Document doc = DocumentHelper.parseText(notityXml); Map<String, Object> map = VxPayUtil.Dom2Map(doc); System.out.println("微信回调数据转map以后=========="+map); String returnCode = (String) map.get("return_code"); System.out.println("微信回调sign============="+map.get("sign")); if ("SUCCESS".equals(returnCode)) { //验证签名是否正确 Map<String, String> validParams = VxPayUtil.paraFilter(map); //回调验签时需要去除sign和空值参数 String prestr = VxPayUtil.createLinkString(validParams); System.out.println("签名验证结果======================"+VxPayUtil.verify(prestr, (String) map.get("sign"), config.getKey(), "utf-8")); //根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等 if (VxPayUtil.verify(prestr, (String) map.get("sign"), config.getKey(), "utf-8")) { /**此处添加自己的业务逻辑代码start**/ Long orderId = Long.valueOf(String.valueOf(map.get("attach"))); System.out.println("微信回调返回的orderId============"+orderId); SvcOrder svcOrder = iSvcOrderService.selectSvcOrderById(orderId); if(svcOrder.getState()==4){ svcOrder.setState(5); svcOrder.setPayTime(new Date()); iSvcOrderService.updateSvcOrder(svcOrder); } //注意要判断微信支付重复回调,支付成功后微信会重复的进行回调 /**此处添加自己的业务逻辑代码end**/ //通知微信服务器已经支付成功 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; } } else { 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(); } /**微信扫码支付 * */ @PostMapping("/weixinPay") @ResponseBody public AjaxResult weixinPay(Long orderId) { // 以下的各种参数,不懂得在微信支付开发文档里面可以查找 SvcOrder svcOrder = iSvcOrderService.selectSvcOrderById(orderId); String out_trade_no = orderId.toString(); // 订单号 // (调整为自己的生产逻辑) // 账号信息 WXPay wxpay =null; VxConfig config = new VxConfig(); wxpay= new WXPay(config); String appid = config.getAppID(); // appid // String appsecret = PayConfigUtil.APP_SECRET; // appsecret String mch_id = config.getMchID(); // 商户号 String key = config.getKey(); // key String nonce_str = WXPayUtil.generateNonceStr(); // 获取发起电脑 ip InetAddress addr = null; try { addr = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } String spbill_create_ip = addr.getHostAddress(); // 回调接口 String notify_url = config.getNotifyUrl(); // 这里说明支付是什么类型,NATIVE(二维码),MWEB(H5) String trade_type = "NATIVE"; HashMap<String, String> packageParams = new HashMap<String, String>(); packageParams.put("appid", appid); // 这里可以传你要执行业务需要的参数,可以尝试传个MAP过去,我也没试过 packageParams.put("attach", orderId.toString()); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str); packageParams.put("body", "测试"); // (调整为自己的名称) packageParams.put("out_trade_no", out_trade_no); packageParams.put("total_fee", String.valueOf((new Double(svcOrder.getOrderMoney()*100d)).intValue())); // 价格的单位为分 packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("notify_url", notify_url); packageParams.put("trade_type", trade_type); // 签名 String sign = null; try { sign = WXPayUtil.generateSignature(packageParams, config.getKey()); } catch (Exception e) { e.printStackTrace(); } packageParams.put("sign", sign); // 将参数转换成xml //String requestXML = null; try { //requestXML = this.mapToXml(packageParams); } catch (Exception e) { e.printStackTrace(); } // 访问支付地址 Map<String, String> rMap = null; try { rMap = wxpay.unifiedOrder(packageParams); } catch (Exception e) { e.printStackTrace(); } // Map map = new HashMap(); // try { // map = XMLUtil.doXMLParse(resXml); // } catch (JDOMException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // 获取支付的url String urlCode = (String) rMap.get("code_url"); return AjaxResult.success(urlCode); } /** * 将Map转换为XML格式的字符串 * * @param data Map类型数据 * @return XML格式的字符串 * @throws Exception */ public static String mapToXml(Map<String, String> data) throws Exception { org.w3c.dom.Document document = WXPayXmlUtil.newDocument(); org.w3c.dom.Element root = document.createElement("xml"); document.appendChild(root); for (String key: data.keySet()) { String value = data.get(key); if (value == null) { value = ""; } value = value.trim(); org.w3c.dom.Element filed = document.createElement(key); filed.appendChild(document.createTextNode(value)); root.appendChild(filed); } TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); transformer.transform(source, result); String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", ""); try { writer.close(); } catch (Exception ex) { } return output; } }