- 工单 #1516 / PR #1517 合并 sha bec83b72 - 删 OrderCreateService 立即调 sendOrderCreated 块 - OrderExpiryProducer 支付提醒延迟 hardcode 10min → 默认 15min + Redis 可配 (mapToDelayLevel(15)=level 15=20m) - 不影响前端,运营关注 ORDER_CREATED 模板 oa/inapp/miniapp 渠道全切
88 行
4.8 KiB
Markdown
88 行
4.8 KiB
Markdown
# 修复:创建订单不再立即发"请完成支付"短信,改为 15 分钟后未支付才发提醒
|
||
|
||
**类型**: 后端 BUG 修复 + 通知流程调整
|
||
**关联**: 工单 #1516 / PR #1517 / 用户(wx)正式环境实测反馈
|
||
**日期**: 2026-04-28
|
||
**影响范围**: 所有创建订单流程(C/B/管理端代客创单),所有用户支付提醒短信
|
||
|
||
---
|
||
|
||
## 现象
|
||
|
||
用户反馈:正式环境下单后**立即**点支付,1-3 秒内支付成功(订单 PENDING_PAY → PAID)。但仍收到一条「您的订单 HL20260428095227-1084 已创建成功,产品:王骁测试核心产品,请尽快完成支付」短信,用户疑惑"已支付了为啥还发提醒"。
|
||
|
||
## 根因
|
||
|
||
1. `OrderCreateService.afterCommit:350` 在订单创建事务提交后**立即**调 `notificationEventHelper.sendOrderCreated(notifyOrder)` 发 ORDER_CREATED 模板,**不判断当前支付状态**
|
||
2. 短信通道延迟到达(阿里云 SMS 5-30s + MQ 异步), 用户立即支付场景下短信到达时订单已 PAID
|
||
3. 同时项目早就有完整的延迟提醒链(SEND_PAYMENT_REMINDER 本地事件 → SendPaymentReminderHandler → MQ 延迟消息 → PaymentReminderConsumer 检查 PENDING_PAY 才发),但被"立即发的 ORDER_CREATED"重复了
|
||
|
||
## 修复内容
|
||
|
||
### 1. 删除立即发 ORDER_CREATED 调用 (OrderCreateService)
|
||
- 删除 `2.9 下单成功通知` 块的 sendOrderCreated afterCommit 注册
|
||
- admin 出行人完整性检查 `checkTravelerAfterAdminCreate` 拆为独立 afterCommit (仅 ctx.isAdminCreate() 时注册)
|
||
- 加详细中文注释解释 BUG 修复理由 + 引用延迟提醒链路径
|
||
- 全仓 `sendOrderCreated` 仅 1 处生产 caller, 删除即彻底切断"立即发"路径
|
||
- NotificationEventHelper.sendOrderCreated 方法本体保留(NotificationEventHelperTest 单测覆盖), 将来若有"管理端代客创建后第一时间通知客户"明确需求可在专门入口调用
|
||
|
||
### 2. 支付提醒延迟改 15 分钟可配置 (OrderExpiryProducer)
|
||
- `delayLevel=14` 硬编码 (10 分钟) → 调 `getPaymentReminderMinutes() + mapToDelayLevel()`
|
||
- 默认 15 分钟,`mapToDelayLevel(15)=level 15=20分钟` (RocketMQ 4.x 无精确 15 级,取不小于 15 的最小 = 20m)
|
||
- 新增 `@Value("${order.payment-reminder.default-minutes:15}")`
|
||
- 新增 `@Value("${order.payment-reminder.redis-key:order:config:payment-reminder-minutes}")`
|
||
- 新增 `getPaymentReminderMinutes()` public 方法 (Redis fallback DB 默认值,与 getExpiryMinutes 同 pattern)
|
||
- 日志增强: 输出 `delayMinutes={}, delayLevel={}` (原硬编码 `delayMinutes=10`)
|
||
|
||
### 3. 单测覆盖 (OrderExpiryProducerTest)
|
||
新增 5 个用例:
|
||
- `sendPaymentReminderMessage_defaultConfig_use15MinutesLevel15` 默认 15min → delayLevel 15
|
||
- `sendPaymentReminderMessage_redisConfig10Minutes_useDelayLevel14` Redis 配 10min → delayLevel 14
|
||
- `getPaymentReminderMinutes_redisConfigValid_useRedisValue` Redis "20" → 20
|
||
- `getPaymentReminderMinutes_redisInvalid_fallbackToDefault` Redis "not-a-number" → fallback 15
|
||
- `getPaymentReminderMinutes_redisNotPositive_useDefault` Redis "0" → fallback 15
|
||
|
||
## 修复后预期行为
|
||
|
||
### 创建订单流程
|
||
1. 用户创建订单,订单状态 = PENDING_PAY
|
||
2. **不再发**任何"请尽快完成支付"立即短信
|
||
3. 15 分钟(实际 20 分钟)后:
|
||
- 若订单仍 PENDING_PAY → 发 ORDER_PAYMENT_REMINDER 短信"请完成支付"
|
||
- 若订单已 PAID/CANCELLED/REFUNDED → 静默跳过(PaymentReminderConsumer 已有状态检查)
|
||
|
||
### 时序保证
|
||
- 15 分钟支付提醒 < 30 分钟过期取消(默认 `order.expiry.default-minutes=30`)
|
||
- 顺序正确,无回归
|
||
|
||
## 前端处理
|
||
|
||
**零影响**。前端无须任何改动:
|
||
- 用户不会再收到"立即创建"短信(本来就是后端发的,前端不感知)
|
||
- 15 分钟后未支付的延迟提醒仍走 ORDER_PAYMENT_REMINDER 模板,前端不感知
|
||
- 订单详情/支付按钮等所有 API 行为无变化
|
||
|
||
## 后端部署
|
||
|
||
- ✅ `mvn compile -pl hl-order-service-v2 -am` 通过
|
||
- ⏭️ 部署: 仅需重启 hl-order-service-v2 (4 个实例) 即可生效
|
||
- 🎯 测试服回归: 创建测试订单不再立即收"请完成支付"短信; 创建后 15 分钟内不支付应收一条延迟提醒短信
|
||
|
||
## 配置 (运维可选)
|
||
|
||
- 默认值已写在 `@Value` 里, 不依赖 Nacos / Redis 必有 key
|
||
- 若需动态调整: Redis 写 `order:config:payment-reminder-minutes` = `"20"` 或 `"30"`
|
||
- 测试 / 正式环境无需改 Nacos (默认即生效)
|
||
|
||
## 影响面 (运营关注)
|
||
|
||
- ORDER_CREATED 模板的 oa(公众号)/inapp(站内信)/miniapp(小程序订阅消息) 渠道全部不再触发
|
||
(sql/notification_center_v2.sql 配置, sms 默认未启用)
|
||
- 不影响 ORDER_PAYMENT_REMINDER 模板(延迟链)
|
||
- 若产品后续要恢复"管理端代客创建后立刻给客户推一条 OA"的场景,建议另开独立 event_code(例 ADMIN_PROXY_ORDER_CREATED),与"已支付场景的延迟提醒"完全隔离
|
||
|
||
## 合并
|
||
|
||
- PR #1517 squash merge 到 dev (sha bec83b72)
|
||
- 关闭工单 #1516
|