微信小程序 支付后台java实现实例

1.小程序前端获取微信 openId 以及订单号 传给后台
2,后台根据 openId 和订单号进行签名 post 微信统一下单接口
3.后台获取微信返回的xml字符串 解析 二次签名以后返回给前端
4.前端调起支付微信支付 API

先看支付函数:

//获取支付信息 @EngineFunction("getPayInformation") public static Map<String, Object> getPayInformation( @EngineFunctionParam("orderId") String orderId ) throws AVException, UnsupportedEncodingException, DocumentException { Map<String, Object> reqMap = new TreeMap<String, Object>( new Comparator<String>() { public int compare(String obj1, String obj2) { // 升序排序 return obj1.compareTo(obj2); } }); if (AVUser.getCurrentUser() != null) { String authDataJson = JSONArray.toJSONString(AVUser.getCurrentUser().get("authData")); JSONObject jsonObject = JSON.parseObject(authDataJson); jsonObject.get("lc_weapp"); JSONObject j2 = JSON.parseObject(jsonObject.get("lc_weapp").toString()); String openId = (String) j2.get("openid"); AVQuery<Order> query = AVObject.getQuery(Order.class); Order order = query.get(orderId); reqMap.put("appid", System.getenv("appid")); reqMap.put("mch_id", System.getenv("mch_id")); reqMap.put("nonce_str", WXPayUtil.getNonce_str()); reqMap.put("body", new String(order.getDishesList().toString().getBytes("UTF-8"))); reqMap.put("openid", openId); reqMap.put("out_trade_no", order.getObjectId()); reqMap.put("total_fee", 1); //订单总金额,单位为分 reqMap.put("spbill_create_ip", "192.168.0.1"); //用户端ip reqMap.put("notify_url", System.getenv("notify_url")); //通知地址 reqMap.put("trade_type", System.getenv("trade_type")); //trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识 String reqStr = WXPayUtil.map2Xml(reqMap); String resultXml = HttpRequest.sendPost(reqStr); System.out.println("微信请求返回:" + resultXml); //解析微信返回串 如果状态成功 则返回给前端 if (WXPayUtil.getReturnCode(resultXml) != null && WXPayUtil.getReturnCode(resultXml).equals("SUCCESS")) { //成功 Map<String, Object> resultMap = new TreeMap<>( new Comparator<String>() { public int compare(String obj1, String obj2) { // 升序排序 return obj1.compareTo(obj2); } }); resultMap.put("appId", System.getenv("appid")); resultMap.put("nonceStr", WXPayUtil.getNonceStr(resultXml));//解析随机字符串 resultMap.put("package", "prepay_id=" + WXPayUtil.getPrepayId(resultXml)); resultMap.put("signType", "MD5"); resultMap.put("timeStamp", String.valueOf((System.currentTimeMillis() / 1000)));//时间戳 String paySign = WXPayUtil.getSign(resultMap); resultMap.put("paySign", paySign); return resultMap; } else { throw new AVException(999, "微信请求支付失败"); } } else { throw new AVException(98, "当前未登录用户"); } }

其中appid和mch_id可以用系统常量

PS:这里注意一个坑

二次签名的时候使用 appId nonceStr package signType timeStamp 这五个key生成签名(这里无视微信官方文档 以及注意 appId 的大小写)

前端调起API支付时 按照官方文档就可以

网络请求类:

HttpRequest

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map; public class HttpRequest { /** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder"); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // conn.setRequestProperty("Pragma:", "no-cache"); // conn.setRequestProperty("Cache-Control", "no-cache"); // conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } }

XML解析工具类

WXPayUtil

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyssyd.html