Sfoglia il codice sorgente

feat : 微信h5支付调试修改

bilingfeng 2 anni fa
parent
commit
8f54dce662

+ 25 - 21
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/PayCommonUtil.java

@@ -4,8 +4,15 @@ import com.zanxiang.common.utils.MD5Util;
 import org.apache.logging.log4j.util.Strings;
 
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
 
+/**
+ * @author xufeng
+ * @date 2022/6/8 15:37
+ */
 public class PayCommonUtil {
 
     /**
@@ -16,19 +23,18 @@ public class PayCommonUtil {
      * @param API_KEY
      * @return
      */
-    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
-        StringBuffer sb = new StringBuffer();
+    public static boolean isTenPaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
+        StringBuilder sb = new StringBuilder();
         Set es = packageParams.entrySet();
-        Iterator it = es.iterator();
-        while (it.hasNext()) {
-            Map.Entry entry = (Map.Entry) it.next();
+        for (Object e : es) {
+            Map.Entry entry = (Map.Entry) e;
             String k = (String) entry.getKey();
             String v = (String) entry.getValue();
             if (!"sign".equals(k) && null != v && !"".equals(v)) {
-                sb.append(k + "=" + v + "&");
+                sb.append(k).append("=").append(v).append("&");
             }
         }
-        sb.append("key=" + API_KEY);
+        sb.append("key=").append(API_KEY);
         //算出摘要  
         String mySign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
         String tenPaySign = ((String) packageParams.get("sign")).toLowerCase();
@@ -40,23 +46,22 @@ public class PayCommonUtil {
      *
      * @param characterEncoding
      * @param packageParams
-     * @param API_KEY
+     * @param apiKey
      * @return
      */
-    public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
-        StringBuffer sb = new StringBuffer();
+    public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String apiKey) {
+        StringBuilder sb = new StringBuilder();
         Set es = packageParams.entrySet();
         for (Object e : es) {
             Map.Entry entry = (Map.Entry) e;
             String k = (String) entry.getKey();
             String v = entry.getValue() == null ? "" : (String) entry.getValue();
             if (Strings.isNotBlank(v) && !"sign".equals(k) && !"key".equals(k)) {
-                sb.append(k + "=" + v + "&");
+                sb.append(k).append("=").append(v).append("&");
             }
         }
-        sb.append("key=" + API_KEY);
-        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
-        return sign;
+        sb.append("key=").append(apiKey);
+        return MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
     }
 
     /**
@@ -66,18 +71,17 @@ public class PayCommonUtil {
      * @return
      */
     public static String getRequestXml(SortedMap<Object, Object> parameters) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         sb.append("<xml>");
         Set es = parameters.entrySet();
-        Iterator it = es.iterator();
-        while (it.hasNext()) {
-            Map.Entry entry = (Map.Entry) it.next();
+        for (Object e : es) {
+            Map.Entry entry = (Map.Entry) e;
             String k = (String) entry.getKey();
             String v = (String) entry.getValue();
             if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
-                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
+                sb.append("<").append(k).append(">").append("<![CDATA[").append(v).append("]]></").append(k).append(">");
             } else {
-                sb.append("<" + k + ">" + v + "</" + k + ">");
+                sb.append("<").append(k).append(">").append(v).append("</").append(k).append(">");
             }
         }
         sb.append("</xml>");

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

@@ -8,7 +8,8 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 
 /**
- * 相关配置参数
+ * @author xufeng
+ * @date 2022/6/8 15:37
  */
 public class WxPayUtil {
 

+ 64 - 23
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/bo/ProductPayParamBO.java

@@ -10,37 +10,78 @@ import lombok.Data;
  */
 @Data
 public class ProductPayParamBO {
-    private static final long serialVersionUID = 1L;
 
+    /**
+     * 游戏id
+     */
     private String gameId;
 
-    private String userId; //玩家id
-
-    private String productId;// 商品ID
-
-    private String subject;//订单名称
-
-    private String body;// 商品描述
-
-    private String totalFee;// 总金额(单位是分)
-
-    private String outTradeNo;// 订单号(唯一)
-
-    private String spbillCreateIp;// 发起人IP地址
-
-    private ProductPayAttachParamBO attach;// 附件数据主要用于商户携带订单的自定义数据
-
-    private Integer payDevice;// 支付方式 (1:PC,平板 2:Wap 3:App )
-
-    private Integer payWay;// 支付类型(1:支付宝 2:微信 3:银联)
+    /**
+     * 玩家id
+     */
+    private String userId;
+
+    /**
+     * 商品ID
+     */
+    private String productId;
+
+    /**
+     * 订单名称
+     */
+    private String subject;
+
+    /**
+     * 商品描述
+     */
+    private String body;
+
+    /**
+     * 总金额(单位是分)
+     */
+    private String totalFee;
+
+    /**
+     * 订单号(唯一)
+     */
+    private String outTradeNo;
+
+    /**
+     * 发起人IP地址
+     */
+    private String spbillCreateIp;
+
+    /**
+     * 附件数据主要用于商户携带订单的自定义数据
+     */
+    private ProductPayAttachParamBO attach;
+
+    /**
+     * 支付方式 (1:PC,平板 2:Wap 3:App )
+     */
+    private Integer payDevice;
+
+    /**
+     * 支付类型(1:支付宝 2:微信 3:米大师)
+     */
+    private Integer payWay;
 
 
     //================以下非传项=================
 
-    private String frontUrl;// 前台回调地址  非扫码支付使用
+    /**
+     * 前台回调地址  非扫码支付使用
+     */
+    private String frontUrl;
 
-    private Object config; //支付相关配置
+    /**
+     * 支付相关配置
+     */
+    private Object config;
 
-    private String deviceSystem; //支付类型详情(android / ios/ window)
+    /**
+     * 支付类型详情(android / ios/ window)
+     */
+    private String deviceSystem;
 
 }

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

@@ -20,7 +20,15 @@ import weixin.popular.api.SnsAPI;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
-import java.util.*;
+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
@@ -66,10 +74,12 @@ 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");
             case 2:
-            case 3:
                 return this.mobile(product, "MWEB");
+//            case 3:
+//                return this.mobile(product, "MWEB");
             case 4:
                 return this.mp(product);
             default:
@@ -117,7 +127,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         // 账号信息
         String key = config.getApiKey();
         // 判断签名是否正确
-        if (PayCommonUtil.isTenpaySign(Constants.UTF8, packageParams, key)) {
+        if (PayCommonUtil.isTenPaySign(Constants.UTF8, packageParams, key)) {
             log.info("微信支付成功回调");
             // 处理业务开始
             String resXml;
@@ -202,12 +212,12 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
      * @param product
      * @return
      */
-    public ResultMap mp(ProductPayParamBO product) {
+    private ResultMap mp(ProductPayParamBO product) {
         //redirect_uri 需要在微信支付端添加认证网址
         totalFee = WxPayUtil.subZeroAndDot(this.totalFee);
-        String redirect_uri = serverUrl + "weixinMobile/dopay?outTradeNo=" + product.getOutTradeNo() + "&totalFee=" + totalFee;
+        String redirectUri = serverUrl + "weixinMobile/dopay?outTradeNo=" + product.getOutTradeNo() + "&totalFee=" + totalFee;
         //也可以通过state传递参数 redirect_uri 后面加参数未经过验证
-        String result = SnsAPI.connectOauth2Authorize(config.getAppId(), redirect_uri, true, null);
+        String result = SnsAPI.connectOauth2Authorize(config.getAppId(), redirectUri, true, null);
         return ResultMap.ok(result);
     }
 
@@ -247,40 +257,62 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
             Map map = XMLUtil.doXMLParse(resXml);
             log.info("订单号:{} 微信响应 map:{}", product.getOutTradeNo(), map);
             String returnCode = (String) map.get("return_code");
-            if (Constants.SUCCESS.equalsIgnoreCase(returnCode)) {
-                String resultCode = (String) map.get("result_code");
-                if (Constants.SUCCESS.equalsIgnoreCase(resultCode)) {
-                    log.info("订单号:{}生成微信支付码成功", product.getOutTradeNo());
-                    String urlCode = tradeType.equals("MWEB") ? (String) map.get("mweb_url") : (String) map.get("code_url");
-                    HashMap<String, String> result = new HashMap<>();
-                    if (tradeType.equals("MWEB")) {
-                        try {
-                            String shortUrl = wxPayUtil.shortUrl(urlCode);
-                            if (!Constants.FAIL.equalsIgnoreCase(shortUrl)) {
-                                result.put("AppLink", shortUrl);
-                            }
-                        } catch (Exception e) {
-                            log.error("订单号:{} 生成微信app支付链接失败:{}", product.getOutTradeNo(), e);
-                        }
-                    }
-                    result.put("fromData", urlCode);
-                    return ResultMap.ok(product.getPayDevice(), urlCode);
-                } else {
-                    String errCodeDes = (String) map.get("err_code_des");
-                    log.error("订单号:{}生成微信支付码(系统)失败:{}", product.getOutTradeNo(), errCodeDes);
-                    return ResultMap.error(errCodeDes);
-                }
-            } else {
+            //返回失败
+            if (!Constants.SUCCESS.equalsIgnoreCase(returnCode)) {
                 String returnMsg = (String) map.get("return_msg");
                 log.error("(订单号:{}生成微信支付码(通信)失败:{}", 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);
+                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);
+            }
+            return ResultMap.ok(product.getPayDevice(), urlCode);
         } catch (Exception e) {
             log.error("订单号:{}生成微信支付码失败(系统异常))", product.getOutTradeNo(), e);
             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");
+        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;
+    }
+
     /**
      * 配置初始化
      */