针对您遇到的Discuz邀请码购买后未正常发放、积分未到账、订单状态异常等问题,结合技术排查逻辑,以下是完整解决方案:
---
### **一、核心问题定位**
该问题涉及支付回调处理、订单状态同步、邀请码生成机制三个核心环节。需重点排查以下方向:
1. **支付接口回调异常**(订单状态未更新)
2. **数据表写入失败**(邀请码记录未生成)
3. **系统队列/计划任务阻塞**(异步任务未触发)
4. **第三方插件兼容性冲突**
---
### **二、逐步排查方案**
#### **1. 支付回调验证**
- **检查回调地址**
进入支付插件配置后台(如支付宝/微信插件),确认「异步通知URL」设置为:
`https://您的域名/api/payment/notify/插件名称/`
确保该URL能外网访问且无防火墙拦截(可用浏览器直接访问测试是否返回空白页)。
- **手动模拟回调测试**
在支付插件日志中获取支付成功的交易号,通过Postman工具模拟支付平台回调:
- POST /api/payment/notify/插件名称/
- Content-Type: application/x-www-form-urlencoded
- 携带原始交易参数(需签名)
复制代码
观察是否返回`success`字符及订单状态是否更新为「已付款」。
#### **2. 订单状态同步机制**
- **检查计划任务**
进入Discuz后台 → 工具 → 计划任务,确认 `支付订单处理` 任务状态为「正常」,点击「立即执行」测试是否能批量更新待付款订单。
- **手动触发SQL修正**
通过数据库管理工具执行(备份后操作):
- UPDATE pre_common_order SET status=1 WHERE status=0 AND dateline<UNIX_TIMESTAMP()-3600;
复制代码
该语句将超1小时未支付的订单标记为「已关闭」,排除旧订单干扰。
#### **3. 邀请码生成排查**
- **检查数据表记录**
查询 `pre_invite` 表确认邀请码生成状态:
- SELECT * FROM pre_invite WHERE uid=购买用户UID ORDER BY id DESC LIMIT 5;
复制代码
若记录缺失,需检查支付成功后的回调逻辑是否触发 `invite::generate()` 方法。
- **文件权限检查**
确认 `data/log/` 和 `data/template/` 目录权限为755(Linux服务器),确保邀请码生成时能写入日志和缓存。
#### **4. 邮件发送延迟处理**
- **切换发送模式测试**
进入Discuz后台 → 站长 → 邮件设置,将「邮件发送方式」改为「PHP函数发送」并提交,尝试手动发送测试邮件。
- **检查邮件队列**
进入数据库执行:
- SELECT COUNT(*) FROM pre_common_mailcron WHERE senddate=0;
复制代码
若存在大量未发送队列,需检查服务器CRON是否正常执行 `pre_common_mailcron` 表处理。
#### **5. 第三方插件冲突检测**
- **临时禁用非必要插件**
进入应用中心 → 插件列表,逐一禁用近期安装的插件(尤其是支付类、用户组类插件),测试购买流程。
- **审查插件钩子**
检查是否存在多个插件同时挂载 `order_paid` 或 `invite_generate` 钩子,可能导致逻辑冲突。
---
### **三、深度优化建议**
1. **开启Discuz调试模式**
修改 `config/config_global.php` 添加:
- $_config['debug'] = 1;
- $_config['dump_tables'] = 1;
复制代码
复现问题时观察具体SQL执行错误及PHP报错信息。
2. **日志追踪强化**
在支付插件回调入口添加日志记录:
- $log = date('Y-m-d H:i:s').' | '.json_encode($_POST).PHP_EOL;
- file_put_contents('./data/payment_callback.log', $log, FILE_APPEND);
复制代码
确认回调数据完整性。
3. **事务锁机制核查**
检查支付处理代码段是否包含完整的数据库事务:
- DB::transaction(function(){
- // 更新订单状态
- // 生成邀请码
- // 变更用户积分
- });
复制代码
避免部分操作失败导致数据不一致。
---
### **四、应急处理方案**
若问题急需解决,可通过以下方式临时修复:
- -- 强制标记订单为已付款
- UPDATE pre_common_order SET status=1 WHERE orderid='订单号';
- -- 手动生成邀请码
- INSERT INTO pre_invite (uid, code, dateline) VALUES ('用户UID', MD5(RAND()), UNIX_TIMESTAMP());
- -- 手动增加积分
- UPDATE pre_common_member_count SET extcredits2=extcredits2+1 WHERE uid='用户UID';
复制代码
---
请按以上步骤逐项排查,如仍存在具体环节报错,可提供相关日志片段或错误截图,以便进一步分析处理。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。 |