Browse Source

app商城购买,回调

xw 4 days ago
parent
commit
b723355f30

+ 17 - 0
fs-service/src/main/java/com/fs/app/AppPayService.java

@@ -0,0 +1,17 @@
+package com.fs.app;
+
+import com.fs.common.core.domain.R;
+import com.fs.his.param.FsPackageOrderDoPayParam;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+
+
+import java.util.Map;
+
+public interface AppPayService {
+
+
+    /**
+     * 微信支付回调
+     */
+    String wxNotify(WxPayOrderNotifyResult result);
+}

+ 72 - 0
fs-service/src/main/java/com/fs/app/impl/AppPayServiceImpl.java

@@ -0,0 +1,72 @@
+package com.fs.app.impl;
+
+import com.fs.app.AppPayService;
+import com.fs.his.service.IFsInquiryOrderService;
+import com.fs.his.service.IFsPackageOrderService;
+import com.fs.his.service.IFsStoreOrderService;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.system.mapper.SysConfigMapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class AppPayServiceImpl implements AppPayService {
+
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+    @Autowired
+    private IFsInquiryOrderService inquiryOrderService;
+    @Lazy
+    @Autowired
+    private IFsStoreOrderScrmService storeOrderService;
+
+    @Lazy
+    @Autowired
+    private ILiveOrderService liveOrderService;
+    @Autowired
+    private IFsPackageOrderService packageOrderService;
+
+    @Override
+    public String wxNotify(WxPayOrderNotifyResult result) {
+        log.info("微信回调参数: {}", result);
+        if (!"SUCCESS".equals(result.getReturnCode())){
+            return WxPayNotifyResponse.success("微信回调失败");
+        }
+
+        if (!"SUCCESS".equals(result.getResultCode())){
+            return WxPayNotifyResponse.success("交易失败");
+        }
+
+        String outTradeNo = result.getOutTradeNo();
+        String[] tradeNoArr = outTradeNo.split("-");
+        if (tradeNoArr.length < 2) {
+            log.info("微信回调订单号格式异常, outTradeNo: {}", outTradeNo);
+            return WxPayNotifyResponse.success("OK");
+        }
+        switch (tradeNoArr[0]) {
+            case "inquiry":
+                inquiryOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            case "store":
+                storeOrderService.payConfirm(1, null, tradeNoArr[1], outTradeNo, result.getTransactionId(), null);
+                break;
+            case "live":
+                liveOrderService.payConfirm(1, null, tradeNoArr[1], outTradeNo, result.getTransactionId(), null);
+                break;
+            case "package":
+                packageOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            default:
+                log.warn("微信回调未知订单前缀, outTradeNo: {}", outTradeNo);
+                break;
+        }
+        return WxPayNotifyResponse.success("OK");
+    }
+
+}

+ 179 - 0
fs-service/src/main/java/com/fs/company/domain/RechargeRecord.java

@@ -0,0 +1,179 @@
+package com.fs.company.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 储值支付记录对象 recharge_record
+ *
+ * @author ruoyi
+ * @date 2026-03-17
+ */
+public class RechargeRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 用户ID */
+    @Excel(name = "用户ID")
+    private Long userId;
+
+    /** 用户姓名 */
+    @Excel(name = "用户姓名")
+    private String userName;
+
+    /** 储值金额 */
+    @Excel(name = "储值金额")
+    private BigDecimal totalAmount;
+
+    /** 交易流水号 */
+    @Excel(name = "交易流水号")
+    private String transactionId;
+
+    /** 订单ID */
+    private Long orderId;
+
+    /** 订单编号 */
+    private String orderNo;
+
+    /** 业务类型:0-充值,1-消费 */
+    @Excel(name = "业务类型", readConverterExp = "0=充值,1=消费")
+    private Integer businessType;
+
+    /** 公司ID */
+    @Excel(name = "公司ID")
+    private Long companyId;
+
+    /** 公司名称 */
+    @Excel(name = "公司名称")
+    private String companyName;
+
+    /** 删除标志:0-未删除,1-已删除 */
+    private String delFlag;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+    public void setUserName(String userName)
+    {
+        this.userName = userName;
+    }
+
+    public String getUserName()
+    {
+        return userName;
+    }
+    public void setTotalAmount(BigDecimal totalAmount)
+    {
+        this.totalAmount = totalAmount;
+    }
+
+    public BigDecimal getTotalAmount()
+    {
+        return totalAmount;
+    }
+    public void setTransactionId(String transactionId)
+    {
+        this.transactionId = transactionId;
+    }
+
+    public String getTransactionId()
+    {
+        return transactionId;
+    }
+    public Integer getBusinessType()
+    {
+        return businessType;
+    }
+
+    public void setBusinessType(Integer businessType)
+    {
+        this.businessType = businessType;
+    }
+    public Long getCompanyId()
+    {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId)
+    {
+        this.companyId = companyId;
+    }
+    public String getCompanyName()
+    {
+        return companyName;
+    }
+
+    public void setCompanyName(String companyName)
+    {
+        this.companyName = companyName;
+    }
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public Long getOrderId() {
+        return orderId;
+    }
+
+    public RechargeRecord setOrderId(Long orderId) {
+        this.orderId = orderId;
+        return this;
+    }
+
+    public String getOrderNo() {
+        return orderNo;
+    }
+
+    public RechargeRecord setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("userId", getUserId())
+                .append("userName", getUserName())
+                .append("totalAmount", getTotalAmount())
+                .append("transactionId", getTransactionId())
+                .append("businessType", getBusinessType())
+                .append("companyId", getCompanyId())
+                .append("companyName", getCompanyName())
+                .append("remark", getRemark())
+                .append("createBy", getCreateBy())
+                .append("createTime", getCreateTime())
+                .append("updateBy", getUpdateBy())
+                .append("updateTime", getUpdateTime())
+                .append("delFlag", getDelFlag())
+                .toString();
+    }
+}

+ 3 - 0
fs-service/src/main/java/com/fs/his/config/AppConfig.java

@@ -72,4 +72,7 @@ public class AppConfig {
 
     //连续提现几天封控
     private BigDecimal limitAmount;
+
+    private Long tongueFlag;
+    private String appId;
 }

+ 2 - 0
fs-service/src/main/java/com/fs/his/enums/BusinessTypeEnum.java

@@ -7,6 +7,8 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum BusinessTypeEnum {
     INTEGRAL_ORDER("integral", 6, "积分商城订单支付"),
+    ORDER_ORDER("store", 8, "商城订单支付"),
+    LIVE_ORDER("live", 9, "直播订单支付"),
     ;
 
     private final String prefix;

+ 4 - 1
fs-service/src/main/java/com/fs/his/enums/PaymentMethodEnum.java

@@ -8,8 +8,11 @@ import lombok.Getter;
 public enum PaymentMethodEnum {
     MINIAPP_WECHAT("weixin"), // 小程序微信支付
     H5_WECHAT("微信"),      // H5微信支付
+    WX_APP("wx_app"),      // H5微信支付
+    T_NATIVE("t_native"),      // H5微信支付
     ALIPAY("alipay"),         // 支付宝支付
-    H5_ALIPAY("alipay");       // H5支付宝支付
+    H5_ALIPAY("alipay"),       // H5支付宝支付
+    CZ_PAY("cz_pay");       // H5支付宝支付  // H5微信支付
 
     private final String desc;
 }

+ 6 - 0
fs-service/src/main/java/com/fs/his/param/FsIntegralOrderDoPayParam.java

@@ -10,4 +10,10 @@ public class FsIntegralOrderDoPayParam {
     private Long orderId;
 
     private Long userId;
+    private String appId;
+
+    /**
+     * 商品类型
+     */
+    private String type;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -369,5 +369,8 @@ public class FsStoreOrderScrm extends BaseEntity
     // 后台修改商品类型,0-未修改过;1-总后台;2-销售后台
     private Integer backendEditProductType;
 
+    @TableField(exist = false)
+    private Boolean isLive = false;
+
 
 }

+ 6 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsUserScrm.java

@@ -19,6 +19,7 @@ import java.util.Date;
  * @author fs
  * @date 2022-03-15
  */
+@Data
 @TableName("fs_user")
 public class FsUserScrm extends BaseEntity
 {
@@ -187,6 +188,11 @@ public class FsUserScrm extends BaseEntity
      * 小程序appId,多个用逗号分隔
      */
     private String appId;
+    /**
+     * 储值金额
+     */
+    @Excel(name = "储值金额")
+    private BigDecimal rechargeBalance;
 
     public String getAppId() {
         return appId;

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -102,7 +102,7 @@ public interface FsStoreAfterSalesScrmMapper
             "<if test =\"maps.hfOrderCode != null and  maps.hfOrderCode!='' \"> " +
               "and fsps.pay_code = #{maps.hfOrderCode} " +
             "</if>" +
-            "<if test =\"maps.bankTransactionId != null and  maps.bankTransactionId!='' \"> " +
+            "<if test = 'maps.bankTransactionId != null    '> " +
               "and fsps.bank_transaction_id = #{maps.bankTransactionId} " +
             "</if>" +
             "<if test = 'maps.status != null    '> " +

+ 6 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -9,7 +9,10 @@ import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.dto.FsOrderDeliveryNoteDTO;
 import com.fs.erp.domain.ErpOrder;
 import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
+import com.fs.his.enums.PaymentMethodEnum;
+import com.fs.his.param.FsIntegralOrderDoPayParam;
 import com.fs.his.param.FsStoreOrderSalesParam;
+import com.fs.his.param.PayOrderParam;
 import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
 import com.fs.his.vo.FsPrescribeVO;
 import com.fs.his.vo.FsStoreOrderExcelVO;
@@ -23,6 +26,7 @@ import com.fs.hisStore.dto.FsStoreOrderComputeDTO;
 import com.fs.hisStore.dto.StoreOrderExpressExportDTO;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.vo.*;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.text.ParseException;
@@ -402,4 +406,6 @@ public interface IFsStoreOrderScrmService
      * @return R
      */
     R batchDeliveryAllPendingOrders(Integer shipmentType);
+
+    R payment(FsIntegralOrderDoPayParam param, PaymentMethodEnum paymentMethodEnum);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStorePaymentScrmService.java

@@ -2,6 +2,7 @@ package com.fs.hisStore.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.core.domain.R;
+import com.fs.his.param.PayOrderParam;
 import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.vo.FsStorePaymentStatisticsVO;
@@ -166,4 +167,6 @@ public interface IFsStorePaymentScrmService
      * 批量导入更新微信订单发货状态
      * **/
     R oneClickShipping();
+
+    R processPaymentScrm(PayOrderParam payOrderParam);
 }

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -631,7 +631,7 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
     }
 
     @Override
-    @DataScope(deptAlias = "cu", userAlias = "cu")
+//    @DataScope(deptAlias = "cu", userAlias = "cu")
     public List<FsStoreAfterSalesVO> selectFsStoreAfterSalesListVO(FsStoreAfterSalesScrm fsStoreAfterSales) {
         List<FsStoreAfterSalesVO> fsStoreAfterSalesVOS = fsStoreAfterSalesMapper.selectFsStoreAfterSalesListVO(fsStoreAfterSales);
         List<Long> orderIds = new ArrayList<>();

+ 527 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.hisStore.service.impl;
 
 import java.math.BigDecimal;
 
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
@@ -16,6 +17,7 @@ import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
 import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
 import cn.binarywang.wx.miniapp.bean.shop.response.WxMaOrderShippingInfoBaseResponse;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
@@ -36,6 +38,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
+import com.fs.company.domain.RechargeRecord;
 import com.fs.company.mapper.CompanyConfigMapper;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
@@ -47,24 +50,31 @@ import com.fs.course.domain.FsCourseRedPacketLog;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.service.IFsCourseRedPacketLogService;
+import com.fs.his.config.AppConfig;
 import com.fs.his.domain.*;
 import com.fs.his.domain.FsPayConfig;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserWx;
 import com.fs.his.domain.MerchantAppConfig;
+import com.fs.his.dto.PayConfigDTO;
+import com.fs.his.enums.PaymentMethodEnum;
 import com.fs.his.mapper.FsUserWxMapper;
 import com.fs.his.mapper.MerchantAppConfigMapper;
+import com.fs.his.param.PayOrderParam;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.hisStore.config.StoreConfig;
 import com.fs.hisStore.config.StoreConfig;
+import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.domain.FsUserScrm;
+import com.fs.hisStore.enums.OrderInfoEnum;
 import com.fs.hisStore.enums.StatTypeEnum;
 import com.fs.his.utils.HttpUtil;
 import com.fs.hisStore.config.StoreConfig;
 import com.fs.hisStore.enums.SysConfigEnum;
+import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
 import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.IFsStorePaymentScrmService;
@@ -73,6 +83,10 @@ import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
 import com.fs.huifuPay.service.HuiFuService;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderPayment;
+import com.fs.live.mapper.LiveOrderMapper;
+import com.fs.live.mapper.LiveOrderPaymentMapper;
 import com.fs.pay.pay.dto.WxJspayDTO;
 import com.fs.pay.service.IPayService;
 import com.fs.system.oss.CloudStorageService;
@@ -99,6 +113,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import com.hc.openapi.tool.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -128,6 +143,12 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
     Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
     private WxPayService wxPayService;
+    @Autowired
+    private FsUserWxMapper userWxMapper;
+    @Autowired
+    private LiveOrderPaymentMapper liveOrderPaymentMapper;
+//    @Autowired
+//    private RechargeRecordMapper rechargeRecordMapper;
 
     @Autowired
     private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
@@ -160,6 +181,10 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
 
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+    @Autowired
+    private FsStoreOrderScrmMapper storeOrderScrmMapper;
 
     /**
      * 查询支付明细
@@ -1398,4 +1423,506 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
             return WxShippingErrorHandler.handleExceptionError(e.getMessage(), dto.getBankTransactionId());
         }
     }
+
+
+    /**
+     * 发起支付
+     * @param payOrderParam 入参
+     * @return R
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public R processPaymentScrm( PayOrderParam payOrderParam) {
+        logger.info("发起支付 payOrderParam: {}", JSON.toJSONString(payOrderParam));
+
+        if (payOrderParam.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new CustomException("支付金额不正确");
+        }
+
+        FsUserScrm user = userService.selectFsUserById(payOrderParam.getUserId());
+        if (Objects.isNull(user)) {
+            throw new CustomException("用户不存在");
+        }
+        if (PaymentMethodEnum.CZ_PAY == payOrderParam.getPaymentMethod()) {
+            if (user.getRechargeBalance().compareTo(BigDecimal.ZERO) <= 0) {
+                throw new CustomException("余额不足!请先充值。");
+            }
+        }
+        String type = null;
+        FsPayConfig payConfig = new FsPayConfig();
+        if (PaymentMethodEnum.WX_APP == payOrderParam.getPaymentMethod()) {
+            String json = configService.selectConfigByKey("app.config");
+            AppConfig config = JSONUtil.toBean(json, AppConfig.class);
+            payOrderParam.setAppId(config.getAppId());
+            type = "wxApp";
+        }
+        //支付宝可以不需要appid(在没有appid的情况下)【ps:小程序的支付宝没传appid 就G】
+        if ((PaymentMethodEnum.ALIPAY == payOrderParam.getPaymentMethod())
+                && StringUtils.isBlank(payOrderParam.getAppId())) {
+            String json = configService.selectConfigByKey("his.pay");
+            PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+            payConfig.setType(payConfigDTO.getType());
+        }else if(!(PaymentMethodEnum.CZ_PAY == payOrderParam.getPaymentMethod())){
+            if (StringUtils.isBlank(payOrderParam.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payOrderParam.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + payOrderParam.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            payConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+            if (StringUtils.isNotEmpty(type)) {
+                payConfig.setType(type);
+            } else {
+                payConfig.setType(merchantAppConfig.getMerchantType());
+            }
+            payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
+
+            logger.debug("支付配置 his.pay: {}", payConfig);
+        }
+
+
+//        FsPayConfig payConfig = JSONUtil.toBean(json, FsPayConfig.class);
+
+        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
+            String openId = getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig);
+            if (StringUtils.isBlank(openId)) {
+                throw new CustomException("用户OPENID不存在");
+            }
+        }
+
+        FsStorePaymentScrm storePayment = new FsStorePaymentScrm();
+
+        // 1. 根据业务类型创建对应的支付对象
+        if (payOrderParam.getBusinessType().getPrefix().equals("live")) {
+            // 处理直播业务支付
+            LiveOrderPayment liveOrderPayment = createLiveStorePayment(payConfig, user, payOrderParam);
+            BeanUtils.copyProperties(liveOrderPayment, storePayment);
+
+            // 处理储值支付
+            if (isRechargePayment(payOrderParam)) {
+                return processLiveRechargePayment(liveOrderPayment, user);
+            }
+        } else {
+            // 处理商城业务支付
+            storePayment = createStorePaymentScrm(payConfig, user, payOrderParam);
+
+//            // 处理储值支付
+//            if (isRechargePayment(payOrderParam)) {
+//                return processStoreRechargePayment(storePayment, user);
+//            }
+        }
+        // 根据配置类型创建第三方支付订单
+        return createThirdPartyPaymentScrm(payConfig, storePayment, user, payOrderParam);
+    }
+
+    /**
+     * 判断是否为储值支付
+     * @param payOrderParam 支付订单参数
+     * @return true:储值支付 false:其他支付方式
+     */
+    private boolean isRechargePayment(PayOrderParam payOrderParam) {
+        return PaymentMethodEnum.CZ_PAY == payOrderParam.getPaymentMethod();
+    }
+
+    /**
+     * 处理直播储值支付
+     * @param liveOrderPayment 直播订单支付信息
+     * @param user 用户信息
+     * @return 支付处理结果
+     */
+    private R processLiveRechargePayment(LiveOrderPayment liveOrderPayment, FsUserScrm user) {
+        // 查询直播订单信息
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderId(liveOrderPayment.getBusinessId());
+        Company company = companyService.selectCompanyById(liveOrder.getCompanyId());
+
+        // 扣减用户储值余额
+        deductUserRechargeBalance(user, liveOrder.getPayMoney());
+
+        // 更新直播订单状态
+        updateLiveOrderStatus(liveOrder);
+
+        // 创建消费记录
+        return R.ok();
+    }
+
+    /**
+     * 处理商城储值支付
+     * @param storePayment 商城订单支付信息
+     * @param user 用户信息
+     * @return 支付处理结果
+     */
+    private R processStoreRechargePayment(FsStorePaymentScrm storePayment, FsUserScrm user) {
+        // 查询商城订单信息
+        FsStoreOrderScrm fsStoreOrderScrm = storeOrderScrmMapper.selectFsStoreOrderById(storePayment.getOrderId());
+        Company company = companyService.selectCompanyById(fsStoreOrderScrm.getCompanyId());
+
+        // 扣减用户储值余额
+        deductUserRechargeBalance(user, storePayment.getPayMoney());
+
+        // 更新商城订单状态
+        updateStoreOrderStatus(fsStoreOrderScrm);
+
+        // 创建消费记录
+        return R.ok();
+    }
+
+    /**
+     * 扣减用户储值余额
+     * @param user 用户信息
+     * @param amount 扣减金额
+     */
+    private void deductUserRechargeBalance(FsUserScrm user, BigDecimal amount) {
+        user.setRechargeBalance(user.getRechargeBalance().subtract(amount));
+        userService.updateFsUser(user);
+    }
+
+    /**
+     * 更新直播订单状态
+     * @param liveOrder 直播订单
+     */
+    private void updateLiveOrderStatus(LiveOrder liveOrder) {
+        liveOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
+        liveOrder.setPayTime(LocalDateTime.now());
+        liveOrder.setIsPay("1");
+        liveOrderMapper.updateLiveOrder(liveOrder);
+    }
+
+    /**
+     * 更新商城订单状态
+     * @param storeOrder 商城订单
+     */
+    private void updateStoreOrderStatus(FsStoreOrderScrm storeOrder) {
+        storeOrder.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
+        storeOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
+        storeOrder.setPayTime(new Date());
+        storeOrderScrmMapper.updateFsStoreOrder(storeOrder);
+    }
+
+
+
+    /**
+     * 订单支付成功后,增加消费记录
+     * @param orderId 订单ID
+     * @param orderNo 订单编号
+     * @param userId 用户ID
+     * @param userName 用户姓名
+     * @param amount 消费金额
+     * @return 影响行数
+     */
+//    public int createConsumptionRecord(Long orderId, String orderNo, Long userId,
+//                                       String userName, BigDecimal amount,Company company
+//    ) {
+//        RechargeRecord record = new RechargeRecord();
+//        record.setUserId(userId);
+//        record.setUserName(userName);
+//        record.setTotalAmount(amount);
+//        record.setTransactionId(generateTransactionId());
+//        record.setOrderId(orderId);
+//        record.setOrderNo(orderNo);
+//        record.setBusinessType(1); // 1-消费
+//        if (ObjectUtil.isEmpty(company)){
+//            record.setRemark("订单消费,自主下单没有归属公司");
+//        }else {
+//            record.setCompanyId(company.getCompanyId());
+//            record.setCompanyName(company.getCompanyName());
+//            record.setRemark("订单消费");
+//        }
+//        record.setCreateTime(new Date());
+//        record.setDelFlag("0");
+//
+//        return rechargeRecordMapper.insertRechargeRecord(record);
+//    }
+
+    /**
+     * 生成交易流水号
+     * @return 交易流水号
+     */
+    private String generateTransactionId() {
+        return "TXF" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
+    }
+    /**
+     * 直播订单支付信息
+     *
+     * @param payConfig
+     * @param user
+     * @param payOrderParam
+     * @return
+     */
+    private LiveOrderPayment createLiveStorePayment(FsPayConfig payConfig, FsUserScrm user, PayOrderParam payOrderParam) {
+        String payCode = OrderCodeUtils.getOrderSn();
+        if (StringUtils.isEmpty(payCode)) {
+            throw new CustomException("订单生成失败,请重试");
+        }
+
+        LiveOrderPayment storePayment = new LiveOrderPayment();
+
+        if (PaymentMethodEnum.CZ_PAY == payOrderParam.getPaymentMethod()){
+            storePayment.setStatus(1);
+            storePayment.setPayMode("cz");
+        }else {
+            storePayment.setStatus(0);
+            storePayment.setPayMode(payConfig.getType());
+        }
+        storePayment.setAppId(payConfig.getAppId());
+        storePayment.setBusinessCode(payOrderParam.getOrderCode());
+        storePayment.setPayCode(payCode);
+        storePayment.setPayMoney(payOrderParam.getAmount());
+        storePayment.setCreateTime(new Date());
+        storePayment.setPayTypeCode(payOrderParam.getPaymentMethod().getDesc());
+        storePayment.setBusinessType(payOrderParam.getBusinessType().getCode());
+        storePayment.setCompanyId(payOrderParam.getCompanyId());
+        storePayment.setCompanyUserId(payOrderParam.getCompanyUserId());
+        storePayment.setRemark(payOrderParam.getBusinessType().getDesc());
+        storePayment.setStoreId(payOrderParam.getStoreId());
+        storePayment.setUserId(user.getUserId());
+        storePayment.setBusinessId(payOrderParam.getOrderId().toString());
+
+        // 设置openId(如果是微信支付)
+        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
+            storePayment.setOpenId(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
+        }
+
+        if (liveOrderPaymentMapper.insertLiveOrderPayment(storePayment) <= 0) {
+            throw new CustomException("支付订单创建失败");
+        }
+
+        return storePayment;
+    }
+
+    /**
+     * 判断是否微信支付
+     * @param method 支付类型
+     * @return boolean
+     */
+    private boolean isWechatPayment(PaymentMethodEnum method) {
+        return method == PaymentMethodEnum.MINIAPP_WECHAT || method == PaymentMethodEnum.H5_WECHAT;
+    }
+
+    /**
+     * 根据支付方式获取对应的openId
+     */
+    private String getOpenIdForPaymentMethod(FsUserScrm user, PaymentMethodEnum method, FsPayConfig payConfig) {
+        String openId;
+        switch (method) {
+            case MINIAPP_WECHAT:
+                openId = user.getMaOpenId();
+                break;
+            case H5_WECHAT:
+                openId = user.getMpOpenId();
+                break;
+            default:
+                openId = null;
+        }
+
+        if (StringUtils.isBlank(openId)) {
+            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                    .eq(FsUserWx::getFsUserId, user.getUserId())
+                    .eq(FsUserWx::getAppId, payConfig.getAppId());
+            FsUserWx fsUserWx = userWxMapper.selectOne(queryWrapper);
+            if (Objects.nonNull(fsUserWx)) {
+                openId = fsUserWx.getOpenId();
+            }
+        }
+
+        return openId;
+    }
+
+    /**
+     * 发起预支付
+     */
+    private R createThirdPartyPaymentScrm(FsPayConfig payConfig, FsStorePaymentScrm storePayment, FsUserScrm user, PayOrderParam payOrderParam) {
+        switch (payConfig.getType()) {
+            case "wx":
+                return createWxPayment(storePayment, user, payOrderParam, payConfig);
+            case "wxApp":
+                return createWxAppPayment(storePayment, user, payOrderParam, payConfig);
+            case "hf":
+                return createHfPayment(storePayment, user, payOrderParam, payConfig);
+            default:
+                throw new CustomException("不支持的支付方式");
+        }
+    }
+
+    /**
+     * 汇付
+     */
+    private R createHfPayment(FsStorePaymentScrm storePayment, FsUserScrm user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
+        logger.debug("创建汇付订单");
+
+        HuiFuCreateOrder order = new HuiFuCreateOrder();
+        order.setTradeType(getHfTradeType(payOrderParam.getPaymentMethod()));
+        order.setReqSeqId(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
+        order.setTransAmt(storePayment.getPayMoney().toString());
+        order.setGoodsDesc(payOrderParam.getBusinessType().getDesc());
+
+        // 微信支付需要设置openid
+        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
+            order.setOpenid(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
+        }
+
+        HuifuCreateOrderResult result = huiFuService.createOrder(order);
+        logger.debug("汇付支付创建结果: {}", result);
+
+        updateStorePaymentTradeNo(storePayment.getPaymentId(), result.getHf_seq_id());
+        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
+    }
+
+    /**
+     * 获取汇付交易类型
+     */
+    private String getHfTradeType(PaymentMethodEnum paymentMethod) {
+        switch (paymentMethod) {
+            case MINIAPP_WECHAT:
+                return "T_MINIAPP";
+            case H5_WECHAT:
+                return "T_JSAPI";
+            case ALIPAY:
+            case H5_ALIPAY:
+                return "A_NATIVE";
+            case T_NATIVE:
+                return "T_NATIVE";
+            default:
+                throw new CustomException("不支持的支付方式");
+        }
+    }
+
+    /**
+     * 更新支付订单交易号
+     */
+    private void updateStorePaymentTradeNo(Long paymentId, String tradeNo) {
+        FsStorePaymentScrm updatePayment = new FsStorePaymentScrm();
+        updatePayment.setPaymentId(paymentId);
+        updatePayment.setTradeNo(tradeNo);
+        fsStorePaymentMapper.updateFsStorePayment(updatePayment);
+    }
+
+
+    /**
+     * 微信支付
+     */
+    private R createWxPayment(FsStorePaymentScrm storePayment, FsUserScrm user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
+        PaymentMethodEnum paymentMethod = payOrderParam.getPaymentMethod();
+        if (paymentMethod != PaymentMethodEnum.MINIAPP_WECHAT) {
+            logger.debug("微信支付 PaymentMethod: {}", paymentMethod.name());
+            throw new CustomException("不支持的支付方式");
+        }
+
+        WxPayConfig wxPayConfig = buildWxPayConfig(payConfig);
+        wxPayService.setConfig(wxPayConfig);
+
+        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+        orderRequest.setOpenid(getOpenIdForPaymentMethod(user, paymentMethod, payConfig));
+        orderRequest.setBody(payOrderParam.getBusinessType().getDesc());
+        orderRequest.setOutTradeNo(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
+        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+        orderRequest.setTradeType("JSAPI");
+        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+
+        try {
+            WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
+            return R.ok().put("data", orderResult).put("type", "wx").put("isPay", 0);
+        } catch (WxPayException e) {
+            logger.error("微信支付发起失败: {}", e.getMessage(), e);
+            throw new CustomException("支付失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 微信App支付
+     */
+    private R createWxAppPayment(FsStorePaymentScrm storePayment, FsUserScrm user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
+        //创建微信订单
+        WxPayConfig wxPayConfig = buildWxPayConfig(payConfig);
+
+        wxPayConfig.setAppId(wxPayConfig.getAppId());
+        wxPayConfig.setMchId(wxPayConfig.getMchId());
+        wxPayConfig.setMchKey(wxPayConfig.getMchKey());
+        wxPayConfig.setSubAppId(StringUtils.trimToNull(null));
+        wxPayConfig.setSubMchId(StringUtils.trimToNull(null));
+        wxPayConfig.setKeyPath(null);
+        wxPayConfig.setNotifyUrl(wxPayConfig.getNotifyUrl());
+        wxPayService.setConfig(wxPayConfig);
+        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+        orderRequest.setBody(payOrderParam.getBusinessType().getDesc());
+        orderRequest.setOutTradeNo(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
+        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+        orderRequest.setTradeType("APP");
+        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+        orderRequest.setNotifyUrl(wxPayConfig.getNotifyUrl());
+        //调用统一下单接口,获取"预支付交易会话标识"
+        try {
+            Object result = wxPayService.createOrder(orderRequest);
+            return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+        } catch (WxPayException e) {
+            e.printStackTrace();
+            throw new CustomException("支付失败"+e.getMessage());
+        }
+    }
+
+    /**
+     * 构建微信支付配置
+     */
+    private WxPayConfig buildWxPayConfig(FsPayConfig fsPayConfig) {
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(StringUtils.trimToNull(fsPayConfig.getAppId()));
+        payConfig.setMchId(StringUtils.trimToNull(fsPayConfig.getWxMchId()));
+        payConfig.setMchKey(StringUtils.trimToNull(fsPayConfig.getWxMchKey()));
+        payConfig.setSubAppId(StringUtils.trimToNull(null));
+        payConfig.setSubMchId(StringUtils.trimToNull(null));
+        payConfig.setKeyPath(null);
+        payConfig.setNotifyUrl(StringUtils.trimToNull(fsPayConfig.getNotifyUrlScrm()));
+        return payConfig;
+    }
+
+
+    /**
+     * 创建支付订单
+     */
+    private FsStorePaymentScrm createStorePaymentScrm(FsPayConfig payConfig, FsUserScrm user, PayOrderParam payOrderParam) {
+        String payCode = OrderCodeUtils.getOrderSn();
+        if (StringUtils.isEmpty(payCode)) {
+            throw new CustomException("订单生成失败,请重试");
+        }
+
+        FsStorePaymentScrm storePayment = new FsStorePaymentScrm();
+        if (PaymentMethodEnum.CZ_PAY == payOrderParam.getPaymentMethod()){
+            storePayment.setStatus(1);
+            storePayment.setPayMode("cz");
+        }else {
+            storePayment.setStatus(0);
+            storePayment.setPayMode(payConfig.getType());
+        }
+        storePayment.setAppId(payConfig.getAppId());
+        storePayment.setOrderId(payOrderParam.getOrderId());
+        storePayment.setBusinessCode(payOrderParam.getOrderCode());
+        storePayment.setPayCode(payCode);
+        storePayment.setPayMoney(payOrderParam.getAmount());
+        storePayment.setCreateTime(new Date());
+        storePayment.setPayTypeCode(payOrderParam.getPaymentMethod().getDesc());
+        storePayment.setBusinessType(payOrderParam.getBusinessType().getCode());
+        storePayment.setCompanyId(payOrderParam.getCompanyId());
+        storePayment.setCompanyUserId(payOrderParam.getCompanyUserId());
+        storePayment.setRemark(payOrderParam.getBusinessType().getDesc());
+        storePayment.setStoreId(payOrderParam.getStoreId());
+        storePayment.setUserId(user.getUserId());
+        storePayment.setBusinessId(payOrderParam.getOrderId().toString());
+
+        // 设置openId(如果是微信支付)
+        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
+            storePayment.setOpenId(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
+        }
+
+        if (fsStorePaymentMapper.insertFsStorePayment(storePayment) <= 0) {
+            throw new CustomException("支付订单创建失败");
+        }
+
+        return storePayment;
+    }
 }

+ 84 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppPayController.java

@@ -0,0 +1,84 @@
+package com.fs.app.controller;
+
+
+import cn.hutool.json.JSONUtil;
+import com.fs.app.AppPayService;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.service.IFsCoursePlaySourceConfigService;
+import com.fs.his.config.AppConfig;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.his.domain.MerchantAppConfig;
+import com.fs.his.service.IMerchantAppConfigService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.google.gson.Gson;
+import com.hc.openapi.tool.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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 javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+@Slf4j
+@Api("app支付接口")
+@RestController
+@RequestMapping("/appPay")
+public class AppPayController extends AppBaseController {
+
+    @Autowired
+    private AppPayService appPayService;
+
+    @Autowired
+    private IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
+   @Autowired
+    private IMerchantAppConfigService merchantAppConfigService;
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+
+
+    @ApiOperation("微信支付回调")
+    @PostMapping("/wxNotify")
+    public String wxNotify(@RequestBody String xmlData) throws WxPayException {
+        WxPayService payService = getWxPayService();
+        WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlData);
+        return appPayService.wxNotify(result);
+    }
+
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("app.config");
+        AppConfig config = new Gson().fromJson(sysConfig.getConfigValue(), AppConfig.class);
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigService.selectCoursePlaySourceConfigByAppId(config.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + config.getAppId());
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigService.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig payConfig1 = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(payConfig1.getAppId());
+        payConfig.setMchId(payConfig1.getWxMchId());
+        payConfig.setMchKey(payConfig1.getWxMchKey());
+        payConfig.setSubAppId(StringUtils.trimToNull(null));
+        payConfig.setSubMchId(StringUtils.trimToNull(null));
+        payConfig.setKeyPath(null);
+        payConfig.setNotifyUrl(payConfig1.getNotifyUrlScrm());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+}

+ 51 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/AppController.java

@@ -0,0 +1,51 @@
+package com.fs.app.controller.store;
+
+import com.fs.app.annotation.Login;
+import com.fs.app.controller.AppBaseController;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.R;
+import com.fs.his.enums.PaymentMethodEnum;
+import com.fs.his.param.FsIntegralOrderDoPayParam;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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;
+
+
+
+
+@Api("app登录接口")
+@RestController
+@RequestMapping(value = "/app/api")
+@Slf4j
+public class AppController extends AppBaseController {
+
+    @Autowired
+    private IFsStoreOrderScrmService fsStoreOrderScrmService;
+
+
+    @Login
+    @RepeatSubmit
+    @ApiOperation("微信支付")
+    @PostMapping("/wxPayment")
+    public R wxPayment(@Validated @RequestBody FsIntegralOrderDoPayParam param) {
+        param.setUserId(Long.parseLong(getUserId()));
+        return fsStoreOrderScrmService.payment(param, PaymentMethodEnum.WX_APP);
+    }
+
+
+    @Login
+    @RepeatSubmit
+    @ApiOperation("支付宝支付")
+    @PostMapping("/aliPayment")
+    public R aliPayment(@Validated @RequestBody FsIntegralOrderDoPayParam param) {
+        param.setUserId(Long.parseLong(getUserId()));
+        return fsStoreOrderScrmService.payment(param, PaymentMethodEnum.ALIPAY);
+    }
+}