Browse Source

微信支付切换为RHT支付

codingliang 1 year ago
parent
commit
03e63aa06c
28 changed files with 1017 additions and 91 deletions
  1. 17 0
      db/update_241107.sql
  2. 8 5
      pom.xml
  3. 42 0
      src/main/java/com/sqx/modules/app/bo/UpdateMoneyBO.java
  4. 3 0
      src/main/java/com/sqx/modules/app/entity/UserMoneyDetails.java
  5. 23 0
      src/main/java/com/sqx/modules/app/service/UserMoneyService.java
  6. 90 7
      src/main/java/com/sqx/modules/app/service/impl/UserMoneyServiceImpl.java
  7. 0 3
      src/main/java/com/sqx/modules/datacentre/controller/DataCentreController.java
  8. 3 0
      src/main/java/com/sqx/modules/goods/entity/GoodsShop.java
  9. 8 0
      src/main/java/com/sqx/modules/goods/service/GoodsShopService.java
  10. 19 4
      src/main/java/com/sqx/modules/goods/service/impl/GoodsShopServiceImpl.java
  11. 15 5
      src/main/java/com/sqx/modules/order/controller/app/AppOrderController.java
  12. 9 0
      src/main/java/com/sqx/modules/order/service/AppOrderService.java
  13. 69 28
      src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java
  14. 23 0
      src/main/java/com/sqx/modules/pay/config/WechatPayConfig.java
  15. 42 0
      src/main/java/com/sqx/modules/pay/controller/app/NewPayController.java
  16. 51 0
      src/main/java/com/sqx/modules/pay/dto/GetPayParamDTO.java
  17. 24 0
      src/main/java/com/sqx/modules/pay/enums/PayChannelEnum.java
  18. 32 0
      src/main/java/com/sqx/modules/pay/enums/PaySceneEnum.java
  19. 22 0
      src/main/java/com/sqx/modules/pay/enums/PayStateEnums.java
  20. 44 0
      src/main/java/com/sqx/modules/pay/service/NewPayService.java
  21. 18 1
      src/main/java/com/sqx/modules/pay/service/PayDetailsService.java
  22. 300 0
      src/main/java/com/sqx/modules/pay/service/impl/NewPayServiceImpl.java
  23. 30 0
      src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java
  24. 14 38
      src/main/java/com/sqx/modules/pay/service/impl/WxServiceImpl.java
  25. 18 0
      src/main/java/com/sqx/modules/pay/vo/AliPayTransactionsParam.java
  26. 10 0
      src/main/java/com/sqx/modules/pay/vo/PayTransactionsVO.java
  27. 53 0
      src/main/java/com/sqx/modules/pay/vo/WechatTransactionsParamVO.java
  28. 30 0
      src/main/java/com/sqx/modules/shop/controller/AdminShopMoneyController.java

+ 17 - 0
db/update_241107.sql

@@ -0,0 +1,17 @@
+-- 新增公共配置
+INSERT INTO `tcwm2.5`.`common_info` (`id`, `create_at`, `max`, `min`, `type`, `value`, `condition_from`) VALUES (433, '2024-10-17 10:48:43', NULL, '是否开启新支付', 433, '1', 'weixin');
+INSERT INTO `tcwm2.5`.`common_info` (`id`, `create_at`, `max`, `min`, `type`, `value`, `condition_from`) VALUES (434, '2024-10-17 10:48:43', NULL, '微信支付RHT商户号', 434, '866360132440001', 'weixin');
+INSERT INTO `tcwm2.5`.`common_info` (`id`, `create_at`, `max`, `min`, `type`, `value`, `condition_from`) VALUES (435, '2024-10-17 10:48:43', NULL, '微信支付RHT商户密钥', 435, 'B9591F61B1944A93938DD3DFA9070763', 'weixin');
+
+
+/* --------------- 修改表 --------------- */
+-- 修改表:goods_shop[店铺信息]
+-- 添加字段:
+ALTER TABLE goods_shop
+    ADD COLUMN `mch_id` VARCHAR(32) COMMENT '商户id;' AFTER reservation_open_flag;
+
+/* --------------- 修改表 --------------- */
+-- 修改表:user_money_details[]
+-- 添加字段:
+ALTER TABLE user_money_details
+    ADD COLUMN `remark` VARCHAR(32) COMMENT '备注信息;' AFTER children_id;

+ 8 - 5
pom.xml

@@ -429,17 +429,20 @@
             <version>0.1.54</version>
         </dependency>
 
-        <!--<dependency>-->
-        <!--<groupId>com.baidu.aip</groupId>-->
-        <!--            <artifactId>java-sdk</artifactId>-->
-        <!--            <version>4.11.3</version>-->
-        <!--</dependency>-->
         <!-- minio -->
         <dependency>
             <groupId>io.minio</groupId>
             <artifactId>minio</artifactId>
             <version>8.5.9</version>
         </dependency>
+
+        <!-- rht pay -->
+        <dependency>
+            <groupId>com.ekyong</groupId>
+            <artifactId>rht-pay</artifactId>
+            <version>1.2</version>
+        </dependency>
+
     </dependencies>
 
     <dependencyManagement>

+ 42 - 0
src/main/java/com/sqx/modules/app/bo/UpdateMoneyBO.java

@@ -0,0 +1,42 @@
+package com.sqx.modules.app.bo;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 更新余额bo
+ *
+ * @author : codingliang
+ * @date : 2024-11-07 21:59
+ */
+@Data
+@Builder
+public class UpdateMoneyBO {
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+    /**
+     * 变动类型 1增加、2减少
+     */
+    private Integer type;
+    /**
+     * 变动来源 1骑手保证金  2商户保证金  3钱包明细
+     */
+    private Integer classify;
+    /**
+     * 变动金额
+     */
+    private BigDecimal amount;
+    /**
+     * 明细标题
+     */
+    private String title;
+    /**
+     * 明细备注
+     */
+    private String remark;
+}

+ 3 - 0
src/main/java/com/sqx/modules/app/entity/UserMoneyDetails.java

@@ -75,6 +75,9 @@ public class UserMoneyDetails implements Serializable {
     @ApiModelProperty("创建时间")
     private String createTime;
 
+    @ApiModelProperty("备注")
+    private String remark;
+
     @TableField(exist = false)
     private String userName;
 

+ 23 - 0
src/main/java/com/sqx/modules/app/service/UserMoneyService.java

@@ -3,7 +3,9 @@ package com.sqx.modules.app.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.sqx.common.utils.Result;
+import com.sqx.modules.app.bo.UpdateMoneyBO;
 import com.sqx.modules.app.entity.UserMoney;
+import com.sqx.modules.app.entity.UserMoneyDetails;
 import com.sqx.modules.order.entity.TbOrder;
 import org.springframework.web.bind.annotation.RequestAttribute;
 
@@ -28,4 +30,25 @@ public interface UserMoneyService extends IService<UserMoney> {
     Result updateCashDeposit(Long userId, BigDecimal money, Integer type);
 
     void addConsumeRecord(TbOrder order);
+
+    /**
+     * 新增用户余额
+     * @param updateMoneyBO 金额变动bo
+     * @return
+     */
+    UserMoneyDetails updateUserMoney(UpdateMoneyBO updateMoneyBO);
+
+    /**
+     * 商户分账
+     * @param shopId 商铺id
+     * @param amount 分账金额
+     */
+    void splitBill(Long shopId, BigDecimal amount);
+
+    /**
+     * 根据用户id查找
+     * @param userId 用户id
+     * @return 用户钱包
+     */
+    UserMoney getByUserId(Long userId);
 }

+ 90 - 7
src/main/java/com/sqx/modules/app/service/impl/UserMoneyServiceImpl.java

@@ -1,16 +1,20 @@
 package com.sqx.modules.app.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sqx.common.exception.SqxException;
 import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.Result;
+import com.sqx.modules.app.bo.UpdateMoneyBO;
 import com.sqx.modules.app.dao.UserDao;
 import com.sqx.modules.app.dao.UserMoneyDao;
 import com.sqx.modules.app.dao.UserMoneyDetailsDao;
-import com.sqx.modules.app.dao.UserVipDao;
-import com.sqx.modules.app.dao.VipDetailsDao;
 import com.sqx.modules.app.entity.RechargeRecord;
 import com.sqx.modules.app.entity.UserEntity;
 import com.sqx.modules.app.entity.UserMoney;
@@ -20,11 +24,16 @@ import com.sqx.modules.app.service.UserMoneyDetailsService;
 import com.sqx.modules.app.service.UserMoneyService;
 import com.sqx.modules.common.entity.CommonInfo;
 import com.sqx.modules.common.service.CommonInfoService;
+import com.sqx.modules.goods.entity.GoodsShop;
+import com.sqx.modules.goods.service.GoodsShopService;
 import com.sqx.modules.order.entity.TbOrder;
+import com.sqx.modules.pay.service.NewPayService;
 import com.sqx.modules.utils.SenInfoCheckUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
@@ -38,12 +47,7 @@ public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> i
     @Autowired
     private UserMoneyDetailsDao userMoneyDetailsDao;
     @Autowired
-    private UserVipDao userVipDao;
-    @Autowired
-    private VipDetailsDao vipDetailsDao;
-    @Autowired
     private UserDao userDao;
-
     @Autowired
     private UserMoneyDao userMoneyDao;
     @Autowired
@@ -52,6 +56,10 @@ public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> i
     private CommonInfoService commonInfoService;
     @Autowired
     private RechargeRecordService rechargeRecordService;
+    @Autowired
+    private GoodsShopService goodsShopService;
+    @Autowired
+    private NewPayService newPayService;
 
     @Override
     public void updateMoney(int i, Long userId, double money) {
@@ -255,6 +263,81 @@ public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> i
         userMoneyDetailsDao.insert(userMoneyDetails);
     }
 
+    @Override
+    @Transactional(propagation = Propagation.SUPPORTS)
+    public UserMoneyDetails updateUserMoney(UpdateMoneyBO updateMoneyBO) {
+        Long userId = updateMoneyBO.getUserId();
+        UserMoney userMoney = getByUserId(userId);
+        BigDecimal changeAmount = updateMoneyBO.getAmount();
+        Integer changeType = updateMoneyBO.getType();
+        if (changeType == 2) {
+            if (userMoney.getMoney().compareTo(changeAmount) <= 0) {
+                throw new SqxException("当前店铺钱包余额不足,扣减失败!");
+            }
+        }
+
+        // 修改总金额
+        baseMapper.updateMayMoney(updateMoneyBO.getType(), userId, changeAmount.doubleValue());
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        // 新增明细
+        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
+        userMoneyDetails.setUserId(userId);
+        userMoneyDetails.setTitle(updateMoneyBO.getTitle());
+        userMoneyDetails.setType(changeType);
+        userMoneyDetails.setClassify(3);
+        userMoneyDetails.setState(2);
+        userMoneyDetails.setMoney(changeAmount);
+        String changeTypeFlag = changeType == 1 ? "新增" : "减少";
+        userMoneyDetails.setContent(changeTypeFlag + ":" + changeAmount +"元");
+        userMoneyDetails.setRemark(updateMoneyBO.getRemark());
+        userMoneyDetails.setCreateTime(sdf.format(new Date()));
+        userMoneyDetailsDao.insert(userMoneyDetails);
+
+        return userMoneyDetails;
+    }
+
+    @Override
+    @Transactional
+    public void splitBill(Long shopId, BigDecimal amount) {
+        GoodsShop goodsShop = goodsShopService.getById(shopId);
+        if (ObjectUtil.isNull(goodsShop)) {
+            throw new SqxException("无效的店铺id");
+        }
+
+        String mchId = goodsShop.getMchId();
+        if (StrUtil.isBlank(mchId)) {
+            throw new SqxException("店铺未录入商户号");
+        }
+
+        UpdateMoneyBO updateMoneyBO = UpdateMoneyBO.builder()
+                .userId(goodsShop.getUserId())
+                .type(2)
+                .classify(3)
+                .amount(amount)
+                .title("系统分账")
+                .build();
+        UserMoneyDetails userMoneyDetails = updateUserMoney(updateMoneyBO);
+
+        String traceNo = newPayService.wechatSplitBill(mchId, amount);
+
+        userMoneyDetails.setRemark(traceNo);
+        userMoneyDetailsService.updateById(userMoneyDetails);
+    }
+
+    @Override
+    public UserMoney getByUserId(Long userId) {
+        LambdaQueryWrapper<UserMoney> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(UserMoney::getUserId, userId);
+
+        UserMoney userMoney = this.getOne(queryWrapper);
+        if (ObjectUtil.isNull(userMoney)) {
+            throw new SqxException("未查到对应用户钱包信息");
+        }
+
+        return userMoney;
+    }
 
     /**
      * 开通成功会员后  奖励金币

+ 0 - 3
src/main/java/com/sqx/modules/datacentre/controller/DataCentreController.java

@@ -5,14 +5,11 @@ import com.sqx.modules.app.entity.RechargeRecord;
 import com.sqx.modules.app.entity.UserEntity;
 import com.sqx.modules.app.service.RechargeRecordService;
 import com.sqx.modules.app.service.UserMoneyService;
-import com.sqx.modules.coupon.entity.TbCouponUser;
-import com.sqx.modules.coupon.service.TbCouponService;
 import com.sqx.modules.coupon.service.TbCouponUserService;
 import com.sqx.modules.datacentre.query.DataCenterQuery;
 import com.sqx.modules.datacentre.query.ShopCenterQuery;
 import com.sqx.modules.datacentre.service.DataCentreService;
 import com.sqx.modules.errand.service.ErrandComplaintService;
-import com.sqx.modules.integral.dao.UserIntegralDetailsDao;
 import com.sqx.modules.integral.service.UserIntegralDetailsService;
 import com.sqx.modules.order.service.AppOrderService;
 import io.swagger.annotations.Api;

+ 3 - 0
src/main/java/com/sqx/modules/goods/entity/GoodsShop.java

@@ -178,6 +178,9 @@ public class GoodsShop implements Serializable {
     @ApiModelProperty("预约开启标识 0未开启 1开启")
     private Integer reservationOpenFlag;
 
+    @ApiModelProperty("商户id")
+    private String mchId;
+
     /**
      * 设备类型 1飞鹅 2pos机
      */

+ 8 - 0
src/main/java/com/sqx/modules/goods/service/GoodsShopService.java

@@ -42,4 +42,12 @@ public interface GoodsShopService extends IService<GoodsShop> {
     // ActivityManage getShopActivity(Long shopId);
 
     GoodsShop selectGoodDatas(Long shopId);
+
+    /**
+     * 商户缴纳保证金
+     * @param money 缴纳金额
+     * @param shopId 店铺id
+     * @param remark 备注
+     */
+    void updateCashDeposit(Double money, Long shopId, String remark);
 }

+ 19 - 4
src/main/java/com/sqx/modules/goods/service/impl/GoodsShopServiceImpl.java

@@ -15,6 +15,8 @@ import com.sqx.modules.app.dao.UserDao;
 import com.sqx.modules.app.entity.Msg;
 import com.sqx.modules.app.entity.UserEntity;
 import com.sqx.modules.app.entity.UserMoney;
+import com.sqx.modules.app.entity.UserMoneyDetails;
+import com.sqx.modules.app.service.UserMoneyDetailsService;
 import com.sqx.modules.app.service.UserMoneyService;
 import com.sqx.modules.app.service.UserService;
 import com.sqx.modules.common.entity.CommonInfo;
@@ -93,9 +95,7 @@ public class GoodsShopServiceImpl extends ServiceImpl<GoodsShopDao, GoodsShop> i
     @Autowired
     private UserIntegralService userIntegralService;
     @Autowired
-    private ShopMessageService shopMessageService;
-    @Autowired
-    private ShopTypeService typeService;
+    private UserMoneyDetailsService userMoneyDetailsService;
 
 
     @Override
@@ -538,5 +538,20 @@ public class GoodsShopServiceImpl extends ServiceImpl<GoodsShopDao, GoodsShop> i
         return result;
     }
 
-
+    @Override
+    @Transactional
+    public void updateCashDeposit(Double money, Long shopId, String remark) {
+        goodsShopDao.updateCashDeposit(money, shopId);
+
+        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
+        userMoneyDetails.setShopId(shopId);
+        userMoneyDetails.setTitle("商户缴纳保证金:" + remark);
+        userMoneyDetails.setType(1);
+        userMoneyDetails.setState(2);
+        userMoneyDetails.setClassify(2);
+        userMoneyDetails.setMoney(BigDecimal.valueOf(money));
+        userMoneyDetails.setContent("商户缴纳保证金" + money + "元");
+        userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+        userMoneyDetailsService.save(userMoneyDetails);
+    }
 }

+ 15 - 5
src/main/java/com/sqx/modules/order/controller/app/AppOrderController.java

@@ -1,29 +1,32 @@
 package com.sqx.modules.order.controller.app;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.sqx.common.utils.Result;
 import com.sqx.modules.app.annotation.Login;
 import com.sqx.modules.order.entity.Evaluate;
 import com.sqx.modules.order.entity.TbOrder;
 import com.sqx.modules.order.service.AppOrderService;
 import com.sqx.modules.order.service.EvaluateService;
+import com.sqx.modules.pay.dto.PayOrderDTO;
+import com.sqx.modules.pay.vo.PayTransactionsVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import javax.validation.Valid;
 import java.util.List;
 
 @Slf4j
 @Api(tags={"用户端-订单"})
 @RestController
 @RequestMapping("/app/order")
+@RequiredArgsConstructor
 public class AppOrderController {
 
-    @Autowired
-    private AppOrderService appOrderService;
-    @Autowired
-    private EvaluateService evaluateService;
+    private final AppOrderService appOrderService;
+    private final EvaluateService evaluateService;
 
     @Login
     @ApiOperation("生成订单(未结算状态)")
@@ -263,4 +266,11 @@ public class AppOrderController {
         return appOrderService.updateTimeOutOrder(userId, orderId);
     }
 
+    @Login
+    @ApiOperation("获取支付参数")
+    @GetMapping(value = "get-pay-param")
+    public Result getPayParam(@RequestAttribute("userId") Long userId, @Valid PayOrderDTO payOrderDTO){
+        PayTransactionsVO payParamVO = appOrderService.getTransactionsParam(userId, payOrderDTO);
+        return Result.success(BeanUtil.beanToMap(payParamVO, false, true));
+    }
 }

+ 9 - 0
src/main/java/com/sqx/modules/order/service/AppOrderService.java

@@ -9,6 +9,7 @@ import com.sqx.modules.order.entity.Evaluate;
 import com.sqx.modules.order.entity.OrderGoods;
 import com.sqx.modules.order.entity.TbOrder;
 import com.sqx.modules.pay.dto.PayOrderDTO;
+import com.sqx.modules.pay.vo.PayTransactionsVO;
 import com.sqx.modules.utils.excel.ExcelData;
 
 import java.time.LocalDateTime;
@@ -174,4 +175,12 @@ public interface AppOrderService extends IService<TbOrder> {
     Result selectOrder(Long userId, Integer orderId,Integer page, Integer limit);
 
     Result updateTimeOutOrder(Long userId, Integer orderId);
+
+    /**
+     * 获取交易参数
+     * @param userId 用户id
+     * @param payOrderDTO 支付参数
+     * @return 交易参数
+     */
+    PayTransactionsVO getTransactionsParam(Long userId, PayOrderDTO payOrderDTO);
 }

+ 69 - 28
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -5,7 +5,6 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -46,8 +45,8 @@ import com.sqx.modules.coupon.entity.TbCouponUser;
 import com.sqx.modules.datacentre.entity.SysUserShop;
 import com.sqx.modules.errand.dao.TbIndentDao;
 import com.sqx.modules.errand.entity.TbIndent;
-import com.sqx.modules.errand.entity.TbIndentSmsSendLog;
 import com.sqx.modules.errand.service.TbIndentService;
+import com.sqx.modules.errand.entity.TbIndentSmsSendLog;
 import com.sqx.modules.errand.service.TbIndentSmsSendLogService;
 import com.sqx.modules.errand.service.TbIndentSmsTemplateService;
 import com.sqx.modules.goods.dao.GoodsDao;
@@ -71,9 +70,15 @@ import com.sqx.modules.order.entity.TbOrder;
 import com.sqx.modules.order.service.AppOrderService;
 import com.sqx.modules.pay.controller.app.AliPayController;
 import com.sqx.modules.pay.dao.PayDetailsDao;
+import com.sqx.modules.pay.dto.GetPayParamDTO;
 import com.sqx.modules.pay.dto.PayOrderDTO;
 import com.sqx.modules.pay.entity.PayDetails;
+import com.sqx.modules.pay.enums.PayChannelEnum;
+import com.sqx.modules.pay.enums.PaySceneEnum;
+import com.sqx.modules.pay.service.NewPayService;
 import com.sqx.modules.pay.service.WxErrService;
+import com.sqx.modules.pay.vo.AliPayTransactionsParam;
+import com.sqx.modules.pay.vo.PayTransactionsVO;
 import com.sqx.modules.shop.service.ShopMessageService;
 import com.sqx.modules.sys.dao.SysUserRoleDao;
 import com.sqx.modules.sys.entity.SysUserEntity;
@@ -96,7 +101,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.DefaultTransactionDefinition;
 
 import javax.annotation.Resource;
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -165,7 +169,6 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
     private ActivityService activityService;
     @Autowired
     private ActivityPartRecordService activityPartRecordService;
-
     @Autowired
     private SysUserService sysUserService;
     @Autowired
@@ -173,6 +176,10 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
     @Autowired
     private TbIndentSmsTemplateService smsTemplateService;
     @Autowired
+    private NewPayService newPayService;
+    @Autowired
+    private AliPayController aliPayController;
+    @Autowired
     private PlatformTransactionManager transactionManager;
 
     @Resource
@@ -428,6 +435,8 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         // 获取店铺信息
         // 注意:调用shopMessageService获取店铺信息,这个service对店铺的抽成比例有特殊处理(历史代码就是如此/(ㄒoㄒ)/~~)
         GoodsShop goodsShop = shopMessageService.selectShopId(parentOrder.getShopId());
+        // 给支付的时候商品描述用
+        parentOrder.setShopName(goodsShop.getShopName());
 
         // // 设置订单类型
         // parentOrder.setOrderType(payOrderDTO.getOrderType());
@@ -1772,7 +1781,7 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
                 userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
             } else if (tbOrder.getPayType() == 1) {
                 PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
-                boolean b = wxErrService.wxRefund(payDetails);
+                boolean b = wechatPayRefund(payDetails);
                 if (!b) {
                     return Result.error("退款失败,请联系客服!");
                 }
@@ -1844,6 +1853,22 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         return Result.success();
     }
 
+    /**
+     * 微信支付退款
+     * @param payDetails 支付订单
+     */
+    private boolean wechatPayRefund(PayDetails payDetails) {
+        boolean b;
+        boolean newPay = newPayService.enableNewPay();
+        if (newPay) {
+            b = newPayService.wechatRefund(payDetails.getOrderId());
+        } else {
+            b = wxErrService.wxRefund(payDetails);
+        }
+
+        return b;
+    }
+
 
     @Override
     public Result updateOrder(TbOrder order) {
@@ -2210,7 +2235,7 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
                 userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
             } else if (tbOrder.getPayType() == 1) {
                 PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
-                boolean b = wxErrService.wxRefund(payDetails);
+                boolean b = wechatPayRefund(payDetails);
                 if (!b) {
                     return Result.error("退款失败,请联系客服!");
                 }
@@ -2355,7 +2380,8 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
                 userMoneyDao.updateMayMoney(1, tbOrder.getUserId(), tbOrder.getPayMoney().doubleValue());
             } else if (tbOrder.getPayType() == 1) {
                 PayDetails payDetails = payDetailsDao.selectByOrderId(tbOrder.getOrderNumber());
-                boolean b = wxErrService.wxRefund(payDetails);
+                // 退款
+                boolean b = wechatPayRefund(payDetails);
                 if (!b) {
                     return Result.error("退款失败,请联系客服!");
                 }
@@ -2499,27 +2525,6 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         return format + newString;
     }
 
-
-    // @Scheduled(cron = "0 */1 * * * ?")
-    // public void makeOrders(){
-    //     //自动制作完成订单
-    //     String value = commonInfoService.findOne(418).getValue();
-    //     if("是".equals(value)){
-    //         String minute = commonInfoService.findOne(419).getValue();
-    //         LocalDateTime minusMinutes = LocalDateTime.now().minusMinutes(Long.valueOf(minute));
-    //         List<TbOrder> tbOrders = baseMapper.selectMakeOrdersList(minusMinutes);
-    //         for (TbOrder order:tbOrders){
-    //             try{
-    //                 order.setStatus(3);
-    //                 updateOrder(order);
-    //             }catch (Exception e){
-    //                 e.printStackTrace();
-    //                 log.error("自动完成异常:"+e.getMessage(),e);
-    //             }
-    //         }
-    //     }
-    // }
-
     @Override
     public List<TbOrder> getProdIngOrders(LocalDateTime minusMinutes) {
         return baseMapper.selectMakeOrdersList(minusMinutes);
@@ -2572,9 +2577,45 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         } finally {
             lock.unlock();
         }
+    }
 
+    @Override
+    public PayTransactionsVO getTransactionsParam(Long userId, PayOrderDTO payOrderDTO) {
+        TbOrder order = prepareOrder(userId, payOrderDTO);
 
+        // 在同一时刻用户只能在同一家店铺执行一次下单操作 ??
+        RLock lock = redissonClient.getLock(String.format(RedisKey.INSERT_ORDER_LOCK, order.getUserId(), order.getShopId()));
+        lock.lock();
+        try {
+            // 设置支付方式 1表示微信支付、4或5表示支付宝支付
+            Integer type = payOrderDTO.getType();
+
+           // 微信支付
+            if (type == 1) {
+                UserEntity userEntity = userService.queryByUserId(userId);
+
+                GetPayParamDTO dto = GetPayParamDTO.builder()
+                        .orderNo(order.getOrderNumber())
+                        .orderDesc(order.getShopName())
+                        .amount(order.getPayMoney())
+                        .userId(userId)
+                        .userThirdId(userEntity.getOpenId())
+                        .payChannel(PayChannelEnum.WECHAT_JS_API)
+                        .paySceneEnum(PaySceneEnum.ORDER_PAY)
+                        .build();
+                return newPayService.getWechatTransactionsParamVO(dto);
+            }
+            // 支付宝支付,暂时未重构先不管,copy原有代码
+            else {
+                Result result = aliPayController.payAppOrders(order.getPayMoney().doubleValue(), type, order.getUserId(), order.getOrderNumber(), 1);
 
+                AliPayTransactionsParam transactionsParam = new AliPayTransactionsParam();
+                transactionsParam.setBody(result.get("data").toString());
+                return transactionsParam;
+            }
+        } finally {
+            lock.unlock();
+        }
     }
 
     /**

+ 23 - 0
src/main/java/com/sqx/modules/pay/config/WechatPayConfig.java

@@ -0,0 +1,23 @@
+package com.sqx.modules.pay.config;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 微信支付配置
+ *
+ * @author : codingliang
+ * @date : 2024-11-07 19:14
+ */
+@Data
+@Builder
+public class WechatPayConfig {
+    // AppId
+    private String appId;
+    // 商户id
+    private String mchId;
+    // 微信商户key
+    private String mchKey;
+    // h5服务域名配置
+    private String h5Url;
+}

+ 42 - 0
src/main/java/com/sqx/modules/pay/controller/app/NewPayController.java

@@ -0,0 +1,42 @@
+package com.sqx.modules.pay.controller.app;
+
+import cn.hutool.core.map.MapUtil;
+import com.sqx.common.utils.Result;
+import com.sqx.modules.pay.service.NewPayService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@Slf4j
+@Api(value = "新支付", tags = {"新支付"})
+@RestController
+@RequestMapping("app/new-pay")
+@RequiredArgsConstructor
+public class NewPayController {
+
+    private final NewPayService payService;
+
+    @GetMapping("enable-new-pay")
+    @ApiOperation("是否启用新支付")
+    public Result enableNewPay() {
+        boolean flag = payService.enableNewPay();
+        Map<String, Object> enable = MapUtil.<String, Object>builder()
+                .put("enable", flag)
+                .build();
+        return Result.success(enable);
+    }
+
+    @PostMapping("wechat-pay/notify")
+    @ApiOperation("RTH微信支付回调")
+    public String wechatPayNotify(@RequestBody String reqJsonData) {
+        return payService.wechatPayNotify(reqJsonData);
+    }
+}

+ 51 - 0
src/main/java/com/sqx/modules/pay/dto/GetPayParamDTO.java

@@ -0,0 +1,51 @@
+package com.sqx.modules.pay.dto;
+
+import com.sqx.modules.pay.enums.PaySceneEnum;
+import com.sqx.modules.pay.enums.PayChannelEnum;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 获取支付参数dto
+ *
+ * @author : codingliang
+ * @date : 2024-11-05 22:11
+ */
+@Data
+@Builder
+public class GetPayParamDTO {
+    /**
+     * 订单号
+     */
+    private String orderNo;
+    /**
+     * 订单描述
+     */
+    private String orderDesc;
+    /**
+     * 订单金额,单位:元
+     */
+    private BigDecimal amount;
+    /**
+     * 用户id
+     */
+    private Long userId;
+    /**
+     * 店铺id
+     */
+    private Long shopId;
+    /**
+     * 用于第三方平台id
+     */
+    private String userThirdId;
+    /**
+     * 支付渠道
+     */
+    private PayChannelEnum payChannel;
+    /**
+     * 支付场景
+     */
+    private PaySceneEnum paySceneEnum;
+}

+ 24 - 0
src/main/java/com/sqx/modules/pay/enums/PayChannelEnum.java

@@ -0,0 +1,24 @@
+package com.sqx.modules.pay.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 支付渠道枚举
+ *
+ * @author : codingliang
+ * @date : 2024-11-05 22:43
+ */
+@Getter
+@AllArgsConstructor
+public enum PayChannelEnum {
+
+    WECHAT_APP(1, "微信app支付"),
+    WECHAT_NATIVE(2, "微信二维码支付"),
+    WECHAT_JS_API(3, "微信小程序、微信公众号支付"),
+    ALIPAY_APP(4, "支付宝app支付"),
+    ALIPAY_H5(5, "支付宝h5支付");
+
+    private int code;
+    private String methodName;
+}

+ 32 - 0
src/main/java/com/sqx/modules/pay/enums/PaySceneEnum.java

@@ -0,0 +1,32 @@
+package com.sqx.modules.pay.enums;
+
+import com.sqx.common.exception.SqxException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 支付场景
+ *
+ * @author : codingliang
+ * @date : 2024-11-06 10:25
+ */
+@Getter
+@AllArgsConstructor
+public enum PaySceneEnum {
+    ORDER_PAY(1, "订单支付"),
+    BALANCE_RECHARGE(2, "余额充值"),
+    BOND_PAY(3, "保证金缴纳"),
+    VIP_PAY(4, "购买会员");
+
+    private int sceneCode;
+    private String sceneDesc;
+
+    public static PaySceneEnum getBySceneCode(int code) {
+        return Arrays.stream(PaySceneEnum.values())
+                .filter(e -> e.getSceneCode() == code)
+                .findFirst()
+                .orElseThrow(() -> new SqxException("无效的支付场景code"));
+    }
+}

+ 22 - 0
src/main/java/com/sqx/modules/pay/enums/PayStateEnums.java

@@ -0,0 +1,22 @@
+package com.sqx.modules.pay.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 支付状态
+ *
+ * @author : codingliang
+ * @date : 2024-11-06 10:19
+ */
+@Getter
+@AllArgsConstructor
+public enum PayStateEnums {
+    // 0待支付 1支付成功 2失败
+    WAIT_PAY(0, "等待支付"),
+    PAY_SUCCESS(1, "支付成功"),
+    PAY_FAIL(2, "支付失败");
+
+    private int stateCode;
+    private String stateDesc;
+}

+ 44 - 0
src/main/java/com/sqx/modules/pay/service/NewPayService.java

@@ -0,0 +1,44 @@
+package com.sqx.modules.pay.service;
+
+import com.sqx.modules.pay.dto.GetPayParamDTO;
+import com.sqx.modules.pay.vo.WechatTransactionsParamVO;
+
+import java.math.BigDecimal;
+
+public interface NewPayService {
+
+    /**
+     * 获取拉取微信交易参数
+     * @param payParam 支付参数
+     * @return 微信交易参数
+     */
+    WechatTransactionsParamVO getWechatTransactionsParamVO(GetPayParamDTO payParam);
+
+    /**
+     * 微信支付退款
+     * @param orderNo 订单号
+     * @return 是否退款成功
+     */
+    boolean wechatRefund(String orderNo);
+
+    /**
+     * 微信分账
+     * @param inMchId 入账商户号
+     * @param amount 入账金额
+     * @return 分账编号
+     */
+    String wechatSplitBill(String inMchId, BigDecimal amount);
+
+    /**
+     * 微信支付回调
+     * @param reqJsonData 请求数据
+     * @return 返回结果
+     */
+    String wechatPayNotify(String reqJsonData);
+
+    /**
+     * 是否开启新支付
+     * @return boolean
+     */
+    boolean enableNewPay();
+}

+ 18 - 1
src/main/java/com/sqx/modules/pay/service/PayDetailsService.java

@@ -2,7 +2,8 @@ package com.sqx.modules.pay.service;
 
 import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.Result;
-import org.apache.poi.ss.formula.functions.T;
+import com.sqx.modules.pay.dto.GetPayParamDTO;
+import com.sqx.modules.pay.entity.PayDetails;
 
 public interface PayDetailsService {
 
@@ -23,4 +24,20 @@ public interface PayDetailsService {
     Double instantselectSumPay(String date, Long userId);
 
     Result selectPayDetailsById(Integer page, Integer limit, Long userId, String startTime, String endTime);
+
+    /**
+     * 根据订单编号查找
+     * @param orderNo 订单编号
+     * @return 支付订单
+     */
+    PayDetails getByOrderNo(String orderNo);
+
+    /**
+     * 新增支付订单
+     * @param dto 交易参数
+     * @param payParam 支付参数
+     */
+    void addPayDetail(GetPayParamDTO dto, String payParam);
+
+    void updateDetail(PayDetails payDetails);
 }

+ 300 - 0
src/main/java/com/sqx/modules/pay/service/impl/NewPayServiceImpl.java

@@ -0,0 +1,300 @@
+package com.sqx.modules.pay.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.ekyong.www.pay.common.Constant;
+import com.ekyong.www.pay.pay.qrcode.api.RhtQrcodePayApi;
+import com.ekyong.www.pay.pay.qrcode.bean.QrcodeOpenPayRequestBean;
+import com.ekyong.www.pay.pay.qrcode.bean.QrcodeOpenPayResponseBean;
+import com.ekyong.www.pay.pay.qrcode.bean.QrcodeRefundRequestBean;
+import com.ekyong.www.pay.pay.qrcode.bean.QrcodeRefundResponseBean;
+import com.ekyong.www.pay.pay.split.api.RhtSplitApi;
+import com.ekyong.www.pay.pay.split.bean.SplitPayRequestBean;
+import com.ekyong.www.pay.pay.split.bean.SplitPayResponseBean;
+import com.ekyong.www.pay.util.SignUtil;
+import com.sqx.common.exception.SqxException;
+import com.sqx.common.utils.SpringContextUtils;
+import com.sqx.modules.app.bo.UpdateMoneyBO;
+import com.sqx.modules.app.service.UserMoneyService;
+import com.sqx.modules.common.service.CommonInfoService;
+import com.sqx.modules.datacentre.service.DataCentreService;
+import com.sqx.modules.goods.service.GoodsShopService;
+import com.sqx.modules.order.entity.TbOrder;
+import com.sqx.modules.order.service.AppOrderService;
+import com.sqx.modules.pay.config.WechatPayConfig;
+import com.sqx.modules.pay.dto.GetPayParamDTO;
+import com.sqx.modules.pay.entity.PayDetails;
+import com.sqx.modules.pay.enums.PayChannelEnum;
+import com.sqx.modules.pay.enums.PaySceneEnum;
+import com.sqx.modules.pay.enums.PayStateEnums;
+import com.sqx.modules.pay.service.NewPayService;
+import com.sqx.modules.pay.service.PayDetailsService;
+import com.sqx.modules.pay.vo.WechatTransactionsParamVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.net.URLDecoder;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.Map;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NewPayServiceImpl implements NewPayService {
+
+    private final PayDetailsService payDetailsService;
+    private final CommonInfoService commonInfoService;
+    private final UserMoneyService userMoneyService;
+    private final GoodsShopService goodsShopService;
+    private final DataCentreService dataCentreService;
+
+    /**
+     * 润海通支付接口地址
+     */
+    private final static String RHT_PAY_BASE_URL = "https://api.ekbuyclub.com";
+
+    private final static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    public WechatTransactionsParamVO getWechatTransactionsParamVO(GetPayParamDTO dto) {
+        // 润海通支付,目前只测试了小程序支付,其余支付方式不考虑
+        if (dto.getPayChannel() != PayChannelEnum.WECHAT_JS_API) {
+            throw new SqxException("不支持的支付方式!");
+        }
+
+        PayDetails payDetails = payDetailsService.getByOrderNo(dto.getOrderNo());
+        if (ObjectUtil.isNotNull(payDetails)) {
+            // 如果在支付有效期内,则直接返回支付参数,否则提示订单超时
+            LocalDateTime createTime = LocalDateTime.parse(payDetails.getCreateTime(), DTF);
+
+            // 支付时间大于2小时后不能再次支付
+            if (Duration.between(createTime, LocalDateTime.now()).toMinutes() > 120) {
+                throw new SqxException("当前订单已超时关闭,请重新下单!");
+            }
+
+            return JSONUtil.toBean(payDetails.getRemark(), WechatTransactionsParamVO.class);
+        }
+
+        WechatPayConfig wechatMchConfig = getWechatMchConfig();
+
+        // h5服务域名配置
+        String notifyUrl = wechatMchConfig.getH5Url() + "/sqx_fast/app/new-pay/notify";
+
+        RhtQrcodePayApi qrcodePay = new RhtQrcodePayApi(wechatMchConfig.getMchId(), wechatMchConfig.getMchKey(), RHT_PAY_BASE_URL);
+        QrcodeOpenPayRequestBean openRequest = new QrcodeOpenPayRequestBean();
+        openRequest.setAmount(dto.getAmount().toString());
+        openRequest.setTraceno(dto.getOrderNo());
+        openRequest.setPayType(Constant.PAY_TYPE_WECHAT);
+        openRequest.setGoodsName(dto.getOrderDesc());
+        openRequest.setNotifyUrl(notifyUrl);
+
+        // 小程序支付,固定填1
+        openRequest.setCallType("1");
+        openRequest.setAppid(wechatMchConfig.getAppId());
+        openRequest.setOpenid(dto.getUserThirdId());
+
+        WechatTransactionsParamVO wechatPayParamVO;
+        try {
+            QrcodeOpenPayResponseBean response = qrcodePay.openPay(openRequest);
+            JSONObject barCodeJson = JSONUtil.parseObj(response.getBarCode());
+            wechatPayParamVO = barCodeJson.toBean(WechatTransactionsParamVO.class);
+            wechatPayParamVO.setPackageStr(barCodeJson.getStr("package"));
+        } catch (Exception e) {
+            throw new SqxException("获取支付参数失败:" + e.getMessage());
+        }
+
+        // 初始化支付订单
+        payDetailsService.addPayDetail(dto, JSONUtil.toJsonStr(wechatPayParamVO));
+        return wechatPayParamVO;
+    }
+
+    @Override
+    public boolean wechatRefund(String orderNo) {
+        WechatPayConfig wechatMchConfig = getWechatMchConfig();
+        RhtQrcodePayApi qrcodePay = new RhtQrcodePayApi(wechatMchConfig.getMchId(), wechatMchConfig.getMchKey(), RHT_PAY_BASE_URL);
+        QrcodeRefundRequestBean request = new QrcodeRefundRequestBean();
+        // 商户流水号
+        request.setTraceno(orderNo);
+        // 接口版本号
+        request.setVersion("1.0");
+
+        try {
+            QrcodeRefundResponseBean response = qrcodePay.refund(request);
+            String respCode = response.getRespCode();
+            if (StrUtil.equals("00", respCode)) {
+                return true;
+            } else {
+                log.error("订单【{}】退款失败,失败原因:{}", orderNo, response.getMessage());
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("订单【{}】退款失败,失败原因:{}", orderNo, e.getMessage());
+        }
+        return false;
+    }
+
+    @Override
+    public String wechatSplitBill(String inMchId, BigDecimal amount) {
+        WechatPayConfig wechatMchConfig = getWechatMchConfig();
+        RhtSplitApi splitApi = new RhtSplitApi(wechatMchConfig.getMchId(), wechatMchConfig.getMchKey(), RHT_PAY_BASE_URL);
+
+        String traceNo = IdWorker.getTimeId();
+        String outAmount = amount.toString();
+
+        SplitPayRequestBean request = new SplitPayRequestBean();
+        request.setVersion("1.0");
+        request.setTraceno(traceNo);
+        request.setOutMerchno(wechatMchConfig.getMchId());
+        request.setOutAmount(outAmount);
+
+        SplitPayRequestBean.SplitDetail splitDetail = new SplitPayRequestBean.SplitDetail();
+        splitDetail.setInAmount(outAmount);
+        splitDetail.setInMerchno(inMchId);
+
+        request.setSplitDetailList(JSONUtil.toJsonStr(Arrays.asList(splitDetail)));
+
+        try {
+            SplitPayResponseBean splitPayResponse = splitApi.splitPay(request);
+            if (splitPayResponse.getStatus() != 1) {
+                throw new SqxException("分账支付失败," + splitPayResponse.getStatusDesc());
+            }
+
+            return traceNo;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new SqxException("分账," + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional
+    public String wechatPayNotify(String reqJsonData) {
+        try {
+            String decode = URLDecoder.decode(reqJsonData, "GBK");
+            Map<String, String> map = JSONUtil.toBean(decode, Map.class);
+
+            // 微信商户key
+            String mchKey = commonInfoService.findOne(75).getValue();
+            boolean valid = SignUtil.validSignature(map, mchKey);
+            if (!valid) {
+                throw new SqxException("验签失败");
+            }
+
+            String status = map.get("status");
+            String orderNo = map.get("traceno");
+            String transDateStr = map.get("transDate");
+            String transTime = map.get("transTime");
+            if (StrUtil.equals(String.valueOf(PayStateEnums.PAY_SUCCESS.getStateCode()), status)) {
+                PayDetails payDetails = payDetailsService.getByOrderNo(orderNo);
+                if (ObjectUtil.isNull(payDetails)) {
+                    log.error("订单【{}】支付成功,但未获取到支付订单!异步通知信息:{}", orderNo, reqJsonData);
+                    return "success";
+                }
+
+                if (!StrUtil.equals(status, String.valueOf(PayStateEnums.WAIT_PAY.getStateCode()))) {
+                    // 支付订单不是未支付状态,直接返回
+                    return "success";
+                }
+
+                payDetails.setState(PayStateEnums.PAY_SUCCESS.getStateCode());
+                payDetails.setPayTime(transDateStr + " " + transTime);
+                payDetails.setRemark("RHT PAY SUCCESS");
+                payDetailsService.updateDetail(payDetails);
+
+                PaySceneEnum payScene = PaySceneEnum.getBySceneCode(payDetails.getClassify());
+                switch (payScene) {
+                    case ORDER_PAY: handleTakeoutOrderPaySuccess(orderNo); break;
+                    case BALANCE_RECHARGE: handleBalanceRechargePaySuccess(payDetails); break;
+                    case BOND_PAY: handleBondPaySuccess(payDetails); break;
+                    case VIP_PAY: handleVipPaySuccess(payDetails); break;
+                    default:
+                        log.error("监测到不支持的支付成功场景,支付订单信息:{}", JSONUtil.toJsonStr(payDetails));
+                }
+            }
+            return "success";
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("异步通知处理异常:{}", e.getMessage());
+            return "fail";
+        }
+    }
+
+    @Override
+    public boolean enableNewPay() {
+        String value = commonInfoService.findOne(433).getValue();
+        return StrUtil.equals(value, "1");
+    }
+
+    /**
+     * 处理vip购买成功通知
+     * @param payDetails
+     */
+    private void handleVipPaySuccess(PayDetails payDetails) {
+        dataCentreService.presenterVip(payDetails.getUserId());
+
+        // 改动钱包明细??
+    }
+
+    /**
+     * 处理充值成功通知
+     * @param payDetails
+     */
+    private void handleBalanceRechargePaySuccess(PayDetails payDetails) {
+        UpdateMoneyBO updateMoneyBO = UpdateMoneyBO.builder()
+                .userId(payDetails.getUserId())
+                .type(1)
+                .classify(3)
+                .amount(new BigDecimal(payDetails.getMoney()))
+                .title("充值入账")
+                .remark(payDetails.getOrderId())
+                .build();
+        userMoneyService.updateUserMoney(updateMoneyBO);
+    }
+
+    /**
+     * 处理充值成功通知
+     * @param payDetails
+     */
+    private void handleBondPaySuccess(PayDetails payDetails) {
+        goodsShopService.updateCashDeposit(payDetails.getMoney(), payDetails.getShopId(), payDetails.getOrderId());
+    }
+
+    /**
+     * 处理外卖订单支付成功通知
+     * @param orderNo 订单编号
+     */
+    private void handleTakeoutOrderPaySuccess(String orderNo) {
+        AppOrderService appOrderService = SpringContextUtils.getBean("appOrderService", AppOrderService.class);
+
+        // 根据订单编号查询订单
+        TbOrder order = appOrderService.selectOrderByNum(orderNo);
+        // 1 表示微信支付
+        order.setPayType(1);
+        // 订单支付成功,修改订单状态
+        appOrderService.updateOrderAfterPaySuccess(order);
+    }
+
+    /**
+     * 获取微信支付商户配置
+     * @return 商户配置
+     */
+    private WechatPayConfig getWechatMchConfig() {
+        return WechatPayConfig.builder()
+                .appId(commonInfoService.findOne(45).getValue())
+                .mchId(commonInfoService.findOne(434).getValue())
+                .mchKey(commonInfoService.findOne(435).getValue())
+                // .h5Url(commonInfoService.findOne(19).getValue())
+                .h5Url("http://mprds4.natappfree.cc")
+                .build();
+    }
+}

+ 30 - 0
src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java

@@ -5,11 +5,15 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.Result;
 import com.sqx.modules.pay.dao.PayDetailsDao;
+import com.sqx.modules.pay.dto.GetPayParamDTO;
 import com.sqx.modules.pay.entity.PayDetails;
+import com.sqx.modules.pay.enums.PayStateEnums;
 import com.sqx.modules.pay.service.PayDetailsService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Map;
 
 /**
@@ -81,5 +85,31 @@ public class PayDetailsServiceImpl extends ServiceImpl<PayDetailsDao, PayDetails
         return Result.success().put("data", pageUtils);
     }
 
+    @Override
+    public PayDetails getByOrderNo(String orderNo) {
+        return payDetailsDao.selectByOrderId(orderNo);
+    }
+
+    @Override
+    public void addPayDetail(GetPayParamDTO dto, String payParam) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        PayDetails payDetails = new PayDetails();
+        payDetails.setState(PayStateEnums.WAIT_PAY.getStateCode());
+        payDetails.setCreateTime(sdf.format(new Date()));
+        payDetails.setOrderId(dto.getOrderNo());
+        payDetails.setUserId(dto.getUserId());
+        payDetails.setShopId(dto.getShopId());
+        payDetails.setMoney(dto.getAmount().doubleValue());
+        payDetails.setClassify(dto.getPaySceneEnum().getSceneCode());
+        payDetails.setType(dto.getPayChannel().getCode());
+        payDetails.setRemark(payParam);
+        payDetailsDao.insert(payDetails);
 
+    }
+
+    @Override
+    public void updateDetail(PayDetails payDetails) {
+        this.updateById(payDetails);
+    }
 }

+ 14 - 38
src/main/java/com/sqx/modules/pay/service/impl/WxServiceImpl.java

@@ -10,6 +10,7 @@ import com.github.wxpay.sdk.WXPayUtil;
 import com.sqx.common.constant.RedisKey;
 import com.sqx.common.utils.RedisUtils;
 import com.sqx.common.utils.Result;
+import com.sqx.modules.app.bo.UpdateMoneyBO;
 import com.sqx.modules.app.dao.UserDao;
 import com.sqx.modules.app.dao.UserMoneyDetailsDao;
 import com.sqx.modules.app.entity.UserEntity;
@@ -25,6 +26,7 @@ import com.sqx.modules.errand.entity.TbIndent;
 import com.sqx.modules.errand.service.TbIndentService;
 import com.sqx.modules.goods.dao.GoodsShopDao;
 import com.sqx.modules.goods.entity.GoodsShop;
+import com.sqx.modules.goods.service.GoodsShopService;
 import com.sqx.modules.order.dao.AppOrderDao;
 import com.sqx.modules.order.entity.TbOrder;
 import com.sqx.modules.order.service.AppOrderService;
@@ -94,6 +96,8 @@ public class WxServiceImpl implements WxService {
     private TbIndentService indentService;
     @Autowired
     private UserMoneyDetailsService userMoneyDetailsService;
+    @Autowired
+    private GoodsShopService goodsShopService;
 
     private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
@@ -758,26 +762,15 @@ public class WxServiceImpl implements WxService {
     @Override
     public void notfiy(PayDetails payDetails){
         if(payDetails.getClassify()==2){
-            //充值金额
-            userMoneyService.updateMoney(1, payDetails.getUserId(), payDetails.getMoney());
-            //修改本充值记录状态
-            PayDetails payDetails1 = new PayDetails();
-            String date = new SimpleDateFormat("yyyy-MM-dd :HH:mm:ss").format(new Date());
-            payDetails1.setId(payDetails.getId());
-            payDetails1.setState(1);
-            payDetails1.setPayTime(date);
-            payDetailsDao.updateById(payDetails1);
-            //添加钱包消费记录
-            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
-            userMoneyDetails.setUserId(payDetails.getUserId());
-            userMoneyDetails.setTitle("钱包充值");
-            userMoneyDetails.setType(1);
-            userMoneyDetails.setClassify(3);
-            userMoneyDetails.setState(2);
-            userMoneyDetails.setMoney(BigDecimal.valueOf(payDetails.getMoney()));
-            userMoneyDetails.setContent("账户充值到账:"+payDetails.getMoney()+"元");
-            userMoneyDetails.setCreateTime(sdf.format(new Date()));
-            userMoneyDetailsDao.insert(userMoneyDetails);
+            UpdateMoneyBO updateMoneyBO = UpdateMoneyBO.builder()
+                    .type(1)
+                    .classify(3)
+                    .userId(payDetails.getUserId())
+                    .amount(new BigDecimal(payDetails.getMoney()))
+                    .title("充值入账")
+                    .remark(payDetails.getOrderId())
+                    .build();
+            userMoneyService.updateUserMoney(updateMoneyBO);
         }else if(payDetails.getClassify()==1){
             // 根据订单编号查询订单
             TbOrder tbOrder = appOrderService.selectOrderByNum(payDetails.getOrderId());
@@ -786,24 +779,7 @@ public class WxServiceImpl implements WxService {
             appOrderService.updateOrderAfterPaySuccess(tbOrder);
         }else if(payDetails.getClassify()==3){
             //商户交保证金
-            Double money = payDetails.getMoney();
-            Long shopId = payDetails.getShopId();
-            goodsShopDao.updateCashDeposit(money, shopId);
-            PayDetails payDetails1 = new PayDetails();
-            payDetails1.setId(payDetails.getId());
-            payDetails1.setState(1);
-            payDetailsDao.updateById(payDetails1);
-            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
-            userMoneyDetails.setShopId(shopId);
-            userMoneyDetails.setTitle("商户缴纳保证金");
-            userMoneyDetails.setState(2);
-            userMoneyDetails.setType(1);
-            userMoneyDetails.setClassify(2);
-            userMoneyDetails.setMoney(BigDecimal.valueOf(money));
-            userMoneyDetails.setContent("商户缴纳保证金"+money+"元");
-            userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
-            userMoneyDetailsDao.insert(userMoneyDetails);
-
+            goodsShopService.updateCashDeposit(payDetails.getMoney(), payDetails.getShopId(), payDetails.getOrderId());
         }else if(payDetails.getClassify()==4){
             PayDetails payDetails1 = new PayDetails();
             payDetails1.setId(payDetails.getId());

+ 18 - 0
src/main/java/com/sqx/modules/pay/vo/AliPayTransactionsParam.java

@@ -0,0 +1,18 @@
+package com.sqx.modules.pay.vo;
+
+import lombok.Data;
+
+/**
+ * 支付宝交易参数
+ *
+ * @author : codingliang
+ * @date : 2024-11-06 19:31
+ */
+@Data
+public class AliPayTransactionsParam extends PayTransactionsVO {
+
+    /**
+     * 交易参数
+     */
+    private String body;
+}

+ 10 - 0
src/main/java/com/sqx/modules/pay/vo/PayTransactionsVO.java

@@ -0,0 +1,10 @@
+package com.sqx.modules.pay.vo;
+
+/**
+ * 交易参数基类
+ *
+ * @author : codingliang
+ * @date : 2024-11-06 19:11
+ */
+public class PayTransactionsVO {
+}

+ 53 - 0
src/main/java/com/sqx/modules/pay/vo/WechatTransactionsParamVO.java

@@ -0,0 +1,53 @@
+package com.sqx.modules.pay.vo;
+
+import lombok.Data;
+
+/**
+ * 微信交易参数
+ *
+ * @author : codingliang
+ * @date : 2024-11-05 21:42
+ */
+@Data
+public class WechatTransactionsParamVO extends PayTransactionsVO {
+    /**
+     * appId
+     */
+    private String appId;
+    /**
+     * 时间戳
+     */
+    private String timeStamp;
+    /**
+     * 随机字符串
+     */
+    private String nonceStr;
+    /**
+     * 统一下单接口返回的 prepay_id 参数值
+     */
+    private String packageStr;
+    /**
+     * 签名算法
+     */
+    private String signType;
+    /**
+     * 签名
+     */
+    private String paySign;
+    /**
+     * 商户号mchId对应的值,app支付时需要
+     */
+    private String partnerId;
+    /**
+     * 支付交易会话ID,app支付时需要
+     */
+    private String prepayId;
+    /**
+     * 支付地址,h5支付时需要
+     */
+    private String h5Url;
+    /**
+     * 支付二维码,native支付时需要
+     */
+    private String codeUrl;
+}

+ 30 - 0
src/main/java/com/sqx/modules/shop/controller/AdminShopMoneyController.java

@@ -0,0 +1,30 @@
+package com.sqx.modules.shop.controller;
+
+import com.sqx.common.utils.Result;
+import com.sqx.modules.app.service.UserMoneyService;
+import com.sqx.modules.sys.controller.AbstractController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+
+@Api(tags={"商户端-商户钱包"})
+@RestController
+@RequestMapping("admin/shop/money")
+@RequiredArgsConstructor
+public class AdminShopMoneyController extends AbstractController {
+
+    private final UserMoneyService userMoneyService;
+
+    @ApiOperation("店铺分账")
+    @PutMapping(value = "split-bill/{shopId}/{amount}")
+    public Result splitBill(@PathVariable Long shopId, @PathVariable BigDecimal amount) {
+        userMoneyService.splitBill(shopId, amount);
+        return Result.success();
+    }
+}