it_lv 2 weeks ago
parent
commit
df23bd2e76
1 changed files with 249 additions and 238 deletions
  1. 249 238
      第8章 支付.md

+ 249 - 238
第8章 支付.md

@@ -50,8 +50,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 public interface OrderFeignClient {
 
     /**
-     * 根据订单编号查询订单信息(包含明细)
-     *
+     * 根据订单编号查询订单信息
      * @param orderNo
      * @return
      */
@@ -116,11 +115,11 @@ public class RechargeInfoApiController {
 
 
 	/**
-	 * 根据充值订单编号查询充值记录
+	 * 根据充值订单编号查询充值信息
 	 * @param orderNo
 	 * @return
 	 */
-	@Operation(summary = "根据充值订单编号查询充值记录")
+	@Operation(summary = "根据充值订单编号查询充值信息")
 	@GetMapping("/rechargeInfo/getRechargeInfo/{orderNo}")
 	public Result<RechargeInfo> getRechargeInfo(@PathVariable String orderNo){
 		RechargeInfo rechargeInfo = rechargeInfoService.getRechargeInfo(orderNo);
@@ -169,17 +168,19 @@ public class RechargeInfoServiceImpl extends ServiceImpl<RechargeInfoMapper, Rec
 	@Autowired
 	private RechargeInfoMapper rechargeInfoMapper;
 
-	/**
-	 * 根据充值订单编号查询充值记录
-	 * @param orderNo
-	 * @return
-	 */
-	@Override
-	public RechargeInfo getRechargeInfo(String orderNo) {
-		LambdaQueryWrapper<RechargeInfo> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(RechargeInfo::getOrderNo, orderNo);
-		return rechargeInfoMapper.selectOne(queryWrapper);
-	}
+    /**
+     * 根据充值订单编号查询充值信息
+     *
+     * @param orderNo
+     * @return
+     */
+    @Override
+    public RechargeInfo getRechargeInfo(String orderNo) {
+        return rechargeInfoMapper.selectOne(
+                new LambdaQueryWrapper<RechargeInfo>()
+                        .eq(RechargeInfo::getOrderNo, orderNo)
+        );
+    }
 }
 ```
 
@@ -187,7 +188,7 @@ public class RechargeInfoServiceImpl extends ServiceImpl<RechargeInfoMapper, Rec
 
 ```java
 /**
- * 根据充值订单编号查询充值记录
+ * 根据充值订单编号查询充值信息
  * @param orderNo
  * @return
  */
@@ -272,50 +273,63 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
      */
     @Override
     public PaymentInfo savePaymentInfo(String paymentType, String orderNo) {
-        //0.根据订单/充值编号查询交易记录 存在直接返回,不存在新增
-        LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(PaymentInfo::getOrderNo, orderNo);
-        PaymentInfo paymentInfo = this.getOne(queryWrapper);
+        Long userId = AuthContextHolder.getUserId();
+        //1.根据订单编号查询本地交易记录,如果存在则返回即可
+        PaymentInfo paymentInfo = baseMapper.selectOne(
+                new LambdaQueryWrapper<PaymentInfo>()
+                        .eq(PaymentInfo::getOrderNo, orderNo)
+        );
         if (paymentInfo != null) {
             return paymentInfo;
-        }else{
-            //1.构建本地交易记录对象
-            paymentInfo = new PaymentInfo();
-
-            //1.1 封装对象中简单属性
-            Long userId = AuthContextHolder.getUserId();
-            paymentInfo.setUserId(userId);
-            paymentInfo.setPaymentType(paymentType);
-            paymentInfo.setOrderNo(orderNo);
-            paymentInfo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);
-            paymentInfo.setPaymentStatus(SystemConstant.PAYMENT_STATUS_UNPAID);
-            //1.2 封装本地交易记录中金额跟内容-远程调用其他服务获取
-            //1.3 判断支付类型:订单
-            if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)) {
-                //1.3.1 远程调用订单服务获取订单信息
-                OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderNo).getData();
-                Assert.notNull(orderInfo, "订单不存在");
-                //1.3.2 校验订单状态是否为:未支付
-                boolean flag = SystemConstant.ORDER_STATUS_UNPAID.equals(orderInfo.getOrderStatus());
-                Assert.state(flag, "订单状态有误!");
-                //1.3.3 封装本地交易记录中交易内容跟金额
-                paymentInfo.setAmount(orderInfo.getOrderAmount());
-                paymentInfo.setContent(orderInfo.getOrderTitle());
-            } else if (SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)) {
-                //1.4 判断支付类型:充值
-                //1.4.1 远程调用账户服务获取充值信息
-                RechargeInfo rechargeInfo = accountFeignClient.getRechargeInfo(orderNo).getData();
-                Assert.notNull(rechargeInfo, "充值记录不存在");
-                //1.4.2 校验充值状态是否为:未支付
-                boolean flag = SystemConstant.ORDER_STATUS_UNPAID.equals(rechargeInfo.getRechargeStatus());
-                Assert.state(flag, "充值状态有误!");
-                //1.4.3 封装本地交易记录中交易内容跟金额
-                paymentInfo.setAmount(rechargeInfo.getRechargeAmount());
-                paymentInfo.setContent("用户充值:" + rechargeInfo.getRechargeAmount());
+        }
+        //2.构建本地交易记录
+        paymentInfo = new PaymentInfo();
+
+
+        //2.1 封装直接赋值属性:用户ID,支付类型、订单号、付款方式、支付状态
+        paymentInfo.setUserId(userId);
+        paymentInfo.setPaymentType(paymentType);
+        paymentInfo.setOrderNo(orderNo);
+        paymentInfo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);
+        paymentInfo.setPaymentStatus(SystemConstant.PAYMENT_STATUS_UNPAID);
+        //2.2 处理支付类型为:1301订单,封装交易金额跟内容
+        if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)) {
+            //2.2.1 远程调用订单服务获取订单信息
+            OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderNo).getData();
+            Assert.notNull(orderInfo, "订单{}不存在", orderNo);
+            //2.2.2 判断订单状态,未支付才能支付 订单状态:0901-未支付 0902-已支付 0903-已取消
+            String orderStatus = orderInfo.getOrderStatus();
+            if (!SystemConstant.ORDER_STATUS_UNPAID.equals(orderStatus)) {
+                throw new GuiguException(500, "订单状态有误:" + orderStatus);
             }
-            //2.保存本地交易记录对象
-            this.save(paymentInfo);
+            //2.2.3 封装交易金额跟内容
+            paymentInfo.setAmount(orderInfo.getOrderAmount());
+            paymentInfo.setContent(orderInfo.getOrderTitle());
         }
+
+
+        //2.3 处理支付类型为:1302充值,封装交易金额跟内容
+        if (SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)) {
+            //2.2.1 远程调用账户服务获取充值信息
+            RechargeInfo rechargeInfo = accountFeignClient.getRechargeInfo(orderNo).getData();
+            Assert.notNull(rechargeInfo, "充值{}不存在", orderNo);
+            //2.2.2 判断充值状态,未支付才能支付 充值状态:0901-未支付 0902-已支付 0903-已取消
+            String rechargeStatus = rechargeInfo.getRechargeStatus();
+            if (!SystemConstant.ORDER_STATUS_UNPAID.equals(rechargeStatus)) {
+                throw new GuiguException(500, "充值状态有误:" + rechargeStatus);
+            }
+            //2.3.3 封装交易金额跟内容
+            paymentInfo.setAmount(rechargeInfo.getRechargeAmount());
+            paymentInfo.setContent("充值:" + rechargeInfo.getRechargeAmount());
+        }
+
+        //2.4 TODO 其他属性,等支付成功后异步回调获取
+        //paymentInfo.setOutTradeNo();
+        //paymentInfo.setCallbackTime();
+        //paymentInfo.setCallbackContent();
+
+        //3.保存本地交易记录
+        baseMapper.insert(paymentInfo);
         return paymentInfo;
     }
 }
@@ -426,17 +440,17 @@ public class WxPayApiController {
     private WxPayService wxPayService;
 
 
-    /**
-     * 对接微信支付返回小程序拉起微信支付页面所需参数
-     *
-     * @param paymentType 支付类型:1301-订单 1302-充值
-     * @param orderNo     订单号(订单、充值)
-     * @return {}包含五项参数
+   /**
+     * 下单或充值选择微信支付,返回小程序拉起微信支付所需参数
+     * @param paymentType 支付类型:1301下单  1302充值
+     * @param orderNo 订单/充值订单编号
+     * @return {"timeStamp":"","package":"","paySign":"","signType":"RSA","nonceStr":""}
      */
     @GuiGuLogin
-    @Operation(summary = "对接微信支付返回小程序拉起微信支付页面所需参数")
+    @Operation(summary = "下单或充值选择微信支付,返回小程序拉起微信支付所需参数")
     @PostMapping("/wxPay/createJsapi/{paymentType}/{orderNo}")
-    public Result<Map<String, String>> createJsapi(@PathVariable String paymentType, @PathVariable String orderNo) {
+    public Result<Map<String, String>> createJsapi(@PathVariable String paymentType,
+                                                  @PathVariable String orderNo){
         Map<String, String> map = wxPayService.createJsapi(paymentType, orderNo);
         return Result.ok(map);
     }
@@ -453,13 +467,13 @@ import java.util.Map;
 public interface WxPayService {
 
     /**
-     * 对接微信支付返回小程序拉起微信支付页面所需参数
-     *
-     * @param paymentType 支付类型:1301-订单 1302-充值
-     * @param orderNo     订单号(订单、充值)
-     * @return {}包含五项参数
+     * 下单或充值选择微信支付,返回小程序拉起微信支付所需参数
+     * @param paymentType 支付类型:1301下单  1302充值
+     * @param orderNo 订单/充值订单编号
+     * @return {{"timeStamp":"","package":"","paySign":"","signType":"RSA","nonceStr":""}}}
      */
     Map<String, String> createJsapi(String paymentType, String orderNo);
+    
 }
 ```
 
@@ -511,22 +525,24 @@ public class WxPayServiceImpl implements WxPayService {
     @Autowired
     private RSAAutoCertificateConfig rsaAutoCertificateConfig;
 
-    /**
-     * 对接微信支付返回小程序拉起微信支付页面所需参数
+        /**
+     * 下单或充值选择微信支付,返回小程序拉起微信支付所需参数
      *
-     * @param paymentType 支付类型:1301-订单 1302-充值
-     * @param orderNo     订单号(订单、充值)
-     * @return {}包含五项参数
+     * @param paymentType 支付类型:1301下单  1302充值
+     * @param orderNo     订单/充值订单编号
+     * @return {{"timeStamp":"","package":"","paySign":"","signType":"RSA","nonceStr":""}}}
      */
     @Override
     public Map<String, String> createJsapi(String paymentType, String orderNo) {
         try {
-            //1.新增本地交易记录
+            //1.获取或保存本地交易记录,验证状态
             PaymentInfo paymentInfo = paymentInfoService.savePaymentInfo(paymentType, orderNo);
-            if (SystemConstant.PAYMENT_STATUS_PAID.equals(paymentInfo.getPaymentStatus())) {
-                throw new RuntimeException("该笔交易已支付");
+            //支付状态:1401-未支付 1402-已支付
+            String paymentStatus = paymentInfo.getPaymentStatus();
+            if (!SystemConstant.PAYMENT_STATUS_UNPAID.equals(paymentStatus)) {
+                throw new GuiguException(500, "本地交易记录状态有误" + paymentStatus);
             }
-            //2.调用微信支付接口返回小程序拉起微信支付所需参数
+            //2.对接微信支付,获取小程序端拉起微信支付所需参数
             //2.1 创建调用微信支付JSAPI业务对象
             JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
 
@@ -563,9 +579,9 @@ public class WxPayServiceImpl implements WxPayService {
                 return map;
             }
             return null;
-        } catch (RuntimeException e) {
-            log.error("创建微信支付JSAPI参数失败", e);
-            throw new RuntimeException(e);
+        } catch (Exception e) {
+            log.error("微信下单失败");
+            throw new GuiguException(500, e.getMessage());
         }
     }
 }
@@ -585,17 +601,16 @@ public class WxPayServiceImpl implements WxPayService {
 
 ```java
 /**
- * 根据商户订单编号查询微信支付结果
- *
+ * 查询订单支付状态
  * @param orderNo
  * @return
  */
 @GuiGuLogin
-@Operation(summary = "根据商户订单编号查询微信支付结果")
+@Operation(summary = "商户端主动查询微信支付结果")
 @GetMapping("/wxPay/queryPayStatus/{orderNo}")
-public Result<Boolean> queryPayStatus(@PathVariable String orderNo) {
-    Boolean flag = wxPayService.queryPayStatus(orderNo);
-    return Result.ok(flag);
+public Result<Boolean> queryPayStatus(@PathVariable String orderNo){
+    boolean result = wxPayService.queryPayStatus(orderNo);
+    return Result.ok(result);
 }
 ```
 
@@ -615,60 +630,45 @@ Boolean queryPayStatus(String orderNo);
 
 ```java
 /**
- * 查询订单支付状态:调用微信支付接口查询支付状态
+ * 查询订单支付状态
  *
  * @param orderNo
  * @return
  */
 @Override
-@GlobalTransactional(rollbackFor = Exception.class)
-public Boolean queryPayStatus(String orderNo) {
-    //1 JSAPI支付和APP支付业务类对象
+public boolean queryPayStatus(String orderNo) {
+    /*//1.构建业务对象
     JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
-    //2.创建商户订单查询支付结果请求对象
-    QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
-    queryRequest.setMchid(wxPayV3Config.getMerchantId());
-    queryRequest.setOutTradeNo(orderNo);
-
-    try {
-        //3.执行查询
-        Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
-        if (transaction != null) {
-            if (transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
-                Integer payerTotal = transaction.getAmount().getPayerTotal();
-                if (1 == payerTotal) {
-                    return true;
-                }
+    //2.构建根据商户订单号查询微信支付订单状态的请求参数
+    QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
+    request.setMchid(wxPayV3Config.getMerchantId());
+    request.setOutTradeNo(orderNo);
+
+    //3.调用微信支付查询订单状态接口
+    Transaction transaction = service.queryOrderByOutTradeNo(request);
+    if (transaction != null) {
+        Transaction.TradeStateEnum tradeState = transaction.getTradeState();
+        if (Transaction.TradeStateEnum.SUCCESS == tradeState) {
+            //交易成功,验证订单金额跟用户实付金额是否一致
+            Integer payerTotal = transaction.getAmount().getPayerTotal();
+            if (payerTotal.intValue() == 1) {
+                return true;
             }
         }
-    } catch (Exception e) {
-        // API返回失败, 例如ORDER_NOT_EXISTS
-        log.error("[支付系统]同步查询支付状态异常:{}", e);
     }
-    return false;
-}
-```
-
-**大家实现(没有办法支付,故在同步回调中模拟支付成功)-代码**:
-
-```java
-/**
- * 根据商户订单编号查询微信支付结果
- *
- * @param orderNo 商户订单编号
- * @return
- */
-@Override
-public Boolean queryPayStatus(String orderNo) {
-    //TODO 模拟用户已经完成付款(商户入账),处理本地交易记录及订单或充值业务
+    return false;*/
+    //TODO 处理核心业务:更新本地交易记录状态
+    //1.伪造微信交易对象 封装:订单编号+微信交易号
     Transaction transaction = new Transaction();
     transaction.setOutTradeNo(orderNo);
-    transaction.setTransactionId("wx"+ IdUtil.getSnowflakeNextId());
-    paymentInfoService.handlerPaymentInfo(transaction);
+    transaction.setTransactionId("WX"+ IdUtil.getSnowflakeNextId());
+    paymentInfoService.updatePaymentInfo(transaction);
     return true;
 }
 ```
 
+**大家课后练习(没有办法支付,故在同步回调中模拟支付成功)**
+
 ## 1.4 支付异步回调
 
 > 微信异步回调说明:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_5.shtml
@@ -779,14 +779,15 @@ public Boolean queryPayStatus(String orderNo) {
 
 ```java
 /**
- * 提供给微信支付调用:用户微信付款成功后,微信通知商户支付结果
+ * 微信支付成功后异步回调
  * @param request
- * @return {code:"SUCCESS",message:"成功"}
+ * @return
+ * @throws Exception
  */
-@Operation(summary = "提供给微信支付调用:用户微信付款成功后,微信通知商户支付结果")
+@Operation(summary = "微信支付成功后异步回调")
 @PostMapping("/wxPay/notify")
-public Map<String, String> notifyPayResult(HttpServletRequest request) {
-    return wxPayService.notifyPayResult(request);
+public Map<String, String> wxPayNotify(HttpServletRequest request) throws Exception {
+    return wxPayService.wxPayNotify(request);
 }
 ```
 
@@ -814,7 +815,7 @@ private RedisTemplate redisTemplate;
  * @return
  */
 @Override
-public Map<String, String> notifyPayResult(HttpServletRequest request) {
+public Map<String, String> wxPayNotify(HttpServletRequest request) {
     //1.验签-避免出现虚假通知或支付结果在网络传输中被恶意篡改
     //1.1 从请求头中获取封装请求参数对象数据
     String signature = request.getHeader("Wechatpay-Signature");
@@ -826,6 +827,7 @@ public Map<String, String> notifyPayResult(HttpServletRequest request) {
     //1.2 获取请求体中参数
     String body = PayUtil.readData(request);
     log.info("请求体:{}", body);
+
     //2.参数解密-解析获取请求体中业务参数(支付结果业务数据)
     //2.1 构造RequestParam
     RequestParam requestParam = new RequestParam.Builder()
@@ -840,29 +842,30 @@ public Map<String, String> notifyPayResult(HttpServletRequest request) {
     //2.3 解密并转换成 Transaction交易对象
     Transaction transaction = parser.parse(requestParam, Transaction.class);
 
-    //3.幂等性处理:微信会多次重复发送通知共计时间24h4m
+    //3.验证微信支付状态:必须是已支付,应付金额跟实付金额一致
     if (transaction != null) {
-        //3.1 微信支付系统生成的订单号
-        String transactionId = transaction.getTransactionId();
-        //3.2 采用Redis进行幂等性处理
-        String key = "pay:notify:" + transactionId;
-        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, transactionId, 25, TimeUnit.HOURS);
-        if (flag) {
-            try {
-                //4.校验通知的信息是否与商户侧的信息一致:校验应付金额跟实付金额是否一致
-                if (transaction.getAmount().getTotal().intValue() == 1) {
-                    //5.TODO 核心业务:更新本地交易及订单或者充值记录状态-存在分布式事务问题
-                    paymentInfoService.handlerPaymentInfo(transaction);
+        Transaction.TradeStateEnum tradeState = transaction.getTradeState();
+        if (Transaction.TradeStateEnum.SUCCESS == tradeState
+                && transaction.getAmount().getPayerTotal().intValue() == 1) {
+
+            //4.幂等性处理 同一笔交易仅需处理一次
+            //4.1 获取交易对象中微信支付订单号或者商户订单作为唯一标识
+            String redisKey = RedisConstant.BUSINESS_PREFIX + transaction.getOutTradeNo();
+            //4.2 利用Redis提供set k v ex nx 命令实现
+            Boolean flag = redisTemplate.opsForValue().setIfAbsent(redisKey, transaction.getOutTradeNo(), 25, TimeUnit.HOURS);
+            if (flag) {
+                try {
+                    //5.核心业务处理:更新本地交易记录
+                    paymentInfoService.updatePaymentInfo(transaction);
                     //6.返回微信正确应答
                     Map<String, String> map = new HashMap<>();
                     map.put("code", "SUCCESS");
                     map.put("message", "成功");
-                    return map;
+                } catch (Exception e) {
+                    redisTemplate.delete(redisKey);
+                    log.error("微信支付回调处理失败");
+                    throw new RuntimeException(e);
                 }
-            } catch (Exception e) {
-                //如果业务发生异常无法正确应答微信,删除key,等待微信下次通知
-                redisTemplate.delete(key);
-                throw new RuntimeException(e);
             }
         }
     }
@@ -876,52 +879,53 @@ public Map<String, String> notifyPayResult(HttpServletRequest request) {
 
 ```java
 /**
- * 用户付款成功后,更新本地交易记录及关联的订单或充值相关业务处理
- * @param transaction
+ * 支付成功后,更新交易记录
+ * @param transaction 微信交易对象
  */
-void handlerPaymentInfo(Transaction transaction);
+void updatePaymentInfo(Transaction transaction);
 ```
 
 **PaymentInfoServiceImpl**
 
 ```java
 /**
- * 用户付款成功后,更新本地交易记录及关联的订单或充值相关业务处理
+ * 支付成功后,更新交易记录
  *
- * @param transaction
+ * @param transaction 微信交易对象
  */
 @Override
 @GlobalTransactional(rollbackFor = Exception.class)
-public void handlerPaymentInfo(Transaction transaction) {
-    //1.核心业务1:更新本地交易-支付状态、回调内容、回调时间、微信端交易编号
-    //1.1 获取交易对应商户订单编号
+public void updatePaymentInfo(Transaction transaction) {
+    //1.根据微信交易对象中的商户订单号查询本地交易记录 如果已支付 忽略
     String orderNo = transaction.getOutTradeNo();
-    //1.2 根据订单编号查询本地交易记录
-    PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new LambdaQueryWrapper<PaymentInfo>().eq(PaymentInfo::getOrderNo, orderNo));
-    if (paymentInfo != null && SystemConstant.PAYMENT_STATUS_UNPAID.equals(paymentInfo.getPaymentStatus())) {
-        //1.3 获取到微信交易订单编号
-        String transactionId = transaction.getTransactionId();
+    PaymentInfo paymentInfo = baseMapper.selectOne(
+            new LambdaQueryWrapper<PaymentInfo>()
+                    .eq(PaymentInfo::getOrderNo, orderNo)
+    );
+    //支付状态:1401-未支付 1402-已支付
+    String paymentStatus = paymentInfo.getPaymentStatus();
+    if (SystemConstant.PAYMENT_STATUS_UNPAID.equals(paymentStatus)) {
+        //2.更新本地交易记录状态:已支付 更新:交易编号、回调时间、回调内容
         paymentInfo.setPaymentStatus(SystemConstant.PAYMENT_STATUS_PAID);
-        paymentInfo.setOutTradeNo(transactionId);
+        paymentInfo.setOutTradeNo(transaction.getTransactionId());
         paymentInfo.setCallbackTime(new Date());
         paymentInfo.setCallbackContent(transaction.toString());
-        paymentInfoMapper.updateById(paymentInfo);
+        baseMapper.updateById(paymentInfo);
 
-        //支付类型:1301-订单 1302-充值
+        //3.处理支付类型:1301订单 订单状态更新及虚拟物品发货
         String paymentType = paymentInfo.getPaymentType();
-        //2.核心业务2-如果交易类型是订单,远程调用订单服务更新订单并且完成虚拟物品发货
         if (SystemConstant.PAYMENT_TYPE_ORDER.equals(paymentType)) {
-            //2.1 远程调用订单服务修改订单状态:已支付
             Result result = orderFeignClient.orderPaySuccess(orderNo);
-            if (!result.getCode().equals(200)) {
-                throw new RuntimeException("远程调用-更新订单状态异常");
+            if (result.getCode().intValue() != 200) {
+                throw new GuiguException(result.getCode(), result.getMessage());
             }
         }
-        //3.TODO 核心业务3-如果交易类型是充值,远程调用账户服务完成充值业务
-        if (SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)) {
-  			Result result = accountFeignClient.rechargePaySuccess(orderNo);
-            if (!result.getCode().equals(200)) {
-                throw new RuntimeException("远程调用-充值异常");
+        //4.处理支付类型:1302充值 余额充值
+        if(SystemConstant.PAYMENT_TYPE_RECHARGE.equals(paymentType)){
+            //4.1 远程调用账户服务,修改充值状态,完车充值业务
+            Result result = accountFeignClient.rechargePaySuccess(orderNo);
+            if (result.getCode().intValue() != 200) {
+                throw new GuiguException(result.getCode(), result.getMessage());
             }
         }
     }
@@ -963,36 +967,44 @@ void orderPaySuccess(String orderNo);
 
 ```java
 /**
- * 用户付款成功后,处理订单相关业务
+ * 用户支付成功后,修改订单状态:已支付
  *
  * @param orderNo
- * @return
  */
 @Override
 public void orderPaySuccess(String orderNo) {
-    //1.修改订单状态改为已支付
-    OrderInfo orderInfo = this.getOrderInfo(orderNo);
-    orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
-    orderInfoMapper.updateById(orderInfo);
-
-    //2.远程调用用户服务完成虚拟物品发货
-    //2.1 构建虚拟物品发货VO对象
-    UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
-    userPaidRecordVo.setOrderNo(orderInfo.getOrderNo());
-    userPaidRecordVo.setUserId(orderInfo.getUserId());
-    //2.1.1 购买项目类型:付款项目类型: 1001-专辑 1002-声音 1003-vip会员'
-    userPaidRecordVo.setItemType(orderInfo.getItemType());
-    //2.1.2 从订单中获取订单明细得到购买项目ID列表
-    List<OrderDetail> orderInfoOrderDetailList = orderInfo.getOrderDetailList();
-    if (CollectionUtil.isNotEmpty(orderInfoOrderDetailList)) {
-        List<Long> itemIdList = orderInfoOrderDetailList.stream().map(OrderDetail::getItemId).collect(Collectors.toList());
+    //1.根据订单编号查询订单状态
+    OrderInfo orderInfo = orderInfoMapper.selectOne(
+            new LambdaQueryWrapper<OrderInfo>()
+                    .eq(OrderInfo::getOrderNo, orderNo)
+    );
+    //订单状态:0901-未支付 0902-已支付 0903-已取消
+    String orderStatus = orderInfo.getOrderStatus();
+    if (SystemConstant.ORDER_STATUS_UNPAID.equals(orderStatus)) {
+        //2.如果订单状态是未支付:修改订单状态为已支付
+        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
+        orderInfoMapper.updateById(orderInfo);
+
+        //3.远程调用"用户服务"虚拟物品发货
+        //3.1 构建虚拟物品发货vo对象
+        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
+        userPaidRecordVo.setOrderNo(orderNo);
+        userPaidRecordVo.setUserId(orderInfo.getUserId());
+        userPaidRecordVo.setItemType(orderInfo.getItemType());
+        //查询订单明细得的购买项目ID列表
+        List<OrderDetail> orderDetailList = orderDetailService.list(
+                new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderInfo.getId())
+                        .select(OrderDetail::getItemId)
+        );
+        List<Long> itemIdList = orderDetailList.stream().map(OrderDetail::getItemId).collect(Collectors.toList());
         userPaidRecordVo.setItemIdList(itemIdList);
-        //2.2 判断业务状态码
+        //3.2 执行远程调用,一定要判断调用业务状态码
         Result result = userFeignClient.savePaidRecord(userPaidRecordVo);
-        if (!result.getCode().equals(200)) {
-            throw new RuntimeException("远程调用-虚拟物品发货异常");
+        if (result.getCode().intValue() != 200) {
+            throw new GuiguException(result.getCode(), result.getMessage());
         }
     }
+
 }
 ```
 
@@ -1038,12 +1050,12 @@ public Result orderPaySuccess(String orderNo) {
 
 ```java
 /**
- * 保存充值记录
+ * 保存充值
  * @param rechargeInfoVo
  * @return {orderNo:"充值订单编号"}
  */
 @GuiGuLogin
-@Operation(summary = "保存充值记录")
+@Operation(summary = "保存充值")
 @PostMapping("/rechargeInfo/submitRecharge")
 public Result<Map<String, String>> submitRecharge(@RequestBody RechargeInfoVo rechargeInfoVo){
 	Map<String, String> map = rechargeInfoService.submitRecharge(rechargeInfoVo);
@@ -1066,29 +1078,27 @@ Map<String, String> submitRecharge(RechargeInfoVo rechargeInfoVo);
 
 ```java
 /**
- * 保存充值记录
+ * 保存充值
  *
  * @param rechargeInfoVo
  * @return {orderNo:"充值订单编号"}
  */
 @Override
 public Map<String, String> submitRecharge(RechargeInfoVo rechargeInfoVo) {
-    //1.构建充值记录对象
     RechargeInfo rechargeInfo = new RechargeInfo();
     rechargeInfo.setUserId(AuthContextHolder.getUserId());
-    rechargeInfo.setRechargeStatus(SystemConstant.ORDER_STATUS_UNPAID);
-    rechargeInfo.setRechargeAmount(rechargeInfoVo.getAmount());
-    rechargeInfo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);
-    //生成充值订单编号 CZ+日期+雪花算法
+    //生成充值订单编号
     String orderNo = "CZ" + DateUtil.today().replace("-", "") + IdUtil.getSnowflakeNextId();
     rechargeInfo.setOrderNo(orderNo);
-    //2.执行保存充值记录
+    rechargeInfo.setRechargeStatus(SystemConstant.ORDER_STATUS_UNPAID);
+    rechargeInfo.setRechargeAmount(rechargeInfoVo.getAmount());
+    rechargeInfo.setPayWay(rechargeInfoVo.getPayWay());
     rechargeInfoMapper.insert(rechargeInfo);
-    //3.封装响应对象中订单编号
+
+    //TODO 超时未支付充值订单关闭,RabbitMQ延迟消息
+
     Map<String, String> map = new HashMap<>();
     map.put("orderNo", orderNo);
-
-    //4.TODO 发送延迟消息 延迟关闭充值记录
     return map;
 }
 ```
@@ -1107,16 +1117,15 @@ public Map<String, String> submitRecharge(RechargeInfoVo rechargeInfoVo) {
 
 ```java
 /**
- * 用户付款后处理充值成功业务
- *
+ * 	微信支付成功后,处理充值业务
  * @param orderNo
  * @return
  */
-@Operation(summary = "用户付款后处理充值成功业务")
+@Operation(summary = "微信支付成功后,处理充值业务")
 @GetMapping("/rechargeInfo/rechargePaySuccess/{orderNo}")
-public Result rechargePaySuccess(@PathVariable String orderNo) {
-    rechargeInfoService.rechargePaySuccess(orderNo);
-    return Result.ok();
+public Result rechargePaySuccess(@PathVariable String orderNo){
+	rechargeInfoService.rechargePaySuccess(orderNo);
+	return Result.ok();
 }
 ```
 
@@ -1124,9 +1133,9 @@ public Result rechargePaySuccess(@PathVariable String orderNo) {
 
 ```java
 /**
- * 用户付款后处理充值成功业务
- *
+ * 	微信支付成功后,处理充值业务
  * @param orderNo
+ * @return
  */
 void rechargePaySuccess(String orderNo);
 ```
@@ -1134,37 +1143,39 @@ void rechargePaySuccess(String orderNo);
 **RechargeInfoServiceImpl实现**
 
 ```java
-@Autowired
-private UserAccountService userAccountService;
-
-
 /**
- * 用户付款后处理充值成功业务
+ * 微信支付成功后,处理充值业务
  *
  * @param orderNo
+ * @return
  */
 @Override
 public void rechargePaySuccess(String orderNo) {
-    //1.修改充值状态
-    //1.1. 根据充值订单编号查询充值记录
-    LambdaQueryWrapper<RechargeInfo> queryWrapper = new LambdaQueryWrapper<>();
-    queryWrapper.eq(RechargeInfo::getOrderNo, orderNo);
-    RechargeInfo rechargeInfo = rechargeInfoMapper.selectOne(queryWrapper);
-
-    if (SystemConstant.ORDER_STATUS_UNPAID.equals(rechargeInfo.getRechargeStatus())) {
-        //1.2 修改充值状态:已支付
+    //1.根据充值订单编号查询充值记录 判断状态是否为未支付
+    RechargeInfo rechargeInfo = rechargeInfoMapper.selectOne(
+            new LambdaQueryWrapper<RechargeInfo>()
+                    .eq(RechargeInfo::getOrderNo, orderNo)
+    );
+    String rechargeStatus = rechargeInfo.getRechargeStatus();
+    if (SystemConstant.ORDER_STATUS_UNPAID.equals(rechargeStatus)) {
+        //2.更新充值记录:已支付
         rechargeInfo.setRechargeStatus(SystemConstant.ORDER_STATUS_PAID);
         rechargeInfoMapper.updateById(rechargeInfo);
-
-        //2.余额充值
-        LambdaUpdateWrapper<UserAccount> updateWrapper = new LambdaUpdateWrapper<>();
+        //3.充值,对总金额、可用金额增加
         BigDecimal amount = rechargeInfo.getRechargeAmount();
-        updateWrapper.setSql("total_amount = total_amount + " + amount + ", available_amount = available_amount + " + amount + ", total_income_amount = total_income_amount + " + amount);
-        updateWrapper.eq(UserAccount::getUserId, rechargeInfo.getUserId());
-        userAccountService.update(updateWrapper);
-
-        //3.新增账户变动日志
-        userAccountService.saveUserAccountDetail(rechargeInfo.getUserId(), "充值:" + amount, SystemConstant.ACCOUNT_TRADE_TYPE_DEPOSIT, amount, orderNo);
+        boolean flag = userAccountService.update(
+                null,
+                new LambdaUpdateWrapper<UserAccount>()
+                        .setSql("total_amount = total_amount +" + amount)
+                        .setSql("available_amount = available_amount +" + amount)
+                        .setSql("total_income_amount = total_income_amount +" + amount)
+                        .eq(UserAccount::getUserId, rechargeInfo.getUserId())
+        );
+        if (!flag) {
+            throw new GuiguException(500, "充值失败!");
+        }
+        //4.新增账户变动日志
+        userAccountService.saveUserAccountDetail(rechargeInfo.getUserId(), "充值", SystemConstant.ACCOUNT_TRADE_TYPE_DEPOSIT, amount, orderNo);
     }
 }
 ```
@@ -1177,7 +1188,7 @@ public void rechargePaySuccess(String orderNo) {
 
 ```java
 /**
- * 用户付款后处理充值成功业务
+ * 	微信支付成功后,处理充值业务
  * @param orderNo
  * @return
  */