Skip to content

支付后处理 ​

1. 支付处理成功 ​

![6. 支付后处理](支付后处理-pic/6. 支付后处理-16834705483461.png)

step1 ​

支付服务:支付宝异步回调

java
@PostMapping("/api/payment/alipay/callback/notify")
@ResponseBody
@SneakyThrows
public String callbackNotify(@RequestParam Map<String, String> paramsMap){
    log.info("支付成功,异步回调,paramMap:{}", JSON.toJSONString(paramsMap));
    
    // 1. 验证签名
    boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, alipayConfig.getAlipayPublicKey(), CsmallAlipayConfig.charset, CsmallAlipayConfig.sign_type);
    
    // 2. 校验参数
    // 校验APPID
    // 校验金额
    // 校验支付宝交易状态
    // 添加幂等标记(setnx)
    
    // 3. 修改支付表状态(已支付)
    
    // 4. 远程调用订单服务(修改订单状态)
}

step2 &#8203;

订单服务:修改订单状态

java
@PostMapping("/api/order/inner/success/{orderId}")
public Result successPay(@PathVariable Long orderId){
	
    // 1. 修改订单状态(已支付)
    
    // 2. 调用仓储服务 接口 (见仓储管理系统参考手册)
}

step3 &#8203;

由仓储服务完成。

step4 &#8203;

订单服务:拆单接口step5

java
@PostMapping("/api/order/inner/orderSplit/{orderId}")
public List<WareOrderTaskDTO> orderSplit(@PathVariable(value = "orderId") String orderId, @RequestBody List<WareSkuDTO> wareSkuDTOList){

    // 1. 获取原订单信息
    
    // 2. 创建新的子订单,使用原订单给子订单赋值(注意:设置parent_order_id为原订单Id)
    
    // 3. 设置子订单订单明细

    // 4. 保存子订单到数据库(状态:已支付)
    
    // 5. 修改原订单状态(状态:已拆分)
    
    // 6. 把子订单List转化为库存工作单List并返回
    return wareOrderTaskDTOS;
}

step5 &#8203;

订单服务:修改订单状态接口

java
@PostMapping("/api/order/inner/successLockStock/{orderId}/{taskStatus}")
public Result successLockStock(@PathVariable(value = "orderId") String orderId, @PathVariable(value = "taskStatus") String taskStatus){

    // 根据库存工作单状态 获取订单状态
    
    // 如果扣减成功,修改订单状态为待发货
    // 如果扣减失败,修改订单状态为库存扣减异常

    return Result.ok();
}

2. 订单超时取消 &#8203;

之前在订单模块,创建订单之后,发送了一个延迟消息,本项目中,在订单模块处理这个延迟消息。

![7. 订单超时取消逻辑](支付后处理-pic/7. 订单超时取消逻辑.png)

伪代码实现

java
// 处理超时订单
public void execExpiredOrder(Long orderId) {
    
    OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
    // 0. 如果订单不存在,那么直接返回
    // 1. 如果订单已支付,也直接返回
    // 2. 如果订单状态 是未支付
    if (orderStatus.equals(OrderStatus.UNPAID.name()) {

        // 3. 查询支付记录
        PaymentInfoDTO paymentInfoDTO = payApiClient.getPaymentInfoDTO(orderId);
        if(paymentInfoDTO != null) {
            
            // 3. 查询支付宝 是否存在支付记录(如果获取成功,Result的data字段放的是支付状态字符串,比如TRADE_SUCCESS)
            Result ret = payApiClient.getAlipayInfo(outTradeNo);
            // 4. 
            if (如果有支付记录 即ret的状态码为200,且data字段不空) {
                // 5. 判断是否交易成功
    
                if (“TRADE_SUCCESS”.equals(result.getData().toString())) {
                    // 如果交易成功,直接返回 
                    return;
                }
                
                if (ret data字段的值不等于 "ACQ.TRADE_NOT_EXIST") {
                  // 关闭支付宝 支付记录
                   closeAlipay(); 
                }
                
              
            }
            // 关闭支付记录,调用支付服务,将支付记录的支付状态改为CLOSED
            closePay();
        }
        // 关闭订单 将订单状态改为CLOSED
        closeOrder();
    }
        
}

笔记 &#8203;

  • 幂等 1^N=1。接口调用一次和多次对资源产生的影响都是一样的
  • 封装支付Helper,用抽象工厂模式