Selaa lähdekoodia

feat : 微信h5支付代码调试整理接手修改

bilingfeng 2 vuotta sitten
vanhempi
commit
612bbe209d

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

@@ -1,6 +1,7 @@
 package com.zanxiang.sdk.common.util;
 
 import com.zanxiang.common.utils.MD5Util;
+import org.apache.logging.log4j.util.Strings;
 
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -45,12 +46,11 @@ public class PayCommonUtil {
     public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
         StringBuffer sb = new StringBuffer();
         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 = entry.getValue() == null ? "" : (String) entry.getValue();
-            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
+            if (Strings.isNotBlank(v) && !"sign".equals(k) && !"key".equals(k)) {
                 sb.append(k + "=" + v + "&");
             }
         }

+ 42 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/QrCode.java

@@ -0,0 +1,42 @@
+package com.zanxiang.sdk.common.util;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import com.zanxiang.common.constant.Constants;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author : lingfeng
+ * @time : 2021-11-23
+ * @description : 二维码
+ */
+public class QrCode {
+
+    /**
+     * 生成二维码
+     *
+     * @param qrCode  : 链接
+     * @param imgPath : 图片路径
+     */
+    public static void createQrCodeImage(String qrCode, String imgPath) {
+        int height = 256;
+        String format = "png";
+        Map<EncodeHintType, Object> map = new HashMap<>(3);
+        map.put(EncodeHintType.CHARACTER_SET, Constants.UTF8);
+        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
+        map.put(EncodeHintType.MARGIN, 2);
+        try {
+            BitMatrix bitMatrix = new MultiFormatWriter().encode(qrCode, BarcodeFormat.QR_CODE, height, height, map);
+            MatrixToImageWriter.writeToPath(bitMatrix, format, new File(imgPath).toPath());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 34 - 9
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/WxPayUrl.java

@@ -1,24 +1,49 @@
 package com.zanxiang.sdk.common.util;
 
 /**
- * 微信支付接口地址
+ * @author : lingfeng
+ * @time : 2021-11-23
+ * @description : 微信支付接口地址
  */
 public class WxPayUrl {
 
-    // 微信支付统一接口(POST)
+    /**
+     * 微信支付统一接口(POST)
+     */
     public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
-    // 微信退款接口(POST)
+
+    /**
+     * 微信退款接口(POST)
+     */
     public final static String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
-    // 订单查询接口(POST)
+
+    /**
+     * 订单查询接口(POST)
+     */
     public final static String CHECK_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
-    // 关闭订单接口(POST)
+
+    /**
+     * 关闭订单接口(POST)
+     */
     public final static String CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
-    // 退款查询接口(POST)
+
+    /**
+     * 退款查询接口(POST)
+     */
     public final static String CHECK_REFUND_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
-    // 对账单接口(POST)
+
+    /**
+     * 对账单接口(POST)
+     */
     public final static String DOWNLOAD_BILL_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
-    // 短链接转换接口(POST)
+
+    /**
+     * 短链接转换接口(POST)
+     */
     public final static String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
-    // 接口调用上报接口(POST)
+
+    /**
+     * 接口调用上报接口(POST)
+     */
     public final static String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";
 }

+ 8 - 46
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/WxPayUtil.java

@@ -47,11 +47,11 @@ public class WxPayUtil {
             String key = wxPay.getApiKey();
             SortedMap<Object, Object> packageParams = new TreeMap<>();
             commonParams(packageParams);
-            packageParams.put("long_url", urlCode);// URL链接
+            packageParams.put("long_url", urlCode);
             String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
-            packageParams.put("sign", sign);// 签名
-            String requestXML = PayCommonUtil.getRequestXml(packageParams);
-            String resXml = HttpUtil.postData(WxPayUrl.SHORT_URL, requestXML);
+            packageParams.put("sign", sign);
+            String requestXml = PayCommonUtil.getRequestXml(packageParams);
+            String resXml = HttpUtil.postData(WxPayUrl.SHORT_URL, requestXml);
             Map map = XMLUtil.doXMLParse(resXml);
             String returnCode = (String) map.get("return_code");
             if (Constants.SUCCESS.equalsIgnoreCase(returnCode)) {
@@ -71,50 +71,12 @@ public class WxPayUtil {
         }
     }
 
-    //    public String doRefund(String url, String data) throws Exception {
-//        /**
-//         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
-//         */
-//        KeyStore keyStore = KeyStore.getInstance("PKCS12");
-//        File certfile = ResourceUtils.getFile("classpath:cert" +
-//                Constants.SF_FILE_SEPARATOR + wxPay.getCertPath());
-//        FileInputStream instream = new FileInputStream(certfile);
-//        try {
-//            keyStore.load(instream, wxPay.getMchId().toCharArray());
-//        } finally {
-//            instream.close();
-//        }
-//        SSLContext sslcontext = SSLContexts.custom()
-//                .loadKeyMaterial(keyStore, wxPay.getMchId().toCharArray())
-//                .build();
-//        SSLConnectionSocketFactory SSL = new SSLConnectionSocketFactory(
-//                sslcontext,
-//                new String[]{"TLSv1"},
-//                null,
-//                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
-//        CloseableHttpClient httpclient = HttpClients.custom()
-//                .setSSLSocketFactory(SSL)
-//                .build();
-//        try {
-//            HttpPost httPost = new HttpPost(url);
-//            httPost.setEntity(new StringEntity(data, "UTF-8"));
-//            CloseableHttpResponse response = httpclient.execute(httPost);
-//            try {
-//                HttpEntity entity = response.getEntity();
-//                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
-//                EntityUtils.consume(entity);
-//                return jsonStr;
-//            } finally {
-//                response.close();
-//            }
-//        } finally {
-//            httpclient.close();
-//        }
-//    }
     public static String subZeroAndDot(String s) {
         if (s.indexOf(".") > 0) {
-            s = s.replaceAll("0+?$", "");// 去掉多余的0
-            s = s.replaceAll("[.]$", "");// 如最后一位是.则去掉
+            // 去掉多余的0
+            s = s.replaceAll("0+?$", "");
+            // 如最后一位是.则去掉
+            s = s.replaceAll("[.]$", "");
         }
         return s;
     }

+ 0 - 45
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/ZxingUtil.java

@@ -1,45 +0,0 @@
-package com.zanxiang.sdk.common.util;
-
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.EncodeHintType;
-import com.google.zxing.MultiFormatWriter;
-import com.google.zxing.WriterException;
-import com.google.zxing.client.j2se.MatrixToImageWriter;
-import com.google.zxing.common.BitMatrix;
-import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
-import com.zanxiang.common.constant.Constants;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * 二维码
- */
-public class ZxingUtil {
-
-    static final String FORMAT = "png";
-
-    static final int height = 256;
-
-    /**
-     * 生成二维码
-     *
-     * @param qrCode
-     * @param imgPath
-     */
-    public static void createQRCodeImage(String qrCode, String imgPath) {
-        HashMap hashMap = new HashMap();
-        hashMap.put(EncodeHintType.CHARACTER_SET, Constants.UTF8);
-        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
-        hashMap.put(EncodeHintType.MARGIN, 2);
-        try {
-            BitMatrix bitMatrix = new MultiFormatWriter().encode(qrCode, BarcodeFormat.QR_CODE, height, height, hashMap);
-            MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, new File(imgPath).toPath());
-        } catch (WriterException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-}

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

@@ -12,8 +12,6 @@ import com.zanxiang.sdk.domain.bo.WxPayConfigBO;
 import com.zanxiang.sdk.service.OrderPayService;
 import lombok.extern.slf4j.Slf4j;
 import org.jdom.JDOMException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
@@ -32,7 +30,6 @@ import java.util.*;
 @Slf4j
 @Service("WxPayService")
 public class WxPayServiceImpl extends PayService implements OrderPayService {
-    private static final Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);
 
     private WxPayConfigBO config;
 
@@ -44,12 +41,14 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
     @Value("${payConfig.wx.notifyUrl}")
     private String notifyUrl;
 
-    private String filePath = "/tmp/wxpay/";
+    @Value("${payConfig.wx.imgFilePath}")
+    private String filePath;
 
     private String body;
+
     private String totalFee;
-    private String outTradeNo;
 
+    private String outTradeNo;
 
     /**
      * 支付调起
@@ -59,15 +58,12 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
      */
     @Override
     public ResultMap create(ProductPayParamBO product) {
-        System.out.println("WxpayService payCreate");
-
         this.body = product.getSubject();
         this.totalFee = String.valueOf(Float.parseFloat(product.getTotalFee()) * 100);
         this.outTradeNo = product.getOutTradeNo() + RandomStringUtil.randomNumStr(5);
         this.attach = product.getAttach();
         //初始化配置
         this.configInit(getPayConfig(product.getGameId(), product.getPayWay(), product.getPayDevice()));
-
         switch (product.getPayDevice()) {
             case 1:
                 return this.mobile(product, "NATIVE");
@@ -100,7 +96,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         }
         in.close();
         inputStream.close();
-        logger.info("微信支付回调 body:{}", sb);
+        log.info("微信支付回调 body:{}", sb);
         // 解析xml成map
         Map<String, String> m = XMLUtil.doXMLParse(sb.toString());
         // 过滤空 设置 TreeMap
@@ -119,37 +115,33 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         ProductPayAttachParamBO attachBO = this.decodeAttach(packageParams.get("attach"));
         configInit(getPayConfig(attachBO.getGamePayWayId()));
         // 账号信息
-        String key = config.getApiKey(); // key
+        String key = config.getApiKey();
         // 判断签名是否正确
         if (PayCommonUtil.isTenpaySign(Constants.UTF8, packageParams, key)) {
-            logger.info("微信支付成功回调");
-            // ------------------------------
+            log.info("微信支付成功回调");
             // 处理业务开始
-            // ------------------------------
             String resXml;
             if (Constants.SUCCESS.equalsIgnoreCase(packageParams.get("result_code").toString())) {
                 // 这里是支付成功
                 String orderNo = (String) packageParams.get("out_trade_no");
-                logger.info("微信订单号{}付款成功", orderNo);
+                log.info("微信订单号{}付款成功", orderNo);
                 if (paySuccess(attachBO.getOrderId(), String.valueOf(Float.parseFloat(packageParams.get("total_amount").toString()) / 100), packageParams.get("trade_no").toString(), attachBO.getGamePayWayId())) {
-                    logger.info("支付宝异步回调成功 request:{},商户订单号为:{}", request, outTradeNo);
+                    log.info("支付宝异步回调成功 request:{},商户订单号为:{}", request, outTradeNo);
                     return ResEnum.SUCCESS.getMsg();
                 }
-                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
+                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了
                 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
             } else {
-                logger.info("支付失败,错误信息:{}", packageParams.get("err_code"));
+                log.info("支付失败,错误信息:{}", packageParams.get("err_code"));
                 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();
         } else {
-            logger.info("通知签名验证失败");
+            log.info("通知签名验证失败");
         }
         return null;
     }
@@ -163,7 +155,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
 
     @Override
     public ResultMap synNotify(HttpServletRequest request) {
-        logger.info("微信支付无同步回调 request:{}", request);
+        log.info("微信支付无同步回调 request:{}", request);
         return null;
     }
 
@@ -179,7 +171,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         SortedMap<Object, Object> packageParams = new TreeMap<>();
         //封装通用参数
         wxPayUtil.commonParams(packageParams);
-        packageParams.put("attach", this.attach);
+        packageParams.put("attach", JSONObject.toJSONString(this.attach));
         //生成签名
         String sign = PayCommonUtil.createSign(Constants.UTF8, packageParams, config.getApiKey());
         //组装二维码信息
@@ -188,14 +180,17 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
         qrCode.append("appid=" + config.getAppId());
         qrCode.append("&mch_id=" + config.getMchId());
         qrCode.append("&nonce_str=" + packageParams.get("nonce_str"));
-//        qrCode.append("&attach=" + this.attach);
         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;
-        logger.info("小程序支付调起,请求参数:qrCode:{}, imgPath:{}", qrCode, imgPath);
-        ZxingUtil.createQRCodeImage(qrCode.toString(), imgPath);
+        log.info("小程序支付调起,请求参数:qrCode:{}, imgPath:{}", qrCode, imgPath);
+        QrCode.createQrCodeImage(qrCode.toString(), imgPath);
         System.out.println(imgPath);
         return ResultMap.ok(product.getPayDevice(), qrCode.toString());
     }
@@ -209,7 +204,7 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
      */
     public ResultMap mp(ProductPayParamBO product) {
         //redirect_uri 需要在微信支付端添加认证网址
-        totalFee = wxPayUtil.subZeroAndDot(this.totalFee);
+        totalFee = WxPayUtil.subZeroAndDot(this.totalFee);
         String redirect_uri = serverUrl + "weixinMobile/dopay?outTradeNo=" + product.getOutTradeNo() + "&totalFee=" + totalFee;
         //也可以通过state传递参数 redirect_uri 后面加参数未经过验证
         String result = SnsAPI.connectOauth2Authorize(config.getAppId(), redirect_uri, true, null);
@@ -222,75 +217,66 @@ public class WxPayServiceImpl extends PayService implements OrderPayService {
      * @param product
      * @return
      */
-    public ResultMap mobile(ProductPayParamBO product, String trade_type) {
-        logger.info("订单号:{}生成微信支付码", product.getOutTradeNo());
+    public ResultMap mobile(ProductPayParamBO product, String tradeType) {
+        //商户支付回调URL设置指引:进入公众平台-->微信支付-->开发配置-->扫码支付-->修改 加入回调URL
+        log.info("订单号:{}生成微信支付码", product.getOutTradeNo());
         try {
             // 账号信息
             String key = config.getApiKey();
-//            String trade_type = "NATIVE";// 交易类型 原生扫码支付
-//            String trade_type = "MWEB";// 交易类型 原生扫码支付
             SortedMap<Object, Object> packageParams = new TreeMap<>();
             wxPayUtil.commonParams(packageParams);
-            packageParams.put("body", this.body);// 商品描述
-            packageParams.put("out_trade_no", this.outTradeNo);// 商户订单号
-            totalFee = wxPayUtil.subZeroAndDot(this.totalFee);
-            packageParams.put("total_fee", totalFee);// 总金额
-            packageParams.put("spbill_create_ip", product.getSpbillCreateIp());// 发起人IP地址
-            packageParams.put("notify_url", notifyUrl);// 回调地址 notifyUrl
-            packageParams.put("trade_type", trade_type);// 交易类型
+            // 商品描述
+            packageParams.put("body", this.body);
+            // 商户订单号
+            packageParams.put("out_trade_no", this.outTradeNo);
+            totalFee = WxPayUtil.subZeroAndDot(this.totalFee);
+            // 总金额
+            packageParams.put("total_fee", totalFee);
+            // 发起人IP地址
+            packageParams.put("spbill_create_ip", product.getSpbillCreateIp());
+            // 回调地址 notifyUrl
+            packageParams.put("notify_url", notifyUrl);
+            // 交易类型
+            packageParams.put("trade_type", tradeType);
             packageParams.put("attach", JSONObject.toJSONString(this.attach));
-
-//            if (trade_type.equals("MWEB")) {
-//                //H5支付专用
-//                JSONObject value = new JSONObject();
-//                value.put("type", "WAP");
-//                value.put("wap_url", "https://localhost");////WAP网站URL地址
-//                value.put("wap_name", "111");//WAP 网站名
-//                JSONObject scene_info = new JSONObject();
-//                scene_info.put("h5_info", value);
-//                packageParams.put("scene_info", scene_info.toString());
-//            }
             String sign = PayCommonUtil.createSign(Constants.UTF8, packageParams, key);
-            packageParams.put("sign", sign);// 签名
-            logger.info("订单号:{} 加密请求参数 packageParams:{}", product.getOutTradeNo(), packageParams);
-            String requestXML = PayCommonUtil.getRequestXml(packageParams);
-            String resXml = HttpUtil.postData(WxPayUrl.UNIFIED_ORDER_URL, requestXML);
+            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);
-            logger.info("订单号:{} 微信响应 map:{}", product.getOutTradeNo(), map);
+            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)) {
-                    logger.info("订单号:{}生成微信支付码成功", product.getOutTradeNo());
-                    String urlCode = trade_type.equals("MWEB") ? (String) map.get("mweb_url") : (String) map.get("code_url");
-                    String imgName = this.outTradeNo + ".png";
-                    String imgPath = filePath + imgName;
+                    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 (trade_type.equals("MWEB")) {
+                    if (tradeType.equals("MWEB")) {
                         try {
                             String shortUrl = wxPayUtil.shortUrl(urlCode);
                             if (!Constants.FAIL.equalsIgnoreCase(shortUrl)) {
                                 result.put("AppLink", shortUrl);
                             }
                         } catch (Exception e) {
-                            logger.error("订单号:{} 生成微信app支付链接失败:{}", product.getOutTradeNo(), e);
+                            log.error("订单号:{} 生成微信app支付链接失败:{}", product.getOutTradeNo(), e);
                         }
                     }
                     result.put("fromData", urlCode);
-//                    return ResultMap.ok(product.getPayDevice(), result);
                     return ResultMap.ok(product.getPayDevice(), urlCode);
                 } else {
                     String errCodeDes = (String) map.get("err_code_des");
-                    logger.error("订单号:{}生成微信支付码(系统)失败:{}", product.getOutTradeNo(), errCodeDes);
+                    log.error("订单号:{}生成微信支付码(系统)失败:{}", product.getOutTradeNo(), errCodeDes);
                     return ResultMap.error(errCodeDes);
                 }
             } else {
                 String returnMsg = (String) map.get("return_msg");
-                logger.error("(订单号:{}生成微信支付码(通信)失败:{}", product.getOutTradeNo(), returnMsg);
+                log.error("(订单号:{}生成微信支付码(通信)失败:{}", product.getOutTradeNo(), returnMsg);
                 return ResultMap.error(returnMsg);
             }
         } catch (Exception e) {
-            logger.error("订单号:{}生成微信支付码失败(系统异常))", product.getOutTradeNo(), e);
+            log.error("订单号:{}生成微信支付码失败(系统异常))", product.getOutTradeNo(), e);
             return ResultMap.error();
         }
     }