Răsfoiți Sursa

refactor(pay): 更新微信支付配置并优化订单处理逻辑

- 更新微信支付配置,使用服务商模式
- 修复订单状态更新逻辑
- 增加比赛订单的赛程和资质信息
- 优化订单查询和支付流程
wzq 2 săptămâni în urmă
părinte
comite
ce1b6091e3

+ 3 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/dto/AppOrderInfoDTO.java

@@ -94,6 +94,9 @@ public class AppOrderInfoDTO implements Serializable {
     @Schema(description = "退款类型;0可退/到期自动退 1限时退 2不可退")
     private Integer refundType;
 
+    @Schema(description = "体育馆包场提前退款时间;单位:分钟")
+    private Integer earlyRefundTime;
+
     @Schema(description = "纬度")
     private BigDecimal latitude;
 

+ 2 - 2
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/WeChatPayService.java

@@ -60,7 +60,7 @@ public class WeChatPayService {
         StringBuilder sb = new StringBuilder();
         //返回给小程序拉起微信支付的参数
         Map<String, String> result = new HashMap<>();
-        result.put("appId", WechatConstants.WECHAT_MP_APPID); //小程序appid
+        result.put("appId", WechatConstants.WECHAT_SP_APPID); //小程序appid
         sb.append(result.get("appId")).append("\n");
         result.put("timeStamp", (new Date().getTime() / 1000) + ""); //时间戳
         sb.append(result.get("timeStamp")).append("\n");
@@ -200,7 +200,7 @@ public class WeChatPayService {
      * @return null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
      */
     public String orderQueryByOutTradeNo(String out_trade_no) {
-        JSONObject res = wechatPayV3Utils.sendGet(String.format(WechatUrlConstants.PAY_V3_QUERY_OUT, out_trade_no, WechatConstants.WECHAT_MCH_ID));
+        JSONObject res = wechatPayV3Utils.sendGet(String.format(WechatUrlConstants.PAY_V3_QUERY_OUT, out_trade_no, WechatConstants.WECHAT_SP_APPID));
         return res == null ? null : res.getString("trade_state");
     }
 

+ 3 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/AppIsinServiceImpl.java

@@ -23,6 +23,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 
 @Service
 @Log4j2
@@ -75,7 +76,8 @@ public class AppIsinServiceImpl extends ServiceImpl<AppIsinMapper, AppIsin> impl
         }
         String orderId = appOrderProInfo.getOrderId();
         AppOrder appOrder = appOrderMapper.selectById(orderId);
-        if (ObjectUtil.isNotEmpty(appOrder)){
+        List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId).gt(AppOrderProInfo::getOrderStatus, 1));
+        if (ObjectUtil.isEmpty(proInfoList)){
             appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_1);
             appOrderMapper.updateById(appOrder);
         }

+ 17 - 12
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -753,7 +753,6 @@ public class OrderServiceImpl implements IOrderService {
 
                     //订单总价(商品的售价总和)
                     BigDecimal sumPrice = BigDecimal.ZERO;
-                    ;
 
                     for (int i = 1; i <= createOrderForm.getAmount(); i++) {
 
@@ -1121,10 +1120,7 @@ public class OrderServiceImpl implements IOrderService {
 
         //构建支付表单返回给前端支撑JsApi支付调用
         UserPayForm payForm = new UserPayForm();
-        payForm
-                .setOrderId(appOrder.getId())
-                .setOrderCode(orderCode)
-        ;
+        payForm.setOrderId(appOrder.getId()).setOrderCode(orderCode);
 
         //判断是否试听课(试听课不走订单)
         if (ObjectUtil.isNotEmpty(appOrder.getOrderOrFree()) && appOrder.getOrderOrFree() == 1) {
@@ -1138,26 +1134,31 @@ public class OrderServiceImpl implements IOrderService {
 
             //构建微信支付参数
             JSONObject params = new JSONObject();
-            params.put("appid", WechatConstants.WECHAT_MP_APPID); //小程序appid
-//        params.put("sub_appid", WechatConstants.WECHAT_MP_APPID); //小程序appid
-            params.put("mchid", WechatConstants.WECHAT_MCH_ID); //商户号
+            params.put("sp_appid", WechatConstants.WECHAT_SP_APPID); //服务商appid
+            params.put("sp_mchid", WechatConstants.WECHAT_SP_MCH_ID);//服务商商户号
+            params.put("sub_appid", WechatConstants.WECHAT_SUB_APPID); //小程序appid
+            params.put("sub_mchid", WechatConstants.WECHAT_SUB_MCH_ID); //特约商户商户号
+
             params.put("description", "全龄运动"); //商品描述
             params.put("out_trade_no", appOrder.getOrderCode()); //商户订单号
             params.put("time_expire", sdf.format(calendar.getTime())); //交易结束时间 选填 时间到了之后将不能再支付 遵循rfc3339标准格式
             params.put("attach", appOrder.getOrderCode()); //附加数据 选填
             // 在查询API和支付通知中原样返回 可作为自定义参数使用
             params.put("notify_url", WechatUrlConstants.PAY_V3_NOTIFY); //支付结果异步通知接口
-            params.put("trade_type", WechatConstants.WECHAT_MP_TRADE_TYPE);//JSAPI
+            params.put("trade_type", WechatConstants.WECHAT_TRADE_TYPE);//JSAPI
             //分账必传参数
             JSONObject settleInfo = new JSONObject();
             settleInfo.put("profit_sharing", Boolean.TRUE);
             params.put("settle_info", settleInfo);
+            //电子发票入口
+            params.put("support_fapiao ", Boolean.TRUE);
 
             //订单金额信息
             JSONObject amount_json = new JSONObject();
             //支付金额 单位:分
+            //amount_json.put("total", Integer.parseInt(amount_fee(appOrder.getPrice())));
             amount_json.put("total", Integer.parseInt(amount_fee(new BigDecimal("0.01"))));//测试0.01元
-//        amount_json.put("total", Integer.parseInt(amount_fee(appOrder.getPrice())));
+            amount_json.put("currency", "CNY");//固定传:CNY,代表人民币
             params.put("amount", amount_json);
 
             //支付者信息
@@ -1167,8 +1168,8 @@ public class OrderServiceImpl implements IOrderService {
             params.put("payer", payer);
 
             //拉起支付-返回JSAPI参数
-//        Map<String, String> result = weChatPayService.wechatPay(params);
-//        payForm.setParams(result);
+//            Map<String, String> result = weChatPayService.wechatPay(params);
+//            payForm.setParams(result);
 
             //发布任务到redission延迟队列
             String task = CommonConstant.ORDER_TIME_OUT_TASK_PREFIX + appOrder.getId();
@@ -1374,6 +1375,8 @@ public class OrderServiceImpl implements IOrderService {
                 appOrderInfoDTO.setSiteName(site.getName());
                 appOrderInfoDTO.setRunStatus(site.getRunStatus());
                 //退改规则、温馨提示
+                appOrderInfoDTO.setRefundType(appSitePlace.getRefundType());
+                appOrderInfoDTO.setEarlyRefundTime(appSitePlace.getEarlyRefundTime());
                 appOrderInfoDTO.setReminder(appSitePlace.getReminder());
                 appOrderInfoDTO.setAdvanceTime(appSitePlace.getAdvanceTime());
 
@@ -1427,6 +1430,8 @@ public class OrderServiceImpl implements IOrderService {
             appOrderInfoDTO.setReminder(appGame.getReminder());
             //开始时间
             appOrderInfoDTO.setStartTime(appGame.getStartTime());
+            //结束时间
+            appOrderInfoDTO.setEndTime(appGame.getEndTime());
             //赛程安排
             List<AppGameScheduleVO> appGameScheduleVOList = appGameScheduleMapper.getListVo(appGame.getId());
             appOrderInfoDTO.setAppGameScheduleVOList(appGameScheduleVOList);

+ 34 - 31
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatConstants.java

@@ -8,7 +8,13 @@ package org.jeecg.modules.pay.config;
 public class WechatConstants {
 
     //微信支付服务商商户号
-    public static final String WECHAT_MCH_ID = "1726394481";
+    public static final String WECHAT_SP_MCH_ID = "1726394481";
+
+    public static final String WECHAT_SP_APPID = "wx6260718c6fd46efb";
+
+    public static final String WECHAT_SUB_MCH_ID = "1726610149";
+
+    public static final String WECHAT_SUB_APPID = "wx6260718c6fd46efb";
 
     //微信商户平台v2密钥
     public static final String WECHAT_MCH_SECRET_V2 = "dkrxaNfksjhDFxg1pGVuraIBahNwp1zX";
@@ -21,39 +27,36 @@ public class WechatConstants {
 
     //微信商户平台证书私钥 即证书中的apiclient_key.pem文件中的内容 可以直接写在这里 也可以用流读取文件
     public static final String WECHAT_MCH_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
-            "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvPhewCxy8aL/O\n" +
-            "RWB7TTdZAsqmHSsuKFEtLOYng6VfEpCJ7Y/GyV2EWzmko//2GHsYVcCCR8Kw+NCf\n" +
-            "cNJsPL4gGGUPXRePebfjPyBgc0TC7rFE0XMh62HXkhosTcRmVrQwzSVWx+T05nwQ\n" +
-            "gVY7V84yAlhXTe6qgAflkzphjnr43nz1Qlqa6leMZa5gzhriqEQDwux0XJVIFm4R\n" +
-            "qZlpSk8tu9k5y+1wKJNytEEYw/q40fwryqT08JKZ78bBTprTp29M97ntvRtrqyeY\n" +
-            "ENLrII8hibaRhhGcGNHsnukLrNK4a78zTF3GRA0YWQkXqWPlJvlV1op4gPdABSGb\n" +
-            "bitJb1XLAgMBAAECggEAZOw+mh0cNImjBPlBgmFK4dFQwfAEgTWo4np8Jf+UCrfX\n" +
-            "VAfjiJlJaUNcZCwq6iDZK3+fOah4QJFbHKfOF5W37SX/daSoP/HabF5bmBBqZlUu\n" +
-            "9DInuz4jABJdTmyPEl0WsxBCU8MVYdEnXB4QemasEnL1S3pPXBQV+CodMjfrLE2J\n" +
-            "kWPvRHPoJPrsI43/y5cYRnN1fGGMLe7yy8JpssWqSXNybdt7EiVcawFC5KzYVwU7\n" +
-            "CfTtAlLr0t66IHyMjobjPAz8YvTPS/3BOCd10tFJRHIoft0rRF3glNn1lrRShMQ+\n" +
-            "VERvF62lWRhy8S+dDBc2XJMKYbichis98aRHoie9UQKBgQDgFnIlMvjO41aVP/iE\n" +
-            "UNcq46Nym/V5SurXcERP14CU68TLyrQkxcSRi2KMDHBYE/eXoRztVg2sKSh6XKHq\n" +
-            "5by65Ipr9iYt10LWqnJHta26NzreVkPwBxiOGkHxPJsucOkE8iZehMy1rth77CFo\n" +
-            "MMO7Ow9rXuLipHxVbTucmHHg2QKBgQDIMubppbLs4e58bkWKkSVjSm9x0NAMNYbn\n" +
-            "6p7ULgZ+VqCDO+y6SDAFWMMin5MNuTzx94HqK6e/QhpYktVIDvBXv+psHeBsf80e\n" +
-            "kTGEwax1Am5kNoa5UIPWHPgnTcASPzQU0hOIN+QIxmuBIhl1EdvGcEjm+YdNb0Pi\n" +
-            "ajyPXd9FQwKBgHsz3A4XuDQHSdNFGJ2m1KYAAh1BIfVN+0/3qZc8JLW76rcg+2o8\n" +
-            "UZazy7q0HBBQ6g+zxPO4HExLVLXxuBQtu1YF0RUKgHMzpsvfanWCrcF0HCmhxDhz\n" +
-            "rkxyo06+w5MFARh3CiFtYh+BwgRgDv350aNfFVszEAsL5FATfnLaXcIBAoGBALFX\n" +
-            "3hPl091husiBSpsYPr15J8X0Cwh1tj7lKLOe3eO2y1PVlrvhzKA/5ARcxYCnsiRK\n" +
-            "c8xDxcJ4RSxnTgYaLbAd8wS5Zp/WipbkWbBXfHTepXmij6/DcjYOzYjLqDTBxloX\n" +
-            "SnQlxpw7YOowkcqR+lUMDJiHPONMiB8equz5ZBpPAoGAYzCkfH4OU3tXCnnYd6mR\n" +
-            "mgcdPpCGSWSYtt+dA8xtaQqFSaTIWFigEVXZn4aWKDZtOTOsm+8qMEWjuo8hbT+p\n" +
-            "+EJOTwyIPgFmaFcegLMTjo0atYP0ma01a4p45RCl5ZFWuPAD/O/4PwHlGtaekgcM\n" +
-            "bJpFz2T7LShklvgAcQk9wbA=\n" +
+            "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDozU6RJZN43U1m\n" +
+            "IYSNg20ukw4dGhmZgs8q082VLl0pY43IRlndQMLcyDh7ZsAwHt1R0YaqM9RvRuBH\n" +
+            "tQcwKHgxiNzXxADx/XoGMAUJz8TiAcv/xbGK8C74Cjq5YUJIlE0f2UH2vQMvihi1\n" +
+            "fPwSsxXJGLgu3/UajXe/zc+YrmhWnpAHU46mVJ/BLEwzBVmfcgGXAPJ/sh57zcSo\n" +
+            "ayWLYLj7nUZ8KI22DEYHDjeZD0i8wcfCVpwfsnqSO3bd2HgXSrDA5UiObXPPypM3\n" +
+            "5Qknf06sXCYa0G2Ui4YlGsC2DTBu0d7p8b/hOe7vyVzXw72uJDQ4GGd8wDiXxnGk\n" +
+            "vnEKTka3AgMBAAECggEBAIeWm/3Znsy0R9IGD4fEViDcMUot218XWsWc2o3alRP4\n" +
+            "Eanln41HnLauPodQzvq33zs6B262BTJSW2ooO2mHCIoBJm7cj5hhg2J7MVQHmKnx\n" +
+            "VflAESnUveZlPtKdnNdc2JaGGO82ItbbXYzGoKHbgALBzPQwKDcw0d/6ZMCOQ+K+\n" +
+            "FrwLi+93HXlW6jGrPAgJ09kcim6efZOHvxFdZq8zMBFoZeiGnGj6G0peHI5PGb8V\n" +
+            "YKjBXiuxHs96w079R3eID1ViiNnGonm6M9AWT2mxMYMt/VPTr0TZUUet6DmKRs+0\n" +
+            "T3XuqoIunpju5RwWDN9CRdIysc5Ylo9U5rnLjBv6ygECgYEA+ipaz9mvqGo9+EQ2\n" +
+            "30VVGpY1W8r4oOZu8pSnmm9FXZFLVznnq0CB22F7fp1WLr3Yr0XoL2NOHZFVtzT8\n" +
+            "5ww9//o/OUgY3uVC9UoosUtSPowAZeldRc2JaFABusQw34/E96BVeuqTZgFxyvo2\n" +
+            "sAmtBfDXHCOjEmwZlaumKNxw3YECgYEA7jtIBTAE70nPTh7s3Kb81L2k0BT2JVki\n" +
+            "VZdBRPqj/mMxu6MEJ5UjzNhZEH3FXHxxC4Oe8v/r1opxs6ES5RnqQ+agtL5mUBn/\n" +
+            "B0327/96DKZWaKFCaoieCUamY/3jqguoIdK80kjGX6xuQISw5tCCJVrnEuxW+CmI\n" +
+            "XDrcOsTGsDcCgYBck+IJe1i7LZ4DS1M3KxREg4P5lVKPUNeMJCEmULlN2CAWhpJK\n" +
+            "WNP1mMy33YfwQkd3DZrQNqLI5GjhJNXWtzwWh8hv7VNu4U73MVt/yQ0Foo/fJw5i\n" +
+            "b57DIKCTOlmP0kelEAuyMi8cF7rBz/j/CoWiZi9k9Xc6sRCCyAP0qSeHgQKBgBpl\n" +
+            "2z8n6QQS67O+XYS9xDpWoVKlX/kXfWR6lDLuiwl/OF2QXL9+GS9zsbrQFPSAnY4n\n" +
+            "EY/fp+RoBt1etddJHdpUTe55QqERoF7Q1tIVPxLzw5NoexGO/eQNPhbKZVXMYN8O\n" +
+            "mPm8Mq8bTkQ779ZDuIgnIH/KTIDHKWL+6rRgZZvVAoGALZn4IpUhcRe7v/+pnYSQ\n" +
+            "6AhmUmTM3OdAA+XJDMuZzDM+5DNmuhZx4Y9sw/Xg1+kejR0W48aFNZ4xhSz89XC6\n" +
+            "rusYJfTda1iqqlaH453yJti98u2EkESJMdY2YlT7H75VjD/A1o1Fn3qnGStn9CKt\n" +
+            "DOukDtlOzybCJFsjG5uBwcg=\n" +
             "-----END PRIVATE KEY-----\n";
 
     //微信小程序支付类型
-    public static final String WECHAT_MP_TRADE_TYPE = "JSAPI";
-
-    //微信小程序appid
-    public static final String WECHAT_MP_APPID = "wx6260718c6fd46efb";
+    public static final String WECHAT_TRADE_TYPE = "JSAPI";
 
     //微信小程序密钥
     public static final String WECHAT_MP_SECRET = "";

+ 0 - 2
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatUrlConstants.java

@@ -7,8 +7,6 @@ package org.jeecg.modules.pay.config;
  */
 public class WechatUrlConstants {
 
-
-
     //小程序code获取openid
     public final static String CODE_2_SESSION = "https://api.weixin.qq.com/sns/jscode2session";
 

+ 4 - 4
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/util/WechatPayV3Utils.java

@@ -69,13 +69,13 @@ public class WechatPayV3Utils {
         // 获取证书管理器实例
         CertificatesManager certificatesManager = CertificatesManager.getInstance();
         // 向证书管理器增加需要自动更新平台证书的商户信息
-        certificatesManager.putMerchant(WechatConstants.WECHAT_MCH_ID,
-                new WechatPay2Credentials(WechatConstants.WECHAT_MCH_ID, new PrivateKeySigner(WechatConstants.WECHAT_MCH_SERIAL_NUM, merchantPrivateKey)),
+        certificatesManager.putMerchant(WechatConstants.WECHAT_SP_MCH_ID,
+                new WechatPay2Credentials(WechatConstants.WECHAT_SP_MCH_ID, new PrivateKeySigner(WechatConstants.WECHAT_MCH_SERIAL_NUM, merchantPrivateKey)),
                 WechatConstants.WECHAT_MCH_SECRET_V3.getBytes(StandardCharsets.UTF_8));
         // ... 若有多个商户号,可继续调用putMerchant添加商户信息
 
         // 从证书管理器中获取verifier
-        verifier = certificatesManager.getVerifier(WechatConstants.WECHAT_MCH_ID);
+        verifier = certificatesManager.getVerifier(WechatConstants.WECHAT_SP_MCH_ID);
     }
 
     /**
@@ -88,7 +88,7 @@ public class WechatPayV3Utils {
             setVerifier();
         }
         WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
-                .withMerchant(WechatConstants.WECHAT_MCH_ID, WechatConstants.WECHAT_MCH_SERIAL_NUM, merchantPrivateKey)
+                .withMerchant(WechatConstants.WECHAT_SP_MCH_ID, WechatConstants.WECHAT_MCH_SERIAL_NUM, merchantPrivateKey)
                 .withValidator(new WechatPay2Validator(verifier));
         // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
 

+ 5 - 4
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppOrderServiceImpl.java

@@ -195,11 +195,12 @@ public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> i
             });
             appOrderInfoVO.setIsinList(appIsinVOList);
         }
-        //只有赛事有赛程
-        if (appOrder.getType() == 2) {
-            String gameId = appOrder.getProductIds();
-            List<AppGameScheduleVO> gameScheduleVOList = appGameScheduleMapper.getListVo(gameId);
+        //只有赛事有赛程和团队信息
+        if (appOrder.getType() == 1) {
+            AppGame appGame = appGameMapper.findByPriceRules(appOrder.getProductIds());
+            List<AppGameScheduleVO> gameScheduleVOList = appGameScheduleMapper.getListVo(appGame.getId());
             appOrderInfoVO.setGameScheduleVOList(gameScheduleVOList);
+            appOrderInfoVO.setGameCertification(appOrder.getGameCertification());
         }
         //无固定场团购优惠
         if (appOrder.getOrderType() == 2) {

+ 3 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/vo/AppOrderInfoVO.java

@@ -81,6 +81,9 @@ public class AppOrderInfoVO implements Serializable {
     @Schema(description = "核销记录")
     private List<VerificationRecordDTO> verificationRecordDTOList;
 
+    @Schema(description = "参赛资质")
+    private String gameCertification;
+
     @Schema(description = "赛程安排")
     private List<AppGameScheduleVO> gameScheduleVOList;
 }