From 513961ecebcfd0619ede7a7edb7ac5e27de28d26 Mon Sep 17 00:00:00 2001
From: Pu Zhibing <393733352@qq.com>
Date: 星期三, 01 一月 2025 17:11:23 +0800
Subject: [PATCH] 增加第三方支付

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java |  217 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 204 insertions(+), 13 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
index e533c48..0ad64c1 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
@@ -19,12 +19,18 @@
 import com.ruoyi.order.model.OrderGood;
 import com.ruoyi.order.model.ShoppingCart;
 import com.ruoyi.order.service.*;
+import com.ruoyi.order.util.payment.PaymentUtil;
+import com.ruoyi.order.util.payment.model.CloseOrderResult;
+import com.ruoyi.order.util.payment.model.UniPayCallbackResult;
+import com.ruoyi.order.util.payment.model.UniPayResult;
 import com.ruoyi.order.vo.*;
 import com.ruoyi.other.api.domain.*;
 import com.ruoyi.other.api.feignClient.*;
 import com.ruoyi.other.api.vo.GetGoodsBargainPrice;
 import com.ruoyi.other.api.vo.GetGoodsShopByGoodsIds;
 import com.ruoyi.other.api.vo.GetSeckillActivityInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -32,9 +38,11 @@
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.*;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class ShoppingCartServiceImpl extends ServiceImpl<ShoppingCartMapper, ShoppingCart> implements ShoppingCartService {
 
@@ -106,6 +114,11 @@
 	
 	@Resource
 	private OrderBalancePaymentService orderBalancePaymentService;
+	
+	@Resource
+	private RedisTemplate redisTemplate;
+	
+	
 	
 	
 	
@@ -726,9 +739,6 @@
 		for (MyShoppingCartVo myShoppingCartVo : goodsList) {
 			earnPoint += (myShoppingCartVo.getEarnSpendingPoints() * myShoppingCartVo.getNumber());
 		}
-		if(null != shoppingCartPayment.getUserAddressId()){
-			userAddressClient.getUserAddressById(shoppingCartPayment.getUserAddressId()).getData();
-		}
 
 		//获取快递策略,计算快递费
 		BigDecimal expressFee = BigDecimal.ZERO;
@@ -867,10 +877,18 @@
 		//现金支付
 		paymentMoney = paymentMoney.add(expressFee).setScale(2, RoundingMode.HALF_EVEN);
 		if(1 == shoppingCartPayment.getPaymentType()){
-			//调起微信支付 TODO 待完善
-
-
-
+			//调起微信支付
+			String goodsNames = goodsList.stream().map(MyShoppingCartVo::getName).collect(Collectors.joining("\n"));
+			UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber(), paymentMoney.doubleValue(), order.getOrderType() == 1 ? "购买服务商品" : "购买单品商品",
+					goodsNames, "", "/order/shopping-cart/shoppingCartPaymentCallback", appUser.getWxOpenid(), "");
+			if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){
+				return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg());
+			}
+			String rc_result = uniPayResult.getRc_Result();
+			//将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。
+			long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC);
+			redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), second);
+			return R.ok(rc_result);
 		}
 		//账户余额
 		BigDecimal redPacketAmount = BigDecimal.ZERO;
@@ -956,6 +974,23 @@
 		}
 		//积分支付
 		if(3 == shoppingCartPayment.getPaymentType()){
+			//先完成快递费支付后再处理后续的逻辑
+			if(expressFee.compareTo(BigDecimal.ZERO) > 0){
+				if(shoppingCartPayment.getFreightPaymentType() == 1){
+					//调起微信支付
+					UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber() + appUser.getId(), expressFee.doubleValue(), order.getOrderType() == 1 ? "购买服务商品快递费" : "购买单品商品快递费",
+							"快递费", "", "/order/shopping-cart/shoppingCartMaterialFlowPaymentCallback", appUser.getWxOpenid(), "");
+					if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){
+						return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg());
+					}
+					String rc_result = uniPayResult.getRc_Result();
+					//将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。
+					long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC);
+					redisTemplate.opsForZSet().add("MaterialFlowPayment", order.getOrderNumber() + appUser.getId(), second);
+					return R.ok(rc_result);
+				}
+			}
+			
 			Integer lavePoint = appUser.getLavePoint();
 			PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
 			int earnPoint1 = earnPoint;
@@ -989,9 +1024,6 @@
 			userPointClient.saveUserPoint(userPoint);
 			//如果有运费,需要先扣除账户积分,再进行支付。支付成功后修改订单状态,未支付成功则回退积分,删除的订单
 			if(expressFee.compareTo(BigDecimal.ZERO) > 0){
-				if(shoppingCartPayment.getFreightPaymentType() == 1){
-					//调起微信支付
-				}
 				if(shoppingCartPayment.getFreightPaymentType() == 2){
 					BigDecimal totalRedPacketAmount = appUser.getTotalRedPacketAmount();
 					BigDecimal totalDistributionAmount = appUser.getTotalDistributionAmount();
@@ -1067,7 +1099,7 @@
 		return R.ok(order.getId().toString());
 	}
 
-
+	
 	public String getNumber(Integer size){
 		String str = "";
 		for (Integer i = 0; i < size; i++) {
@@ -1075,6 +1107,165 @@
 		}
 		return str;
 	}
-
-
+	
+	
+	/**
+	 * 线上支付回调逻辑处理
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	@Override
+	public R shoppingCartPaymentCallback(UniPayCallbackResult uniPayCallbackResult) {
+		Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, uniPayCallbackResult.getR2_OrderNo()));
+		if(null == order || order.getPayStatus() == 2){
+			return R.ok();
+		}
+		Integer earnPoint = order.getGetPoint();
+		AppUser appUser = appUserClient.getAppUserById(order.getAppUserId());
+		BigDecimal paymentMoney = order.getPaymentAmount();
+		//构建积分流水记录
+		if(earnPoint > 0){
+			PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
+			int earnPoint1 = earnPoint;
+			if(null != pointSetting && 1 == pointSetting.getBuyPointOpen()){
+				earnPoint1 = new BigDecimal(earnPoint1).multiply(pointSetting.getBuyPoint().divide(new BigDecimal(100))).intValue();
+			}
+			appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
+			appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+			appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
+			appUser.setAvailablePoint(appUser.getAvailablePoint() + earnPoint1);
+			
+			UserPoint userPoint = new UserPoint();
+			userPoint.setType(1);
+			userPoint.setHistoricalPoint(appUser.getLavePoint() - earnPoint);
+			userPoint.setVariablePoint(earnPoint);
+			userPoint.setBalance(appUser.getLavePoint());
+			userPoint.setCreateTime(LocalDateTime.now());
+			userPoint.setAppUserId(appUser.getId());
+			userPoint.setObjectId(order.getId());
+			userPointClient.saveUserPoint(userPoint);
+		}
+		appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));
+		appUser.setLastShopTime(LocalDateTime.now());
+		appUserClient.editAppUserById(appUser);
+		//变更等级
+		appUserClient.vipUpgrade(appUser.getId());
+		//修改订支付状态
+		order.setPayStatus(2);
+		//自提
+		if(order.getOrderType() == 1 && StringUtils.isEmpty(order.getAddressJson())){
+			order.setOrderStatus(2);
+		}
+		orderService.updateById(order);
+		//删除购物车数据
+		Long userid = tokenService.getLoginUserApplet().getUserid();
+		List<OrderGood> list = orderGoodService.list(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId()));
+		List<Integer> goodsIds = list.stream().map(OrderGood::getGoodsId).collect(Collectors.toList());
+		this.remove(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getAppUserId, userid).in(ShoppingCart::getGoodsId, goodsIds));
+		return R.ok();
+	}
+	
+	
+	/**
+	 * 订单物流支付回调处理逻辑
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	@Override
+	public R shoppingCartMaterialFlowPaymentCallback(UniPayCallbackResult uniPayCallbackResult) {
+		String r2_orderNo = uniPayCallbackResult.getR2_OrderNo();
+		r2_orderNo = r2_orderNo.substring(0, 23);
+		Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, r2_orderNo));
+		if(null == order || order.getPayStatus() == 2){
+			return R.ok();
+		}
+		Integer earnPoint = order.getGetPoint();
+		AppUser appUser = appUserClient.getAppUserById(order.getAppUserId());
+		Integer lavePoint = appUser.getLavePoint();
+		Integer orderPoint = order.getPoint();
+		PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
+		int earnPoint1 = earnPoint;
+		//计算可用积分比例
+		if(null != pointSetting && 1 == pointSetting.getBuyPointOpen()){
+			earnPoint1 = new BigDecimal(earnPoint1).multiply(pointSetting.getBuyPoint().divide(new BigDecimal(100))).intValue();
+		}
+		//扣减订单支付积分
+		appUser.setLavePoint(appUser.getLavePoint() - orderPoint);
+		appUser.setAvailablePoint(appUser.getAvailablePoint() - orderPoint);
+		
+		appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
+		appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+		appUser.setAvailablePoint(appUser.getAvailablePoint() + earnPoint1);
+		appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
+		appUser.setLastShopTime(LocalDateTime.now());
+		appUserClient.editAppUserById(appUser);
+		//变更等级
+		appUserClient.vipUpgrade(appUser.getId());
+		
+		//构建积分流水记录
+		UserPoint userPoint = new UserPoint();
+		userPoint.setType(1);
+		userPoint.setHistoricalPoint(lavePoint);
+		Integer point = appUser.getLavePoint() - lavePoint;
+		userPoint.setVariablePoint(point >= 0 ? point : point * -1);
+		userPoint.setBalance(appUser.getLavePoint());
+		userPoint.setCreateTime(LocalDateTime.now());
+		userPoint.setAppUserId(appUser.getId());
+		userPoint.setObjectId(order.getId());
+		userPointClient.saveUserPoint(userPoint);
+		//修改订支付状态
+		order.setPayStatus(2);
+		//自提
+		if(order.getOrderType() == 1 && StringUtils.isEmpty(order.getAddressJson())){
+			order.setOrderStatus(2);
+		}
+		orderService.updateById(order);
+		//删除购物车数据
+		Long userid = tokenService.getLoginUserApplet().getUserid();
+		List<OrderGood> list = orderGoodService.list(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId()));
+		List<Integer> goodsIds = list.stream().map(OrderGood::getGoodsId).collect(Collectors.toList());
+		this.remove(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getAppUserId, userid).in(ShoppingCart::getGoodsId, goodsIds));
+		return R.ok();
+	}
+	
+	
+	/**
+	 * 定时任务关闭订单
+	 */
+	@Override
+	public void closeOrder() {
+		//订单支付数据
+		long second = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);
+		Set<String> orderPayment = redisTemplate.opsForZSet().range("OrderPayment", 0, second);
+		for (String code : orderPayment) {
+			Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, code));
+			if(null == order || order.getPayStatus() != 1){
+				continue;
+			}
+			//开始执行关闭订单操作
+			CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(code);
+			if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) &&
+					Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){
+				redisTemplate.opsForZSet().add("OrderPayment", code, 0);
+				log.error("关闭订单失败:{}---->{}", code, JSON.toJSONString(closeOrderResult));
+			}
+		}
+		
+		//快递支付
+		Set<String> materialFlowPayment = redisTemplate.opsForZSet().range("MaterialFlowPayment", 0, second);
+		for (String code : materialFlowPayment) {
+			code = code.substring(0, 23);
+			Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, code));
+			if(null == order || order.getPayStatus() != 1){
+				continue;
+			}
+			//开始执行关闭订单操作
+			CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(code);
+			if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) &&
+					Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){
+				redisTemplate.opsForZSet().add("MaterialFlowPayment", code, 0);
+				log.error("关闭订单失败:{}---->{}", code, JSON.toJSONString(closeOrderResult));
+			}
+		}
+	}
 }

--
Gitblit v1.7.1