# 2026-04-16 工作记录

## 支付回调状态不更新问题诊断与修复

**问题接口**: `POST /api/shop/shop-order/notify/{tenantId}`

### 发现的 Bug

1. **根因 Bug**：`ShopOrderServiceImpl.updateByOutTradeNo()` 第837行有 `order.setExpirationTime(null)`，强制覆盖了 Controller 中设置的 `expirationTime`（`LocalDateTime.now().plusYears(10)`），导致 XML 中 expirationTime 条件不生效。**已修复**：删除了该行。

2. **XML 缺少 `update_time`**：`ShopOrderMapper.xml` 的 `updateByOutTradeNo` SQL 的 `<set>` 块中没有 `update_time = NOW()` 和 `expiration_time` 字段。**已修复**：新增了这两个字段更新。

3. **回调地址路由问题**：Controller 路由为 `/notify/{tenantId}`，但测试访问的 `/notify`（无 tenantId）不存在，返回 fail。正确回调地址格式为 `https://glt-api.websoft.top/api/shop/shop-order/notify/{tenantId}`（需带租户ID）。**待检查**：数据库 Payment 表的 `notify_url` 字段是否正确配置了带 tenantId 的完整路径。

### 修复文件
- `src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java`
- `src/main/java/com/gxwebsoft/shop/mapper/xml/ShopOrderMapper.xml`

---

## 支付回调签名验证失败：Transaction 类错误（00:29修复）

**错误日志关键信息**：
```
signature verification failed, signType[WECHATPAY2-SHA256-RSA2048]
serial[test]  message[test\ntest\n{"test":"test"}]  sign[test]
```

### 根本原因（最致命）

`ShopOrderController.java` 导入了 **服务商模式** 的 Transaction 类：
```java
// 错误（服务商模式）
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
```
而 `ShopOrderServiceImpl.java` 下单时用的是**直连商户模式**：
```java
// 正确（直连商户模式）
import com.wechat.pay.java.service.payments.model.Transaction;
```
两个 Transaction 包路径不同，字段结构有差异（服务商 Transaction 有 spAppid/spMchid 等字段），用错误的类解析回调会导致字段映射失败，交易状态无法正确读取。**已修复**：改为正确的直连商户模式 Transaction。

---

## 配送员提成直接入账（01:15修改）

**文件**：`src/main/java/com/gxwebsoft/glt/service/impl/GltTicketOrderServiceImpl.java`

**变更**：配送员提成（ticketOrderId 关联送水订单）从进入 `freeze_money` 改为直接进入 `money`（可提现余额）。修改了 2 处 `LambdaUpdateWrapper` SQL（`freeze_money` → `money`），注释同步更新。`total_money` 不变（仍累计）。

---

---

## 分销佣金解冻任务分析（DealerCommissionUnfreeze10584Task）

**订单号**：2038841514750459904

### 解冻规则
- **送水套餐**（shop_order.form_id IN 水票模板的 goods_id）：该订单关联的水票第一条送水订单 deliveryStatus=40（已完成）才触发解冻
- **非送水套餐**（form_id 不在水票模板中）：shop_order.order_status=1 即触发解冻

### "已送达"≠"已完成"的关键区别
- deliveryStatus=30（送达待确认）：配送员拍照确认送达，此时**不触发解冻**
- deliveryStatus=40（已完成）：需用户手动确认收货 OR 超时24h自动确认后才到达此状态

### 常见未解冻原因（按排查优先级）
1. 送水订单停在 deliveryStatus=30（送达待确认），未到 40（已完成）
2. shop_order.form_id 在水票模板里，走的是"送水套餐"逻辑，但没有找到对应的 glt_user_ticket 记录
3. glt_user_ticket 记录缺失或 order_no 字段为空
4. 已有 flowType=50 的解冻 marker（说明已解冻）

### 次要原因

`RSAAutoCertificateConfig` 每次回调都重新 `build()`，SDK 内部会发一次 `serial=test` 的探测验签，网络问题或并发场景下可能导致首次回调失败。**已优化**：添加 `notifyConfigCache`（ConcurrentHashMap）按 mchId 缓存 config，避免重复初始化。
