浩荣商城 正在参加 Gitee 2025 最受欢迎开源软件投票活动。希望可以来支持一下,这对我们非常重要,万分感谢!❤️ ❤️ ❤️ 点击去跳转
Skip to content

Haorong Mall 支付逻辑分析

本文档详细解析了 haorong-mall 项目中用户从下单到支付成功,以及订单状态同步的完整技术实现流程。

1. 核心流程概览

整个购物支付流程涉及 haorong-order (订单服务) 和 haorong-pay (支付服务) 两个核心模块,采用 Dubbo 进行远程调用,RocketMQ 进行异步消息通知。

主要步骤:

  1. 创建订单:用户提交订单,系统校验库存、优惠券,生成订单记录。
  2. 预支付:用户发起支付请求,订单服务调用支付服务,获取第三方支付参数 (如微信 PrepayID)。
  3. 用户支付:用户在客户端 (App/小程序) 完成支付。
  4. 支付回调:第三方支付平台 (微信/支付宝) 回调支付服务。
  5. 状态同步:支付服务更新内部状态,并通过 RocketMQ 通知订单服务更新订单状态。
  6. 超时取消:通过延迟消息或定时任务处理未支付订单。

2. 详细实现逻辑

2.1 下单流程 (Order Creation)

  • 入口: AppOrderInfoController.createOrder
  • 核心服务: OrderInfoServiceImpl.createOrder

关键步骤:

  1. 参数校验: 检查收货地址、商品 SKU 是否存在。
  2. 库存扣减: orderStockHandler 调用商品服务扣减库存。
  3. 优惠计算: orderCouponHandler 计算优惠券折扣。
  4. 运费计算: orderFreightHandler 计算运费。
  5. 订单保存: 保存 OrderInfo (订单主表) 和 OrderItemEntity (订单明细表)。
  6. 事务控制: 使用 @GlobalTransactional (Seata) 保证分布式事务一致性。

2.2 预支付与支付发起 (Pre-payment)

  • 入口: AppOrderInfoController.prepay
  • 核心逻辑: OrderInfoServiceImpl.prepay

交互流程:

  1. 校验订单: 检查订单是否存在、是否已支付。
  2. 构建参数: 创建 CreateOrderReqDTO,设置 mqNotifyUrlRocketMqConstants.PAY_NOTIFY_TOPIC (关键!用于后续回调通知)。
    java
    JSONObject extraParams = new JSONObject();
    extraParams.put("mqNotifyUrl", RocketMqConstants.PAY_NOTIFY_TOPIC); // 告诉支付服务回调通知哪个 Topic
    createOrderReqDTO.setExtra(extraParams.toJSONString());
  3. 远程调用: 通过 Dubbo 调用 RemotePayService.createOrder
  4. 支付服务分发: RemotePayServiceImpl 根据 tradeType (支付方式) 使用策略模式分发给具体的 PayOrderHandler
    • AliPayAppPayHandler / AlipayH5PayHandler
    • WechatAppPayHandler / WechatJsApiPayHandler
  5. 返回参数: 返回给前端用于调起支付 SDK 的参数。

2.3 支付回调 (Callback Handling)

  • 模块: haorong-pay
  • 入口: PayNotifyRecordController
    • 微信: /notify/wx/{tenantId}/{terminalType}
    • 支付宝: /notify/alipay/{tenantId}/{terminalType}

处理逻辑 (PayNotifyRecordServiceImpl):

  1. 验签: 验证第三方平台回调签名的合法性。
  2. 去重: 使用 Redis (setIfAbsent) 防止重复处理同一笔回调。
  3. 更新支付单: 更新 pay_trade_order 表状态为支付成功 (PayStatus = YES)。
  4. 记录日志: 保存 PayNotifyRecord
  5. 发送 MQ 通知: 解析 extra 字段中的 mqNotifyUrl,发送 RocketMQ 消息。
    java
    // 发送消息通知订单服务
    rocketMQTemplate.syncSend(json.getString("mqNotifyUrl"), new GenericMessage<>(jsonObject), ...);

2.4 订单状态同步 (Status Update)

  • 模块: haorong-order
  • 消费者: HuanxingPayListener

处理逻辑:

  1. 监听消息: 监听 RocketMqConstants.PAY_NOTIFY_TOPIC
  2. 更新订单: 接收到支付成功消息后,将 order_info 表状态更新为已支付 (PayStatus = YES)。
  3. 后续操作:
    • 增加商品销量。
    • 更新优惠券状态 (如已使用)。
    • 发送订单支付成功事件 (ORDER_PAY_SUCCESS_NOTIFY_TOPIC)。

2.5 订单超时取消 (Timeout Cancellation)

为了防止库存被长期占用,系统实现了订单超时自动取消机制。

机制一:定时任务 (兜底方案)

  • : OrderJobHandler
  • 任务: orderCancelJobHandler (@XxlJob)
  • 逻辑: 每隔一段时间扫描 WAITING_FOR_PAYMENT 状态且创建时间超过 30 分钟的订单,执行取消逻辑。

机制二:延迟队列 (实时方案)

  • 消费者: OrderCancelListener
  • 逻辑: 监听 ORDER_CANCEL_TOPIC。下单成功后发送延迟消息 (如 30 分钟延迟),消息到达时如果订单仍未支付,则触发取消。
  • 取消动作: OrderInfoServiceImpl.cancelOrder
    • 更新订单状态为 CANCELED
    • 回滚库存: 调用商品服务回滚 SKU 库存。
    • 回滚优惠券: 恢复优惠券为未使用状态。

3. 核心类与文件索引

模块关键类路径说明
OrderAppOrderInfoControllerhaorong-order/.../AppOrderInfoController.javaC 端订单接口 (创建、预支付)
OrderOrderInfoServiceImplhaorong-order/.../OrderInfoServiceImpl.java订单核心业务逻辑
OrderHuanxingPayListenerhaorong-order/.../HuanxingPayListener.java支付成功 MQ 消息消费者
OrderOrderJobHandlerhaorong-order/.../OrderJobHandler.java订单超时取消定时任务
PayRemotePayServiceImplhaorong-pay/.../RemotePayServiceImpl.java支付 Dubbo 服务实现
PayPayNotifyRecordControllerhaorong-pay/.../PayNotifyRecordController.java支付回调 HTTP 接口
PayPayNotifyRecordServiceImplhaorong-pay/.../PayNotifyRecordServiceImpl.java回调处理与 MQ 发送
PayAbstractPayOrderHandlerhaorong-pay/.../AbstractPayOrderHandler.java支付处理器模板基类