From d61b9e9391c43e7f7f744e5ae4d2d588a3879e9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A2=A8=E5=A4=A7=E5=8F=94?= <494979559@qq.com>
Date: Tue, 10 Sep 2024 18:25:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=8E=A5=E5=8F=A3=E6=9B=B4?=
 =?UTF-8?q?=E6=8D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../common/core/domain/entity/SmUser.java     |  1 +
 .../common/pay/syb/config/SybConfig.java      |  3 +
 .../common/pay/syb/enums/SybTrxCode.java      | 26 +++++++
 .../common/pay/syb/enums/SybTrxStatus.java    | 42 +++++++++++
 .../common/pay/syb/service/SybPayClient.java  | 30 ++++++++
 .../common/pay/syb/service/SybPayService.java | 69 ++++++++++++++++++-
 .../ruoyi/common/pay/syb/util/SybUtil.java    | 18 +++++
 .../common/pay/wx/domain/RefundAble.java      |  2 +-
 .../com/ruoyi/common/utils/DateUtils.java     |  9 +++
 .../service/impl/PayBillConverterImpl.java    |  2 +-
 .../service/impl/PayBillServiceImpl.java      | 23 +++++--
 .../service/impl/RefundServiceImpl.java       | 26 +++++++
 .../impl/TransactionBillServiceImpl.java      | 14 ++--
 .../impl/TransactionBillValidatorImpl.java    |  3 +-
 .../controller/app/AppChannelController.java  |  7 --
 .../web/controller/app/AppPayController.java  | 40 +++++++++++
 .../src/main/resources/application-dev.yml    |  2 +
 17 files changed, 294 insertions(+), 23 deletions(-)
 create mode 100644 smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxCode.java
 create mode 100644 smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxStatus.java

diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java
index 5c37c60f..d0759f0e 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java
@@ -131,6 +131,7 @@ public class SmUser extends BaseEntity
     private BigDecimal serviceRate;
 
     @ApiModelProperty("是否设备管理员")
+    @JsonView(JsonViewProfile.AppMch.class)
     private Boolean deviceAdmin;
 
     @ApiModelProperty("服务费收取方式")
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/config/SybConfig.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/config/SybConfig.java
index 6ecdc0ff..a231b542 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/config/SybConfig.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/config/SybConfig.java
@@ -43,4 +43,7 @@ public class SybConfig {
     // 通联平台sm2公钥,用于请求返回或者通联通知的验签
     private String sm2TlPubKey;
 
+    // 通知地址
+    private String notifyUrl;
+
 }
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxCode.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxCode.java
new file mode 100644
index 00000000..342b04cc
--- /dev/null
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxCode.java
@@ -0,0 +1,26 @@
+package com.ruoyi.common.pay.syb.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 收银宝交易类型
+ * @author wjh
+ * 2024/9/10
+ */
+@Getter
+@AllArgsConstructor
+public enum SybTrxCode {
+
+    WX_PAY("VSP501", "微信支付"),
+    WX_REFUND("VSP503", "微信支付退款");
+
+    private final String code;
+
+    private final String msg;
+
+    public boolean equalsCode(String code) {
+        return this.getCode().equals(code);
+    }
+
+}
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxStatus.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxStatus.java
new file mode 100644
index 00000000..fca4a548
--- /dev/null
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/enums/SybTrxStatus.java
@@ -0,0 +1,42 @@
+package com.ruoyi.common.pay.syb.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+/**
+ * 交易结果
+ * @author wjh
+ * 2024/9/10
+ */
+@Getter
+@AllArgsConstructor
+public enum SybTrxStatus {
+    SUCCESS("0000", "交易成功"),
+    PROCESSING("2000", "交易处理中"),
+    NOT_EXIST("1001", "交易不存在"),
+    REPEAT("3888", "流水号重复"),
+    CHANNEL_MERCHANT_ERROR("3099", "渠道商户错误"),
+    TRANSACTION_AMOUNT_LESS_THAN_SERVICE_CHARGE("3014", "交易金额小于应收手续费"),
+    CHECK_REAL_NAME_INFO_FAILED("3031", "校验实名信息失败"),
+    TRANSACTION_NOT_PAID("3088", "交易未支付"),
+    TRANSACTION_REVERSED("3089", "撤销异常"),
+    TRANSACTION_REVOKED("3050", "交易已被撤销");
+
+    public static boolean isSuccess(String code) {
+        return SUCCESS.getCode().equals(code);
+    }
+
+    public static SybTrxStatus getByCode(String code) {
+        for (SybTrxStatus value : SybTrxStatus.values()) {
+            if (value.getCode().equals(code)) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    private final String code;
+    private final String msg;
+
+}
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java
index a9fc3b2c..52800edd 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java
@@ -121,6 +121,36 @@ public class SybPayClient {
 		return map;
 	}
 
+	/**
+	 * 关闭支付订单
+	 */
+	public Map<String,String> close(String oldtrxid,String oldreqsn) throws Exception{
+		HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/close");
+		http.init();
+		TreeMap<String,String> params = new TreeMap<String,String>();
+		if(!SybUtil.isEmpty(sybConfig.getOrgId()))
+			params.put("orgid", sybConfig.getOrgId());
+		params.put("cusid", sybConfig.getCusId());
+		params.put("appid", sybConfig.getAppId());
+		params.put("version", "11");
+		params.put("oldtrxid", oldtrxid);
+		params.put("oldreqsn", oldreqsn);
+		params.put("randomstr", SybUtil.getValidatecode(8));
+		params.put("signtype", sybConfig.getSignType());
+		String appkey = "";
+		if(sybConfig.getSignType().equals("RSA"))
+			appkey = sybConfig.getRsaCusPriKey();
+		else if(sybConfig.getSignType().equals("SM2"))
+			appkey = sybConfig.getSm2CusPriKey();
+		else
+			appkey = sybConfig.getMd5AppKey();
+		params.put("sign", SybUtil.unionSign(params,appkey,sybConfig.getSignType()));
+		byte[] bys = http.postParams(params, true);
+		String result = new String(bys,"UTF-8");
+		Map<String,String> map = handleResult(result);
+		return map;
+	}
+
 	public Map<String,String> refund(long trxamt,String reqsn,String oldtrxid,String oldreqsn) throws Exception{
 		HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/refund");
 		http.init();
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java
index 2b7c759d..298887b9 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java
@@ -2,13 +2,19 @@ package com.ruoyi.common.pay.syb.service;
 
 import com.alibaba.fastjson2.JSON;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.pay.syb.config.SybConfig;
+import com.ruoyi.common.pay.syb.util.SybUtil;
 import com.ruoyi.common.pay.wx.domain.Payable;
+import com.ruoyi.common.pay.wx.domain.RefundAble;
 import com.ruoyi.common.utils.StringUtils;
 import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
+import com.wechat.pay.java.service.payments.model.Transaction;
+import com.wechat.pay.java.service.refund.model.Refund;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.Map;
+import java.util.TreeMap;
 
 /**
  * @author wjh
@@ -20,6 +26,9 @@ public class SybPayService {
     @Autowired
     private SybPayClient sybPayClient;
 
+    @Autowired
+    private SybConfig sybConfig;
+
     /**
      * 微信小程序预下单
      */
@@ -33,7 +42,7 @@ public class SybPayService {
                     payable.payableDescription(),
                     payable.payableOpenId(),
                     "",
-                    "",
+                    sybConfig.getNotifyUrl(),
                     "",
                     "",
                     "",
@@ -54,11 +63,65 @@ public class SybPayService {
                     return JSON.parseObject(payInfo, PrepayWithRequestPaymentResponse.class);
                 }
             }
-
-            return null;
+            throw new ServiceException("支付数据为空");
         } catch(Exception e) {
             throw new ServiceException("调起支付失败:" + e.getMessage());
         }
     }
 
+    public boolean validSign(TreeMap<String, String> params) {
+        try {
+            String appkey = "";
+            if("RSA".equals(params.get("signtype"))) {
+                appkey = sybConfig.getRsaTlPubKey();
+            } else if("SM2".equals(params.get("signtype"))) {
+                appkey = sybConfig.getSm2TlPubKey();
+            } else {
+                appkey = sybConfig.getMd5AppKey();
+            }
+            boolean isSign = SybUtil.validSign(params, appkey, params.get("signtype"));// 接受到推送通知,首先验签
+            System.out.println("验签结果:"+isSign);
+            return isSign;
+        } catch (Exception e) {
+            throw new ServiceException("验签异常:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 使用商户自定义订单编号查询支付订单
+     */
+    public Map<String, String> queryOrderByOutTradeNo(String outTradeNo) {
+        try {
+            return sybPayClient.query(outTradeNo, "");
+        } catch (Exception e) {
+            throw new ServiceException("查询支付订单异常:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 微信退款
+     */
+    public Map<String, String> refundWx(RefundAble refundAble) {
+        try {
+            return sybPayClient.refund(
+                    refundAble.refundAmount().getRefund().longValue(),
+                    refundAble.refundOutRefundNo(),
+                    "",
+                    refundAble.refundOutTradeNo()
+            );
+        } catch (Exception e) {
+            throw new ServiceException("发起退款异常:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 关闭微信支付订单
+     */
+    public void closeOrderWx(String outTradeNo) {
+        try {
+            sybPayClient.close("", outTradeNo);
+        } catch (Exception e) {
+            throw new ServiceException("关闭支付订单异常:" + e.getMessage());
+        }
+    }
 }
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/util/SybUtil.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/util/SybUtil.java
index 37963ca3..8fcfa9a7 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/util/SybUtil.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/syb/util/SybUtil.java
@@ -2,6 +2,7 @@ package com.ruoyi.common.pay.syb.util;
 
 import org.apache.commons.codec.binary.Base64;
 
+import javax.servlet.http.HttpServletRequest;
 import java.security.*;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;
@@ -209,4 +210,21 @@ public class SybUtil {
 
 		return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
 	}
+
+
+	/**
+	 * 动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容由于收银宝加字段而引起的签名异常
+	 * @param request
+	 * @return
+	 */
+	public static TreeMap<String, String> getParams(HttpServletRequest request){
+		TreeMap<String, String> map = new TreeMap<String, String>();
+		Map reqMap = request.getParameterMap();
+		for(Object key:reqMap.keySet()){
+			String value = ((String[])reqMap.get(key))[0];
+			System.out.println(key+";"+value);
+			map.put(key.toString(),value);
+		}
+		return map;
+	}
 }
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/RefundAble.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/RefundAble.java
index 43b34984..21ceb3a3 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/RefundAble.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/RefundAble.java
@@ -17,7 +17,7 @@ public interface RefundAble {
     // 退款原因
     String refundReason();
 
-    // 退款金额
+    // 退款金额(分)
     AmountReq refundAmount();
 
 }
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
index 9026ed27..5e469dc5 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -307,4 +307,13 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
     public static LocalDate toLocalDate(Date date) {
         return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
     }
+
+    /**
+     * 字符串转LocalDateTime
+     * @param timeStr 字符串
+     * @param format 格式化
+     */
+    public static LocalDateTime toLocalDate(String timeStr, String format) {
+        return LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern(format));
+    }
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillConverterImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillConverterImpl.java
index 9017e9d4..0598b7ba 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillConverterImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillConverterImpl.java
@@ -149,7 +149,7 @@ public class PayBillConverterImpl implements PayBillConverter {
         po.setChannelCost(this.calcChannelCost(channel, order.getSuitPrice()));
 
         // 支付人
-        if (TransactionBillPayType.WECHAT.getType().equals(channel.getChannelId())) {
+        if (TransactionBillPayType.wxList().contains(channel.getChannelId())) {
             po.setAccount(user.getWxOpenId());
         }
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java
index 40165eaa..98373fca 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java
@@ -4,15 +4,16 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 import com.ruoyi.common.core.redis.RedisLock;
 import com.ruoyi.common.core.redis.enums.RedisLockKey;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.pay.syb.enums.SybTrxStatus;
 import com.ruoyi.common.pay.syb.service.SybPayService;
 import com.ruoyi.common.pay.wx.util.WxPayUtil;
-import com.ruoyi.common.pay.yst.service.YstPayService;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.ServiceUtil;
 import com.ruoyi.common.utils.SnowFlakeUtil;
@@ -210,9 +211,15 @@ public class PayBillServiceImpl implements PayBillService
             // 关闭订单
             for (PayBillVO bill : payingList) {
                 // 关闭支付中的订单
-                if (PayBillStatus.PAYING.getStatus().equals(bill.getStatus())
-                        && TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) {
-                    wxPayService.closeOrder(bill.getPayNo());
+                if (PayBillStatus.PAYING.getStatus().equals(bill.getStatus())) {
+                    // 微信
+                    if (TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) {
+                        wxPayService.closeOrder(bill.getPayNo());
+                    }
+                    // 通联微信
+                    else if (TransactionBillPayType.TL_WX.getType().equals(bill.getChannelId())) {
+                        sybPayService.closeOrderWx(bill.getPayNo());
+                    }
                 }
             }
 
@@ -459,6 +466,14 @@ public class PayBillServiceImpl implements PayBillService
             } else {
                 return PayResultVO.fail("暂未支付成功");
             }
+        } else if (TransactionBillPayType.TL_WX.getType().equals(bill.getChannelId())) {
+            // 通联微信支付
+            Map<String, String> result = sybPayService.queryOrderByOutTradeNo(bill.getPayNo());
+            if (SybTrxStatus.isSuccess(result.get("trxstatus"))) {
+                return PayResultVO.success(DateUtils.toLocalDate(result.get("fintime"), "yyyyMMddHHmmss"));
+            } else {
+                return PayResultVO.fail("暂未支付成功");
+            }
         }
         return PayResultVO.fail("暂不支持该支付方式");
     }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java
index 68d0f254..db32d44f 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java
@@ -1,8 +1,13 @@
 package com.ruoyi.ss.refund.service.impl;
 
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.pay.syb.enums.SybTrxStatus;
+import com.ruoyi.common.pay.syb.service.SybPayService;
 import com.ruoyi.common.pay.wx.service.WxPayService;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.ServiceUtil;
@@ -50,6 +55,13 @@ public class RefundServiceImpl implements RefundService
     @Autowired
     private PayBillService payBillService;
 
+    @Autowired
+    private SybPayService sybPayService;
+
+    @Autowired
+    private ScheduledExecutorService scheduledExecutorService;
+
+
     /**
      * 查询退款订单
      *
@@ -181,8 +193,22 @@ public class RefundServiceImpl implements RefundService
             RefundVO refundVO = this.selectRefundByRefundNo(refund.getRefundNo());
 
             // 发起退款
+            // 微信
             if (TransactionBillPayType.WECHAT.getType().equals(refund.getChannelId())) {
                 wxPayService.refund(refundVO);
+            }
+            // 通联微信
+            else if (TransactionBillPayType.TL_WX.getType().equals(refund.getChannelId())) {
+                Map<String, String> refundResult = sybPayService.refundWx(refundVO);
+                String trxStatus = refundResult.get("trxstatus");
+                // 当状态不为空,则判断是否处理退款成功
+                if (trxStatus != null) {
+                    ServiceUtil.assertion(!SybTrxStatus.isSuccess(trxStatus), "发起退款失败:" + refundResult.get("errmsg"));
+                    // 通联退款是同步通知,直接处理退款成功
+                    scheduledExecutorService.schedule(() -> {
+                        this.handleRefundSuccess(refund.getRefundNo());
+                    }, 0, TimeUnit.SECONDS);
+                }
             } else {
                 throw new ServiceException("当前支付方式不支持退款");
             }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
index 238013b8..6810a5e5 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
@@ -290,11 +290,13 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
         else if(ServiceType.PERCENT.getType().equals(serviceType)){
             // 服务费
             BigDecimal serviceCharge = serviceRate.multiply(order.getMoney()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
-            // 最低服务费
-            BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
-            ServiceUtil.assertion(order.getMoney().compareTo(minService) < 0, "当前套餐金额小于最低服务费,请联系商户处理");
-            if (serviceCharge.compareTo(minService) < 0) {
-                serviceCharge = minService;
+            // 非分时订单,处理最低服务费
+            if (!SuitFeeType.timingList().contains(order.getSuitFeeType())) {
+                BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
+                ServiceUtil.assertion(order.getMoney().compareTo(minService) < 0, "当前套餐金额小于最低服务费,请联系商户处理");
+                if (serviceCharge.compareTo(minService) < 0) {
+                    serviceCharge = minService;
+                }
             }
             order.setServiceCharge(serviceCharge);
 
@@ -929,7 +931,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
         } else {
             throw new ServiceException("计算金额出错,套餐收费类型不支持");
         }
-        // 最低0.01元
+        // 最低金额
         if (totalAmount.compareTo(BigDecimal.valueOf(0.01)) < 0) {
             totalAmount = BigDecimal.valueOf(0.01);
         }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillValidatorImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillValidatorImpl.java
index 5cc1a24d..f51c761a 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillValidatorImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillValidatorImpl.java
@@ -250,7 +250,8 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
     }
 
     @Override
-    public ValidateResult prePay(RechargePayBO bo) {
+    public ValidateResult
+    prePay(RechargePayBO bo) {
         TransactionBillVO order = bo.getOrder();
         if (order == null || order.getBillId() == null) {
             return error("订单不存在");
diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java
index 4d0d6cf3..0132475e 100644
--- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java
+++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java
@@ -30,11 +30,4 @@ public class AppChannelController extends BaseController {
         return success(channelService.selectEnabledRechargeList());
     }
 
-    @ApiOperation("获取提现渠道列表")
-    @JsonView(JsonViewProfile.App.class)
-    @GetMapping("/enabledWithdrawList")
-    public AjaxResult getWithdrawEnabledList() {
-        return error("本接口即将弃用,请使用/app/channel/withdraw/enabledList");
-    }
-
 }
diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java
index 7805552d..9e11ce78 100644
--- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java
+++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java
@@ -4,6 +4,11 @@ import com.alibaba.fastjson2.JSON;
 import com.ruoyi.common.annotation.Anonymous;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.pay.syb.enums.SybTrxCode;
+import com.ruoyi.common.pay.syb.enums.SybTrxStatus;
+import com.ruoyi.common.pay.syb.service.SybPayService;
+import com.ruoyi.common.pay.syb.util.SybUtil;
 import com.ruoyi.common.pay.wx.domain.enums.WxNotifyEventType;
 import com.ruoyi.common.pay.wx.domain.enums.WxTransferBatchStatus;
 import com.ruoyi.common.pay.wx.util.WxPayUtil;
@@ -33,6 +38,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.TreeMap;
 
 /**
  * @author 辉
@@ -53,6 +59,9 @@ public class AppPayController extends BaseController {
     @Autowired
     private PayBillService payBillService;
 
+    @Autowired
+    private SybPayService sybPayService;
+
     @Autowired
     private TransactionBillConverter transactionBillConverter;
 
@@ -152,4 +161,35 @@ public class AppPayController extends BaseController {
         return ResponseEntity.status(HttpStatus.OK).body(null);
     }
 
+    @PostMapping("/notify/tl")
+    @Anonymous
+    public String tlPayNotify(HttpServletRequest request) {
+        try {
+            request.setCharacterEncoding("UTF-8");//通知传输的编码为GBK
+            // 获取所有参数
+            TreeMap<String, String> params = SybUtil.getParams(request);
+            boolean sign = sybPayService.validSign(params);
+            if (sign) {
+                String trxCode = params.get("trxcode"); // 交易类型
+                String cusOrderId = params.get("cusorderid");   // 商户自定义订单号
+                String trxStatus = params.get("trxstatus");    // 交易结果
+
+                if (SybTrxStatus.isSuccess(trxStatus)) {
+                    // 微信支付通知
+                    if (SybTrxCode.WX_PAY.equalsCode(trxCode)) {
+                        // 新版支付订单
+                        payBillService.handleSuccess(cusOrderId, DateUtils.toLocalDate(params.get("paytime"), "yyyyMMddHHmmss"));
+                    }
+                    // 微信退款通知
+                    else if (SybTrxCode.WX_REFUND.equalsCode(trxCode)) {
+                        refundService.handleRefundSuccess(cusOrderId);
+                    }
+                }
+            }
+            return "error";
+        } catch (Exception e) {
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
 }
diff --git a/smart-switch-web/src/main/resources/application-dev.yml b/smart-switch-web/src/main/resources/application-dev.yml
index ec1ffad0..d1920906 100644
--- a/smart-switch-web/src/main/resources/application-dev.yml
+++ b/smart-switch-web/src/main/resources/application-dev.yml
@@ -128,3 +128,5 @@ syb:
   sm2CusPriKey: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgaPcLc/a1wqUa9wpDetd0PtjbPv+ldPq8vPc7UeDmlWegCgYIKoEcz1UBgi2hRANCAASo8eWV80+/3elREuKbSukOwkP+tekaq1bsk9zrreR14RAzQrDJWrq8PBso8Ctpvew51w6aVhFubw+oDFFNLE/w
   # 通联平台sm2公钥,用于请求返回或者通联通知的验签
   sm2TlPubKey: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBQicgWm0KAMqhO3bdqMUEDrKQvYg8cCXHhdGwq7CGE6oJDzJ1P/94HpuVdBf1KidmPxr7HOH+0DAnpeCcx9TcQ==
+  # 支付通知地址
+  notifyUrl: http://124.221.246.124:2290/app/pay/notify/tl