179 lines
4.5 KiB
Markdown
179 lines
4.5 KiB
Markdown
# V免签微信协议改造说明
|
||
|
||
这个目录用于给其他用户复用本次 V免签 服务端改造。
|
||
|
||
## 目录说明
|
||
|
||
- `route.php`
|
||
V免签路由文件改造后的完整版本。
|
||
- `Index.php`
|
||
`application/index/controller/Index.php` 改造后的完整版本。
|
||
|
||
## 本次改造解决了什么
|
||
|
||
原版 V免签 更适合传统监控端通过金额回调 `appPush` 完成订单。
|
||
这次改造的目标是让一个独立的微信协议监听客户端可以:
|
||
|
||
1. 从 V免签 服务端拉取当前未支付订单
|
||
2. 在本地监听到微信到账后,按 `orderId` 精确回推指定订单
|
||
3. 继续复用 V免签 原本的异步通知逻辑通知商户站点
|
||
|
||
这样就避免了以下问题:
|
||
|
||
- 只按金额匹配,多个同金额订单时容易串单
|
||
- 监听端找不到待支付订单时,错误地把微信交易号直接当作 `payId` 去回调
|
||
- 服务端根域名被误请求,返回首页 HTML 而不是订单处理结果
|
||
|
||
## 服务端新增接口
|
||
|
||
### 1. `getPendingOrders`
|
||
|
||
用途:
|
||
给客户端拉取当前待支付订单列表。
|
||
|
||
请求方式:
|
||
`GET` 或 `POST`
|
||
|
||
参数:
|
||
|
||
- `t`
|
||
当前时间戳
|
||
- `sign`
|
||
签名,算法:`md5(t + 通讯密钥)`
|
||
- `type`
|
||
支付类型,微信传 `1`,支付宝传 `2`
|
||
|
||
返回:
|
||
返回 `state=0` 的待支付订单列表,包含:
|
||
|
||
- `payId`
|
||
- `orderId`
|
||
- `param`
|
||
- `payType`
|
||
- `price`
|
||
- `reallyPrice`
|
||
- `state`
|
||
- `timeOut`
|
||
- `date`
|
||
|
||
### 2. `appPushOrder`
|
||
|
||
用途:
|
||
客户端本地匹配到具体订单后,通知 V免签 将指定订单置为已支付。
|
||
|
||
请求方式:
|
||
`GET` 或 `POST`
|
||
|
||
参数:
|
||
|
||
- `orderId`
|
||
云端订单号
|
||
- `tradeNo`
|
||
微信侧交易号
|
||
- `t`
|
||
当前时间戳
|
||
- `sign`
|
||
签名,算法:`md5(orderId + tradeNo + t + 通讯密钥)`
|
||
|
||
处理流程:
|
||
|
||
1. 校验签名
|
||
2. 查询对应 `orderId`
|
||
3. 订单状态必须为 `0`
|
||
4. 更新订单为已支付
|
||
5. 调用原有商户异步通知
|
||
6. 成功返回 JSON,失败则把订单状态更新为 `2`
|
||
|
||
## 需要修改的原项目文件
|
||
|
||
如果你自己的 V免签 项目结构和原版一致,只需要替换:
|
||
|
||
- `route/route.php`
|
||
- `application/index/controller/Index.php`
|
||
|
||
建议替换前先备份原文件。
|
||
|
||
## 部署步骤
|
||
|
||
1. 备份线上原文件
|
||
2. 用本目录中的 `route.php` 覆盖线上 `route/route.php`
|
||
3. 用本目录中的 `Index.php` 覆盖线上 `application/index/controller/Index.php`
|
||
4. 确认线上缓存已刷新
|
||
5. 重新测试客户端与 V免签 的联动
|
||
|
||
## 验证方法
|
||
|
||
### 验证 1:拉取待支付订单
|
||
|
||
先在 V免签 后台或发卡程序创建一笔新的微信订单,确保订单未过期。
|
||
|
||
然后请求:
|
||
|
||
```text
|
||
https://你的域名/getPendingOrders?t=当前时间戳&sign=md5(t+通讯密钥)&type=1
|
||
```
|
||
|
||
如果成功,应该返回 JSON,`data` 中能看到待支付微信订单。
|
||
|
||
### 验证 2:按订单推送成功
|
||
|
||
当客户端匹配到订单后,应请求:
|
||
|
||
```text
|
||
https://你的域名/appPushOrder?orderId=云端订单号&tradeNo=微信交易号&t=当前时间戳&sign=md5(orderId+tradeNo+t+通讯密钥)
|
||
```
|
||
|
||
成功时应返回类似:
|
||
|
||
```json
|
||
{"code":1,"msg":"成功","data":null}
|
||
```
|
||
|
||
## 与原版的关键差异
|
||
|
||
### 原版 `appPush`
|
||
|
||
原版只按下面三个条件查单:
|
||
|
||
- `really_price`
|
||
- `state=0`
|
||
- `type`
|
||
|
||
这种方式在同金额并发订单下容易误匹配。
|
||
|
||
### 改造后的 `appPushOrder`
|
||
|
||
改造后由客户端先拉待支付订单,再在本地完成:
|
||
|
||
- 金额匹配
|
||
- 时间范围过滤
|
||
- 精确得到 `orderId`
|
||
|
||
最后再回推给服务端,服务端按 `orderId` 精确处理,不再依赖“金额即订单”。
|
||
|
||
## 适用场景
|
||
|
||
适用于以下场景:
|
||
|
||
- 自己有独立的微信监听客户端
|
||
- 不希望直接改发卡系统创建订单逻辑
|
||
- 想保留 V免签 现有订单表、商户通知和后台逻辑
|
||
- 想把“支付监听”和“订单完成”拆成两段处理
|
||
|
||
## 注意事项
|
||
|
||
1. `getPendingOrders` 只会返回未过期且 `state=0` 的订单
|
||
2. 如果客户端一直拉到 `0` 条订单,先检查订单是否已经过期
|
||
3. 如果客户端监听到了微信收款,但没匹配到订单,不应该再回调根域名
|
||
4. 商户异步通知仍然依赖原表中的 `notify_url`
|
||
5. 如果你在服务端做了二次开发,替换前先比对自定义逻辑
|
||
|
||
## 推荐客户端配合逻辑
|
||
|
||
为了避免刷历史收款记录,客户端建议再做两件事:
|
||
|
||
1. 启动协议监听时忽略历史账单,只处理启动后的新收款
|
||
2. 正常轮询成功时不要持续打印日志,只在状态变化、检测到收款或异常时打印
|
||
|
||
这样用户体验会更好,也更容易排查问题。
|