# API调用失败退款时的代理处理确认 ## 执行流程分析 ### 关键执行顺序 ``` 1. 支付成功 → 创建代理订单(ProcessStatus = 0,未处理) ↓ 2. 支付回调 → 发送查询任务 ↓ 3. 查询任务执行: ├─ 创建查询记录(query表,状态为 "pending") ✅ 第77-87行 ├─ 生成授权书 ✅ 第108-142行 ├─ 调用API(第164行)⚠️ 可能失败 │ ├─ 如果成功 → 继续执行 │ └─ 如果失败 → return handleError(第166行)⚠️ 直接返回 │ ├─ [API成功才会执行到这里] ├─ 保存响应数据 ✅ 第177-182行 ├─ 更新查询状态为 "success" ✅ 第184-189行 └─ 发送代理处理任务 ✅ 第192行(关键!只有到这里才会发送) ``` ### 关键代码位置 **第164-167行**: ```go combinedResponse, err := l.svcCtx.ApiRequestService.ProcessRequests(decryptData, product.Id) if err != nil { return l.handleError(ctx, err, order, query) // ← 直接返回,不会继续执行 } ``` **第192行(发送代理处理任务)**: ```go // 报告生成成功后,发送代理处理异步任务(不阻塞报告流程) if asyncErr := l.svcCtx.AsynqService.SendAgentProcessTask(order.Id); asyncErr != nil { logx.Errorf("发送代理处理任务失败,订单ID: %d, 错误: %v", order.Id, asyncErr) } ``` --- ## 确认结果 ### ✅ API调用失败时的情况(第166-167行) **执行流程**: 1. 支付时创建代理订单(`ProcessStatus = 0`) 2. API调用失败(第164行) 3. **直接返回** `handleError`(第166行) 4. 进入退款流程 5. **第192行不会执行**(因为已经return了) **代理状态**: - ✅ 代理订单 `ProcessStatus = 0`(未处理) - ✅ 代理**没有收到**佣金 - ✅ 代理**没有收到**返佣 - ✅ 代理处理任务**没有发送** --- ## 业务逻辑分析 ### ✅ 符合业务逻辑 **理由**: 1. **服务未完成交付** - API调用失败,意味着无法生成查询报告 - 用户支付了订单,但服务没有成功交付 2. **用户权益保护** - 平台退款给用户是合理的 - 用户没有获得服务,不应该承担费用 3. **代理收益逻辑** - 代理的收益应该基于**服务成功交付** - 而不是仅仅因为用户支付了订单 - 如果服务未成功交付,代理不应该获得收益 4. **当前实现正确** - 只有在查询成功后(第184行更新状态为 "success") - 才会发送代理处理任务(第192行) - API调用失败时,查询未成功,代理任务不会发送 --- ## 结论 ### ✅ 当前处理完全正确 **对于 API 调用失败退款的情况**: - ✅ 代理订单未处理(`ProcessStatus = 0`) - ✅ 代理没有收到佣金和返佣 - ✅ 代理处理任务没有发送 - ✅ **完全符合业务逻辑** **业务逻辑合理性**: - ✅ 代理收益应该在服务成功交付后才发放 - ✅ API调用失败意味着服务未交付,不应发放收益 - ✅ 退款给用户是合理的,保护用户权益 --- ## 不需要修改 当前逻辑已经正确处理了这种情况,**无需修改**。 **关键保护点**: 1. 代理处理任务只在查询成功后发送(第192行) 2. API调用失败会直接返回,不会执行到第192行 3. 代理订单状态保持为0,代理没有收益 --- ## 需要注意的其他场景 虽然当前场景处理正确,但需要注意以下场景: ### ⚠️ 场景:代理已处理但订单被退款 如果: 1. API调用成功 2. 查询状态更新为 "success" 3. 发送代理处理任务 4. 代理处理任务执行,发放佣金和返佣(`ProcessStatus = 1`) 5. **之后**订单被退款(比如管理员手动退款) 这种情况下需要撤销代理收益(需要另外处理,不是当前场景)。