Quellcode durchsuchen

feat : 微信h5支付调试修改

bilingfeng vor 2 Jahren
Ursprung
Commit
748f111129

+ 4 - 5
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/HttpUtil.java

@@ -120,11 +120,10 @@ public class HttpUtil {
         // 读取超时 --服务器响应比较慢,增大时间
         http.setReadTimeout(DEF_READ_TIMEOUT);
         http.setUseCaches(false);
-        http.setRequestProperty("Content-Type",
-                "application/x-www-form-urlencoded");
-        http.setRequestProperty(
-                "User-Agent",
-                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36");
+        http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+//        http.setRequestProperty(
+//                "User-Agent",
+//                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36");
         http.setSSLSocketFactory(ssf);
         http.setDoOutput(true);
         http.setDoInput(true);

+ 37 - 1
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/WxPayUtil.java

@@ -3,9 +3,16 @@ package com.zanxiang.sdk.common.util;
 import com.zanxiang.common.constant.Constants;
 import com.zanxiang.sdk.domain.bo.WxPayConfigBO;
 
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @author xufeng
@@ -53,7 +60,7 @@ public class WxPayUtil {
             packageParams.put("sign", sign);
             String requestXml = PayCommonUtil.getRequestXml(packageParams);
             String resXml = HttpUtil.postData(WxPayUrl.SHORT_URL, requestXml);
-            Map map = XMLUtil.doXMLParse(resXml);
+            Map map = XMLUtil.doXmlParse(resXml);
             String returnCode = (String) map.get("return_code");
             if (Constants.SUCCESS.equalsIgnoreCase(returnCode)) {
                 String resultCode = (String) map.get("return_code");
@@ -72,6 +79,35 @@ public class WxPayUtil {
         }
     }
 
+    /**
+     * 转换deepLink
+     *
+     * @param url
+     * @return
+     * @throws Exception
+     */
+    public String readUrl(String url, String serverUrl) throws Exception {
+        // 定义好匹配规则
+        String regex = "weixin://wap/pay?.[^\\x{4e00}-\\x{9fa5}-\"]+";
+        Pattern pattern = Pattern.compile(regex);
+        URL payUrl = new URL(url);
+        URLConnection con = payUrl.openConnection();
+        // 加referer防盗链,必须是申请的支付白名单域名
+        con.setRequestProperty("Referer", serverUrl);
+        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8));
+        String result = null;
+        String realLineStr;
+        while ((realLineStr = br.readLine()) != null) {
+            // 一行行查找
+            Matcher matcher = pattern.matcher(realLineStr);
+            if (matcher.find()) {
+                result = matcher.group();
+                break;
+            }
+        }
+        return result;
+    }
+
     public static String subZeroAndDot(String s) {
         if (s.indexOf(".") > 0) {
             // 去掉多余的0

+ 6 - 7
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/XMLUtil.java

@@ -32,7 +32,7 @@ public class XMLUtil {
      * @throws JDOMException
      * @throws IOException
      */
-    public static Map doXMLParse(String strXml) throws JDOMException, IOException {
+    public static Map doXmlParse(String strXml) throws JDOMException, IOException {
         strXml = filterXXE(strXml);
         strXml = strXml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
         if (StringUtils.isBlank(strXml)) {
@@ -44,9 +44,8 @@ public class XMLUtil {
         Document doc = builder.build(in);
         Element root = doc.getRootElement();
         List list = root.getChildren();
-        Iterator it = list.iterator();
-        while (it.hasNext()) {
-            Element e = (Element) it.next();
+        for (Object object : list) {
+            Element e = (Element) object;
             String k = e.getName();
             String v;
             List children = e.getChildren();
@@ -92,9 +91,9 @@ public class XMLUtil {
     /**
      * 通过DOCTYPE和ENTITY来加载本地受保护的文件、替换掉即可
      * 漏洞原理:https://my.oschina.net/u/574353/blog/1841103
-     *      * 防止 XXE漏洞 注入实体攻击
-     *      * 过滤 过滤用户提交的XML数据
-     *      * 过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。
+     * 防止 XXE漏洞 注入实体攻击
+     * 过滤 过滤用户提交的XML数据
+     * 过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。
      *    
      */
     public static String filterXXE(String xmlStr) {

+ 49 - 111
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/pay/WxPayServiceImpl.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.zanxiang.common.constant.Constants;
 import com.zanxiang.common.domain.ResultMap;
 import com.zanxiang.common.enums.ResEnum;
+import com.zanxiang.common.utils.JsonUtil;
 import com.zanxiang.common.utils.RandomStringUtil;
 import com.zanxiang.sdk.common.util.*;
 import com.zanxiang.sdk.domain.bo.ProductPayAttachParamBO;
@@ -20,15 +21,10 @@ import weixin.popular.api.SnsAPI;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
-import java.net.URL;
-import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @author xufeng
@@ -39,18 +35,34 @@ import java.util.regex.Pattern;
 @Service("WxPayService")
 public class WxPayServiceImpl extends PayService implements OrderPayService {
 
-    private WxPayConfigBO config;
+    /**
+     * 二维码支付
+     */
+    private static final String WX_PAY_NATIVE = "NATIVE";
 
-    private WxPayUtil wxPayUtil;
+    /**
+     * h5支付
+     */
+    private static final String WX_PAY_MWEB = "MWEB";
 
+    /**
+     * 服务器域名
+     */
     @Value("${server.domain}")
     private String serverUrl;
 
+    /**
+     * 微信回调接口
+     */
     @Value("${payConfig.wx.notifyUrl}")
     private String notifyUrl;
 
-    @Value("${payConfig.wx.imgFilePath}")
-    private String filePath;
+    /**
+     * 微信支付配置
+     */
+    private WxPayConfigBO config;
+
+    private WxPayUtil wxPayUtil;
 
     private String body;
 
@@ -74,13 +86,15 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         this.configInit(getPayConfig(product.getGameId(), product.getPayWay(), product.getPayDevice()));
         switch (product.getPayDevice()) {
             case 1:
-                //PC端
-                return this.mobile(product, "NATIVE");
+                //PC端二维码
+                return this.mobile(product, WX_PAY_NATIVE);
             case 2:
-                return this.mobile(product, "MWEB");
+                //手机端H5
+                return this.mobile(product, WX_PAY_MWEB);
 //            case 3:
 //                return this.mobile(product, "MWEB");
             case 4:
+                //微信小程序
                 return this.mp(product);
             default:
                 throw new RuntimeException("未知支付方式");
@@ -100,7 +114,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         InputStream inputStream = request.getInputStream();
         StringBuffer sb = new StringBuffer();
         String s;
-        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, Constants.UTF8));
+        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
         while ((s = in.readLine()) != null) {
             sb.append(s);
         }
@@ -108,21 +122,18 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         inputStream.close();
         log.info("微信支付回调 body:{}", sb);
         // 解析xml成map
-        Map<String, String> m = XMLUtil.doXMLParse(sb.toString());
+        Map m = XMLUtil.doXmlParse(sb.toString());
         // 过滤空 设置 TreeMap
         SortedMap<Object, Object> packageParams = new TreeMap<>();
-        Iterator it = m.keySet().iterator();
-        while (it.hasNext()) {
-            String parameter = (String) it.next();
-            String parameterValue = m.get(parameter);
-
+        for (Object parameter : m.keySet()) {
+            String parameterValue = (String) m.get(parameter);
             String v = "";
             if (null != parameterValue) {
                 v = parameterValue.trim();
             }
             packageParams.put(parameter, v);
         }
-        ProductPayAttachParamBO attachBO = this.decodeAttach(packageParams.get("attach"));
+        ProductPayAttachParamBO attachBO = JsonUtil.toObj(JsonUtil.toString(packageParams.get("attach")), ProductPayAttachParamBO.class);
         configInit(getPayConfig(attachBO.getGamePayWayId()));
         // 账号信息
         String key = config.getApiKey();
@@ -136,7 +147,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
                 String orderNo = (String) packageParams.get("out_trade_no");
                 log.info("微信订单号{}付款成功", orderNo);
                 if (paySuccess(attachBO.getOrderId(), String.valueOf(Float.parseFloat(packageParams.get("total_amount").toString()) / 100), packageParams.get("trade_no").toString(), attachBO.getGamePayWayId())) {
-                    log.info("支付宝异步回调成功 request:{},商户订单号为:{}", request, outTradeNo);
+                    log.info("微信异步回调成功 request:{},商户订单号为:{}", request, outTradeNo);
                     return ResEnum.SUCCESS.getMsg();
                 }
                 // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了
@@ -170,42 +181,6 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
     }
 
 
-    /**
-     * pc支付
-     *
-     * @param product
-     * @return
-     */
-    public ResultMap pc(ProductPayParamBO product) {
-        //商户支付回调URL设置指引:进入公众平台-->微信支付-->开发配置-->扫码支付-->修改 加入回调URL
-        SortedMap<Object, Object> packageParams = new TreeMap<>();
-        //封装通用参数
-        wxPayUtil.commonParams(packageParams);
-        packageParams.put("attach", JSONObject.toJSONString(this.attach));
-        //生成签名
-        String sign = PayCommonUtil.createSign(Constants.UTF8, packageParams, config.getApiKey());
-        //组装二维码信息
-        StringBuffer qrCode = new StringBuffer();
-        qrCode.append("weixin://wxpay/bizpayurl?");
-        qrCode.append("appid=" + config.getAppId());
-        qrCode.append("&mch_id=" + config.getMchId());
-        qrCode.append("&nonce_str=" + packageParams.get("nonce_str"));
-        qrCode.append("&out_trade_no=" + this.outTradeNo);
-        qrCode.append("&time_stamp=" + packageParams.get("time_stamp"));
-        qrCode.append("&sign=" + sign);
-        String imgName = this.outTradeNo + ".png";
-        File pathFile = new File(this.filePath);
-        if (!pathFile.exists()) {
-            pathFile.mkdirs();
-        }
-        String imgPath = filePath + imgName;
-        log.info("小程序支付调起,请求参数:qrCode:{}, imgPath:{}", qrCode, imgPath);
-        QrCode.createQrCodeImage(qrCode.toString(), imgPath);
-        System.out.println(imgPath);
-        return ResultMap.ok(product.getPayDevice(), qrCode.toString());
-    }
-
-
     /**
      * 小程序(需要HTTPS)
      *
@@ -227,7 +202,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
      * @param product
      * @return
      */
-    public ResultMap mobile(ProductPayParamBO product, String tradeType) {
+    private ResultMap mobile(ProductPayParamBO product, String tradeType) {
         //商户支付回调URL设置指引:进入公众平台-->微信支付-->开发配置-->扫码支付-->修改 加入回调URL
         log.info("订单号:{}生成微信支付码", product.getOutTradeNo());
         try {
@@ -251,69 +226,42 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
             packageParams.put("attach", JSONObject.toJSONString(this.attach));
             String sign = PayCommonUtil.createSign(Constants.UTF8, packageParams, key);
             packageParams.put("sign", sign);
-            log.info("订单号:{} 加密请求参数 packageParams:{}", product.getOutTradeNo(), packageParams);
             String requestXml = PayCommonUtil.getRequestXml(packageParams);
             String resXml = HttpUtil.postData(WxPayUrl.UNIFIED_ORDER_URL, requestXml);
-            Map map = XMLUtil.doXMLParse(resXml);
-            log.info("订单号:{} 微信响应 map:{}", product.getOutTradeNo(), map);
+            Map map = XMLUtil.doXmlParse(resXml);
+            if (map == null) {
+                log.error("微信支付通信异常, 订单号:{}", product.getOutTradeNo());
+                return ResultMap.error();
+            }
             String returnCode = (String) map.get("return_code");
             //返回失败
             if (!Constants.SUCCESS.equalsIgnoreCase(returnCode)) {
                 String returnMsg = (String) map.get("return_msg");
-                log.error("(订单号:{}生成微信支付码(通信)失败:{}", product.getOutTradeNo(), returnMsg);
+                log.error("微信支付通信失败, 订单号:{}, msg :{}", product.getOutTradeNo(), returnMsg);
                 return ResultMap.error(returnMsg);
             }
             //结果失败
             String resultCode = (String) map.get("result_code");
             if (!Constants.SUCCESS.equalsIgnoreCase(resultCode)) {
                 String errCodeDes = (String) map.get("err_code_des");
-                log.error("订单号:{}生成微信支付码(系统)失败:{}", product.getOutTradeNo(), errCodeDes);
+                log.error("微信支付通信失败, 订单号:{}, errCodeDes :{}", product.getOutTradeNo(), errCodeDes);
                 return ResultMap.error(errCodeDes);
             }
-            //成功
-            log.info("订单号:{}生成微信支付码成功", product.getOutTradeNo());
-            String urlCode = tradeType.equals("MWEB") ? (String) map.get("mweb_url") : (String) map.get("code_url");
-            //转成deepLink
-            if (tradeType.equals("MWEB")) {
-                urlCode = this.readUrl(urlCode);
+            if (tradeType.equals(WX_PAY_MWEB)) {
+                String urlCode = wxPayUtil.readUrl((String) map.get("mweb_url"), serverUrl);
+                return ResultMap.ok(product.getPayDevice(), urlCode);
             }
-            return ResultMap.ok(product.getPayDevice(), urlCode);
+            if (tradeType.equals(WX_PAY_NATIVE)) {
+                String urlCode = (String) map.get("code_url");
+                return ResultMap.ok(product.getPayDevice(), urlCode);
+            }
+            return ResultMap.ok(product.getPayDevice(), null);
         } catch (Exception e) {
-            log.error("订单号:{}生成微信支付码失败(系统异常))", product.getOutTradeNo(), e);
+            log.error("微信支付通信异常, 订单号:{}, e : {}", product.getOutTradeNo(), e.getMessage());
             return ResultMap.error();
         }
     }
 
-    /**
-     * 转换deepLink
-     *
-     * @param url
-     * @return
-     * @throws Exception
-     */
-    private String readUrl(String url) throws Exception {
-        // 定义好匹配规则
-        String regex = "weixin://wap/pay?.[^\\x{4e00}-\\x{9fa5}-\"]+";
-        Pattern pattern = Pattern.compile(regex);
-        URL payUrl = new URL(url);
-        URLConnection con = payUrl.openConnection();
-        // 加referer防盗链,必须是你申请的支付白名单
-//        con.setRequestProperty("Referer", "https://test.game.hzshengmel.com");
-        con.setRequestProperty("Referer", serverUrl);
-        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8));
-        String result = "";
-        String realLineStr = null;
-        while ((realLineStr = br.readLine()) != null) {
-            // 一行行查找
-            Matcher matcher = pattern.matcher(realLineStr);
-            if (matcher.find()) {
-                result = matcher.group();
-                break;
-            }
-        }
-        return result;
-    }
-
     /**
      * 配置初始化
      */
@@ -322,14 +270,4 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         this.config = JSONObject.parseObject(obj, WxPayConfigBO.class);
         this.wxPayUtil = new WxPayUtil(this.config);
     }
-
-    /**
-     * 反解析自定义参数
-     *
-     * @param obj
-     * @return
-     */
-    private ProductPayAttachParamBO decodeAttach(Object obj) {
-        return JSONObject.parseObject(obj.toString(), ProductPayAttachParamBO.class);
-    }
 }