From a7359ca2d8337b0796e36f3a3722790647bd7c62 Mon Sep 17 00:00:00 2001
From: zhanglin <852614290@qq.com>
Date: 星期日, 23 七月 2023 16:04:10 +0800
Subject: [PATCH] 微信支付,支付与结果通知

---
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java |  297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 281 insertions(+), 16 deletions(-)

diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java
index 97aeb2d..70fd562 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/order/OrderServiceImpl.java
@@ -13,7 +13,9 @@
 import com.ruoyi.common.security.utils.CodeFactoryUtil;
 import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.order.domain.dto.*;
+import com.ruoyi.order.domain.pojo.account.OrderPayment;
 import com.ruoyi.order.domain.pojo.account.OrderRefund;
+import com.ruoyi.order.domain.pojo.account.PaymentMessage;
 import com.ruoyi.order.domain.pojo.order.ConsumerGoods;
 import com.ruoyi.order.domain.pojo.order.Order;
 import com.ruoyi.order.domain.pojo.order.OrderGoods;
@@ -24,6 +26,9 @@
 import com.ruoyi.order.service.order.OrderGoodsService;
 import com.ruoyi.order.service.order.OrderService;
 import com.ruoyi.order.service.order.UserServiceRecordService;
+import com.ruoyi.order.tools.request.ecommerce.profitsharing.ProfitSharingApplyRequest;
+import com.ruoyi.order.tools.request.pay.combine.CombineTransactionsJsRequest;
+import com.ruoyi.order.tools.service.ProfitsSharingService;
 import com.ruoyi.system.api.constant.AppErrorConstant;
 import com.ruoyi.system.api.constant.DelayTaskEnum;
 import com.ruoyi.system.api.constant.SecurityConstant;
@@ -39,6 +44,9 @@
 import com.ruoyi.system.api.domain.poji.sys.SysUser;
 import com.ruoyi.system.api.domain.vo.*;
 import com.ruoyi.system.api.service.*;
+import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
+import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
+import com.wechat.pay.java.service.payments.jsapi.model.*;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,6 +60,10 @@
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAConfig;
+import com.wechat.pay.java.service.payments.jsapi.JsapiService;
 
 /**
  * <p>
@@ -106,8 +118,28 @@
     @Resource
     private RedisService redisService;
 
+    @Resource
+    private ProfitsSharingService profitsSharingService;
+
     @Autowired
     private RedissonClient redissonClient;
+
+    /** 商户号 */
+    public static String merchantId = "";
+    /** 商户API私钥路径 */
+    public static String privateKeyPath = "";
+    /** 商户证书序列号 */
+    public static String merchantSerialNumber = "";
+    /** 微信支付平台证书路径 */
+    public static String wechatPayCertificatePath = "";
+    /** 微信支付 APIv3 密钥 */
+    public static String apiV3Key = "";
+    /** 微信支付APPID */
+    public static String appId="";
+    /** 微信支付商户ID */
+    public static String mchId="";
+    /** 通知地址 */
+    public static String notifyUrl="";
 
     /**
      * @description: buyGoods
@@ -126,6 +158,20 @@
         AppSureOrderGoodsVo appSureOrderGoodsVo;
         // 获取购买商品列表
         List<AppBuyGoodsDto> appBuyGoodsDtoList = appSureOrderDto.getAppBuyGoodsDtoList();
+        //获取商品列表
+        StringJoiner goodsIdSJ = new StringJoiner(",");
+        for (AppBuyGoodsDto appBuyGoodsDto : appBuyGoodsDtoList) {
+            goodsIdSJ.add(appBuyGoodsDto.getGoodsId());
+        }
+        List<Goods> goodsList = remoteGoodsService.listGoodsByGoodsId(goodsIdSJ.toString()).getData();
+        Map<String, Goods> goodsMap = goodsList.stream()
+                .collect(Collectors.toMap(Goods::getGoodsId, Function.identity()));
+        Boolean haveDeposit = false;
+        for(Goods goods : goodsList){
+            if(goods.getSubscription()!=null&&goods.getSubscription().compareTo(BigDecimal.ZERO)>0){
+                haveDeposit = true;
+            }
+        }
         String goodsId;
         Integer buyNum;
         BigDecimal buyNumBig;
@@ -134,8 +180,11 @@
         BigDecimal goodsPrice;
         BigDecimal goodsTotalPrice;
         BigDecimal goodsRealPrice;
+        MerBaseDto merBaseDto = new MerBaseDto();
+        merBaseDto.setUserId(userId);
+        merBaseDto.setShopId(appSureOrderDto.getShopId());
         // 获取用户优惠券列表
-        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(userId).getData();
+        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(merBaseDto).getData();
         // 初始化商品优惠券列表
         List<AppMemberCouponVo> appGoodsMemberCouponVoList;
         // 将优惠券列表转换为Map,以优惠券ID为键
@@ -163,7 +212,7 @@
             buyNum = appBuyGoodsDto.getBuyNum();
             memberCouponId = appBuyGoodsDto.getMemberCouponId();
             // 获取商品信息
-            goods = remoteGoodsService.getGoods(goodsId).getData();
+            goods = goodsMap.get(goodsId);
             if(goods.getGoodsStatus()!=1){
                 throw new ServiceException(AppErrorConstant.GOODS_DOWN);
             }
@@ -230,8 +279,16 @@
             appSureOrderGoodsVo.setCouponDiscount(discountMoney);
             appSureOrderGoodsVo.setGoodsRealPrice(goodsRealPrice);
             goodsDeposit = goods.getSubscription();
-            if (goodsDeposit == null) {
-                goodsDeposit = new BigDecimal("0.00");
+            // 获取商品押金
+            goodsDeposit = goods.getSubscription();
+            if (goodsDeposit != null && goodsDeposit.compareTo(BigDecimal.ZERO)>0) {
+                goodsDeposit = goodsDeposit.multiply(buyNumBig);
+            }else{
+                if(haveDeposit){
+                    goodsDeposit = goodsRealPrice;
+                }else{
+                    goodsDeposit = new BigDecimal("0.00");
+                }
             }
             appSureOrderGoodsVo.setGoodsDeposit(goodsDeposit);
             // 计算订单总金额
@@ -384,8 +441,10 @@
         appPanicBuyVo.setGoodsTotalPrice(goodsTotalPrice);
         appPanicBuyVo.setGoodsRealPrice(goodsRealPrice);
         goodsDeposit = activityGoodsGetVo.getActivitySubscription();
-        if (goodsDeposit == null) {
+        if (goodsDeposit == null || goodsDeposit.compareTo(BigDecimal.ZERO)==0) {
             goodsDeposit = new BigDecimal("0.00");
+        }else{
+            goodsDeposit = goodsDeposit.multiply(buyNumBig);
         }
         appPanicBuyVo.setGoodsDeposit(goodsDeposit);
         orderGoodsMoney = orderGoodsMoney.add(goodsTotalPrice);
@@ -414,6 +473,20 @@
         AppSureOrderGoodsVo appSureOrderGoodsVo;
         // 获取购买的商品列表
         List<AppBuyGoodsDto> appBuyGoodsDtoList = appPlaceOrderDto.getAppBuyGoodsDtoList();
+        StringJoiner goodsIdSJ = new StringJoiner(",");
+        for (AppBuyGoodsDto appBuyGoodsDto : appBuyGoodsDtoList) {
+            goodsIdSJ.add(appBuyGoodsDto.getGoodsId());
+        }
+        //获取商品列表
+        List<Goods> goodsList = remoteGoodsService.listGoodsByGoodsId(goodsIdSJ.toString()).getData();
+        Map<String, Goods> goodsMap = goodsList.stream()
+                .collect(Collectors.toMap(Goods::getGoodsId, Function.identity()));
+        Boolean haveDeposit = false;
+        for(Goods goods : goodsList){
+            if(goods.getSubscription()!=null&&goods.getSubscription().compareTo(BigDecimal.ZERO)>0){
+                haveDeposit = true;
+            }
+        }
         // 初始化变量
         String goodsId;
         Integer buyNum;
@@ -426,8 +499,11 @@
         BigDecimal goodsPrice;
         BigDecimal goodsTotalPrice;
         BigDecimal goodsRealPrice;
+        MerBaseDto merBaseDto = new MerBaseDto();
+        merBaseDto.setUserId(userId);
+        merBaseDto.setShopId(appPlaceOrderDto.getShopId());
         // 获取用户优惠券列表
-        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(userId).getData();
+        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(merBaseDto).getData();
         // 将用户优惠券列表转换为Map,方便后续查找
         Map<String, AppMemberCouponVo> appMemberCouponVoMap = appMemberCouponVoList.stream().collect(Collectors.toMap(AppMemberCouponVo::getMemberCouponId, Function.identity()));
         AppMemberCouponVo appMemberCouponVo;
@@ -458,7 +534,7 @@
             goodsId = appBuyGoodsDto.getGoodsId();
             memberCouponId = appBuyGoodsDto.getMemberCouponId();
             // 获取商品信息
-            goods = remoteGoodsService.getGoods(goodsId).getData();
+            goods = goodsMap.get(goodsId);
             // 设置商品信息
             appSureOrderGoodsVo.setGoodsId(goodsId);
             appSureOrderGoodsVo.setGoodsName(goods.getGoodsName());
@@ -521,8 +597,14 @@
             appSureOrderGoodsVo.setGoodsRealPrice(goodsRealPrice);
             // 获取商品押金
             goodsDeposit = goods.getSubscription();
-            if (goodsDeposit == null) {
-                goodsDeposit = new BigDecimal("0.00");
+            if (goodsDeposit != null && goodsDeposit.compareTo(BigDecimal.ZERO)>0) {
+                goodsDeposit = goodsDeposit.multiply(buyNumBig);
+            }else{
+                if(haveDeposit){
+                    goodsDeposit = goodsRealPrice;
+                }else{
+                    goodsDeposit = new BigDecimal("0.00");
+                }
             }
             appSureOrderGoodsVo.setGoodsDeposit(goodsDeposit);
             // 计算商品总数量、商品总价、优惠总金额、支付押金、支付金额
@@ -614,7 +696,45 @@
         appPlaceOrderVo.setOrderId(orderId);
         appPlaceOrderVo.setOrderNo(orderNo);
         // 调用支付
-        //使用优惠券
+       /* CombineTransactionsJsRequest request=new CombineTransactionsJsRequest();
+        request.setCombineAppid();
+        request.setCombineMchid();
+        profitsSharingService.combineTransactions(request);*/
+
+       //构建预下单支付对象
+        PrepayRequest request = new PrepayRequest();
+        Amount amount = new Amount();
+        amount.setTotal(Integer.parseInt(order.getPayMoney().multiply(new BigDecimal(100)).toString()));
+        request.setAmount(amount);
+        request.setAppid(this.appId);
+        request.setMchid(this.mchId);
+        request.setDescription(order.getGoodsInfo());
+        request.setNotifyUrl(this.notifyUrl);
+        request.setOutTradeNo(order.getOrderId());
+        Payer payer = new Payer();        payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********");
+
+        request.setPayer(payer);
+
+        //设置订单允许分账 秒杀活动才允许分账
+       /* if(order.getOrderFrom()==2){
+            SettleInfo settleInfo=new SettleInfo();
+            settleInfo.setProfitSharing(true);
+            request.setSettleInfo(settleInfo);
+        }*/
+
+
+        //返回前端唤醒支付结果信息
+        PrepayWithRequestPaymentResponse res = this.getJsApIResponse(request);
+
+        appPlaceOrderVo.setAppId(this.appId);
+        appPlaceOrderVo.setTimeStamp(res.getTimeStamp());
+        appPlaceOrderVo.setNonceStr(res.getNonceStr());
+        appPlaceOrderVo.setPackageStr(res.getPackageVal());
+        appPlaceOrderVo.setTradeType(res.getSignType());
+        appPlaceOrderVo.setPaySign(res.getPaySign());
+
+
+        //减去优惠券
         if(memberCouponSJ!=null){
             remoteCouponService.useMemberCoupon(memberCouponSJ.toString());
         }
@@ -632,6 +752,79 @@
         remoteConfigService.addDelayTask(delayTask);
         return appPlaceOrderVo;
     }
+
+    /**
+     *
+     * 功能描述: 预下单,返回支付数据prePayId
+     *
+     * 构建对象参考
+     *     PrepayRequest request = new PrepayRequest();
+     *     Amount amount = new Amount();
+     *     amount.setTotal(100);
+     *     request.setAmount(amount);
+     *     request.setAppid("wxa9d9651ae******");
+     *     request.setMchid("190000****");
+     *     request.setDescription("测试商品标题");
+     *     request.setNotifyUrl("https://notify_url");
+     *     request.setOutTradeNo("out_trade_no_001");
+     *     Payer payer = new Payer();
+     *     payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********");
+     *     request.setPayer(payer);
+     *
+     * @auther: linqingsong
+     * @date: 2023/7/22 16:13
+     */
+    /*public String getPrePayId(PrepayRequest request) {
+        Config config =
+                new RSAConfig.Builder()
+                        .merchantId(merchantId)
+                        .privateKeyFromPath(privateKeyPath)
+                        .merchantSerialNumber(merchantSerialNumber)
+                        .wechatPayCertificatesFromPath(wechatPayCertificatePath)
+                        .build();
+        JsapiService service = new JsapiService.Builder().config(config).build();
+        PrepayResponse response = service.prepay(request);
+        return response.getPrepayId();
+    }*/
+
+
+    /**
+     *
+     * 功能描述: 预下单,并返回前端需要换起支付的字符串
+     *
+     * 构建对象参考
+     *      *     PrepayRequest request = new PrepayRequest();
+     *      *     Amount amount = new Amount();
+     *      *     amount.setTotal(100);
+     *      *     request.setAmount(amount);
+     *      *     request.setAppid("wxa9d9651ae******");
+     *      *     request.setMchid("190000****");
+     *      *     request.setDescription("测试商品标题");
+     *      *     request.setNotifyUrl("https://notify_url");
+     *      *     request.setOutTradeNo("out_trade_no_001");
+     *      *     Payer payer = new Payer();
+     *      *     payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********");
+     *      *     request.setPayer(payer);
+     *
+     *
+     * @auther: linqingsong
+     * @date: 2023/7/22 16:53
+     */
+    public PrepayWithRequestPaymentResponse getJsApIResponse(PrepayRequest request){
+        Config config =
+                new RSAConfig.Builder()
+                        .merchantId(merchantId)
+                        .privateKeyFromPath(privateKeyPath)
+                        .merchantSerialNumber(merchantSerialNumber)
+                        .wechatPayCertificatesFromPath(wechatPayCertificatePath)
+                        .build();
+        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
+
+        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
+
+        return response;
+    }
+
 
     /**
      * @param appPlaceActivityDto
@@ -711,6 +904,7 @@
         String orderGoodsId;
         // 创建商品类型集合
         HashSet<String> goodsTypeSet = new HashSet<>();
+        HashSet<String> goodsNurseSet = new HashSet<>();
         // 创建商品订单对象,并设置商品ID,商品名称,商品介绍,商品类型
         appSureOrderGoodsVo = new AppSureOrderGoodsVo();
         useCoupon = 0;
@@ -741,8 +935,10 @@
         appSureOrderGoodsVo.setGoodsRealPrice(goodsRealPrice);
         // 获取商品押金
         goodsDeposit = activityGoodsGetVo.getActivitySubscription();
-        if (goodsDeposit == null) {
+        if (goodsDeposit == null || goodsDeposit.compareTo(BigDecimal.ZERO)==0) {
             goodsDeposit = new BigDecimal("0.00");
+        }else{
+            goodsDeposit = goodsDeposit.multiply(buyNumBig);
         }
         appSureOrderGoodsVo.setGoodsDeposit(goodsDeposit);
         // 计算商品数量,订单商品金额,优惠券折扣,订单支付押金,订单支付金额
@@ -785,6 +981,13 @@
         } else if (goods.getGoodsType() == 4) {
             goodsTypeSet.add("单品");
         }
+        String goodsNurse = goods.getGoodsNurses();
+        if(StringUtils.isNotBlank(goodsNurse)){
+            String[] goodsNurseArr = goodsNurse.split(",");
+            for(String str : goodsNurseArr){
+                goodsNurseSet.add(str);
+            }
+        }
         // 创建订单,并设置订单ID,删除标志,订单状态,订单号,订单来源,店铺ID,用户ID,订单金额,优惠券金额,折扣金额,应收金额,应收押金,变动应收金额,支付类型
         Order order = new Order();
         order.setOrderId(orderId);
@@ -822,10 +1025,11 @@
         // 保存订单
         this.save(order);
         // 更新用户商品类型
-        if (goodsTypeSet != null && goodsTypeSet.size() > 0) {
+        if (goodsTypeSet != null || goodsNurseSet!= null) {
             AppMemberGoodsTypeDto appMemberGoodsTypeDto = new AppMemberGoodsTypeDto();
             appMemberGoodsTypeDto.setUserId(userId);
             appMemberGoodsTypeDto.setGoodsTypeSet(goodsTypeSet);
+            appMemberGoodsTypeDto.setGoodsNurseSet(goodsNurseSet);
             remoteMemberService.updateMemberGoodsType(appMemberGoodsTypeDto);
         }
         // 设置订单ID和订单号
@@ -841,6 +1045,40 @@
         agStockChangeDto.setUserId(order.getUserId());
         remoteActivityService.changeActivityStock(agStockChangeDto);
         // 调用支付
+        PrepayRequest request = new PrepayRequest();
+        Amount amount = new Amount();
+        amount.setTotal(Integer.parseInt(order.getPayMoney().multiply(new BigDecimal(100)).toString()));
+        request.setAmount(amount);
+        request.setAppid(this.appId);
+        request.setMchid(this.mchId);
+        request.setDescription(order.getGoodsInfo());
+        request.setNotifyUrl(this.notifyUrl);
+        request.setOutTradeNo(order.getOrderId());
+        Payer payer = new Payer();
+        // TODO 获取openID
+        payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********");
+
+        request.setPayer(payer);
+
+        //设置订单允许分账 秒杀活动才允许分账
+        if(order.getOrderFrom()==2){
+            SettleInfo settleInfo=new SettleInfo();
+            settleInfo.setProfitSharing(true);
+            request.setSettleInfo(settleInfo);
+        }
+
+
+        //返回前端唤醒支付结果信息
+        PrepayWithRequestPaymentResponse res = this.getJsApIResponse(request);
+
+        appPlaceOrderVo.setAppId(this.appId);
+        appPlaceOrderVo.setTimeStamp(res.getTimeStamp());
+        appPlaceOrderVo.setNonceStr(res.getNonceStr());
+        appPlaceOrderVo.setPackageStr(res.getPackageVal());
+        appPlaceOrderVo.setTradeType(res.getSignType());
+        appPlaceOrderVo.setPaySign(res.getPaySign());
+
+
         //生成自动取消订单延时任务
         Integer delayTime = 30;
         if(redisService.hasKey(SecurityConstant.AUTO_CANCEL_ORDER_TIME)){
@@ -1109,7 +1347,13 @@
         SysUser sysUser = remoteUserService.getSysUser(order.getUserId()).getData();
         merVerifyOrderVo.setUserName(sysUser.getNickName());
         merVerifyOrderVo.setUserMobile(sysUser.getPhonenumber());
+        //
+        if(order.getOrderFrom()==2){
+
+            //profitsSharingService.applyProfitSharing();
+        }
         return merVerifyOrderVo;
+
     }
 
     /**
@@ -1381,7 +1625,10 @@
         BigDecimal goodsRealPrice;
         Long shopId = merNewOrderDto.getShopId();
         Shop shop = remoteShopService.getShop(shopId).getData();
-        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(userId).getData();
+        MerBaseDto merBaseDto = new MerBaseDto();
+        merBaseDto.setUserId(userId);
+        merBaseDto.setShopId(shopId);
+        List<AppMemberCouponVo> appMemberCouponVoList = remoteCouponService.listVoMemberCouponByUserId(merBaseDto).getData();
         Map<String, AppMemberCouponVo> appMemberCouponVoMap = new HashMap<>();
         if (null != appMemberCouponVoList) {
             appMemberCouponVoMap = appMemberCouponVoList.stream().collect(Collectors.toMap(AppMemberCouponVo::getMemberCouponId, Function.identity()));
@@ -1448,8 +1695,10 @@
             }
 
             goodsDeposit = goods.getSubscription();
-            if (goodsDeposit == null) {
+            if (goodsDeposit == null || goodsDeposit.compareTo(BigDecimal.ZERO)==0) {
                 goodsDeposit = new BigDecimal("0.00");
+            }else{
+                goodsDeposit = goodsDeposit.multiply(buyNumBig);
             }
             goodsNum = goodsNum + buyNum;
             orderGoodsMoney = orderGoodsMoney.add(goodsTotalPrice);
@@ -3006,12 +3255,13 @@
      * @description  订单支付回调
      * @author  jqs
      * @date    2023/7/13 17:57
-     * @param orderId
+     * @param Transaction
      * @return  void
      */
     @Override
-    public void payBack(String orderId) {
+    public void payBack(Transaction transaction) {
         // 更新订单状态
+        String orderId=transaction.getOutTradeNo();
         Order order = this.getById(orderId);
         order.setOrderStatus(2);
         order.setPayTime(new Date());
@@ -3105,7 +3355,22 @@
             }
             activityTotalChangeDto.setUserId(order.getUserId());
             remoteActivityService.changeActivityTotal(activityTotalChangeDto);
+
+
+            //活动订单进行分账
+            ProfitSharingApplyRequest request=new ProfitSharingApplyRequest();
+            request.setAppid(this.appId);
+            request.setSubMchid("");
+            request.setTransactionId(transaction.getTransactionId());
+            profitsSharingService.applyProfitSharing(request);
         }
+        //生成支付记录
+        OrderPayment orderPayment = new OrderPayment();
+
+
+
+
+
     }
 
     /**

--
Gitblit v1.7.1