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