# 甘草订单状态回调功能配置指南 ## 功能说明 实现甘草订单状态回调功能,当甘草订单状态发生变化时(如审核通过、制作中、发货、完成等),甘草系统会主动回调我们的接口,更新订单状态。 ## 已创建的文件 ### 1. 回调控制器 **文件:** `server/app/api/controller/GancaoCallbackController.php` **功能:** - 接收甘草订单状态回调 - 验证回调签名(防止伪造) - 更新订单状态 - 记录回调日志 **支持的订单状态:** - `10` - 系统审核中 - `11` - 系统审核通过 - `110` - 订单药房流转制作中(包含:派单、审方、调配、复核、浸泡、煎药、包装、发货等流程) - `20` - 物流中 - `30` - 完成(终态) - `90` - 拦截(终止流转:可恢复) - `91` - 主动撤单(退费:终态) - `92` - 驳回(无法制作并退费:终态) ### 2. 数据库迁移文件 **文件:** `add_gancao_callback_fields.sql` **新增字段:** - `gancao_order_state` - 甘草订单状态 - `gancao_flow_name` - 订单流程名称 - `gancao_supplier` - 供应商/药房名称 - `gancao_remark` - 订单备注 ## 配置步骤 ### 步骤 1: 执行数据库迁移 ```bash # 连接到数据库 mysql -u root -p your_database # 执行 SQL 文件 source /path/to/add_gancao_callback_fields.sql; # 或者直接执行 mysql -u root -p your_database < add_gancao_callback_fields.sql ``` ### 步骤 2: 添加路由 在 `server/route/api.php` 文件中添加回调路由: ```php (string) zyt_gancao_scm_env('CALLBACK_URL', ''), // 回调签名验证(如果甘草提供了独立的密钥) 'callback_appkey' => (string) zyt_gancao_scm_env('CALLBACK_APPKEY', ''), 'callback_secret_key' => (string) zyt_gancao_scm_env('CALLBACK_SECRET_KEY', ''), ]; ``` ### 步骤 5: 测试回调接口 #### 方法 A:使用 curl 测试 ```bash # 模拟甘草回调请求 curl -X POST https://your-domain.com/api/gancao/callback/order-status \ -H "Content-Type: application/json" \ -H "access-appkey: your_appkey" \ -H "access-nonce: test1234" \ -H "access-timestamp: $(date +%s)" \ -H "access-sign: calculated_sign" \ -d '{ "recipel_order_no": "GC202604...", "state": 11, "ext": { "flow_name": "审核通过" } }' ``` #### 方法 B:查看日志 ```bash # 查看回调日志 tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i "gancao callback" ``` ### 步骤 6: 向甘草提供回调地址 联系甘草技术支持,提供以下信息: 1. 回调地址:`https://your-domain.com/api/gancao/callback/order-status` 2. 确认回调签名验证方式 3. 测试回调是否正常 ## 回调数据格式 ### 请求头 ``` access-appkey: ak-xxxxx access-nonce: random_string access-timestamp: 1234567890 access-sign: md5_hash ``` ### 请求体 ```json { "recipel_order_no": "GC202604...", "state": 110, "ext": { "flow_name": "煎药开始", "supplier": "XX药房" } } ``` ### 状态 110(制作中)的扩展信息 ```json { "recipel_order_no": "GC202604...", "state": 110, "ext": { "flow_name": "派单|审方|调配|复核|浸泡|煎药开始|包装|发货|寄出", "supplier": "XX药房" } } ``` ### 状态 20(物流中)的扩展信息 ```json { "recipel_order_no": "GC202604...", "state": 20, "ext": { "shipping_name": "顺丰速运", "nu": "SF1234567890", "supplier": "XX药房" } } ``` ## 签名验证 ### 签名算法 ``` access_sign = md5(access-appkey + secret-key + access-nonce + access-timestamp + request_body) ``` ### 示例 ``` access-appkey: ak-36b05d5034f13a86b102c97e72f14 secret-key: f8c1f3c58b55a61a4d41242016d314ea access-nonce: 1jd4u8ii access-timestamp: 1723014934 Body: {"recipel_order_no":"1234","state":10,"ext":{"flow_name":"浸泡开始"}} 计算: md5("ak-36b05d5034f13a86b102c97e72f14" + "f8c1f3c58b55a61a4d41242016d314ea" + "1jd4u8ii" + "1723014934" + '{"recipel_order_no":"1234","state":10,"ext":{"flow_name":"浸泡开始"}}') = 03b46e3b385d1dceb183cad08e44f31f ``` ## 订单状态映射 ### 甘草状态 → 系统履约状态 | 甘草状态 | 状态名称 | 系统履约状态 | 说明 | |---------|---------|-------------|------| | 10 | 系统审核中 | 保持不变 | 甘草内部审核 | | 11 | 系统审核通过 | 保持不变 | 审核通过,准备制作 | | 110 | 订单药房流转制作中 | 2(履约中) | 药房制作流程 | | 110(发货) | 发货/寄出 | 5(已发货) | 药房已发货 | | 20 | 物流中 | 5(已发货) | 快递运输中 | | 30 | 完成 | 3(已完成) | 订单完成 | | 90 | 拦截 | 保持不变 | 订单被拦截 | | 91 | 主动撤单 | 4(已取消) | 撤单并退费 | | 92 | 驳回 | 4(已取消) | 无法制作并退费 | ## 日志记录 ### 回调接收日志 ``` [info] Gancao callback received: { "headers": {...}, "body": {...} } ``` ### 回调处理日志 ``` [info] Gancao callback processed: { "order_id": 123, "recipel_order_no": "GC202604...", "state": 110, "ext": {...} } ``` ### 订单日志 在 `zyt_prescription_order_log` 表中记录: - `admin_name`: "甘草系统" - `action`: "gancao_callback" - `summary`: "甘草订单状态更新:系统审核通过" ## 错误处理 ### 签名验证失败 ``` [warning] Gancao callback sign verification failed ``` **处理:** 返回 "ok",避免甘草重试 ### 订单不存在 ``` [warning] Gancao callback order not found ``` **处理:** 返回 "ok",记录日志 ### 更新失败 ``` [error] Gancao callback update order failed ``` **处理:** 返回 "ok",记录错误日志 ## 重试机制 甘草的重试策略: - 如果回调失败(未返回 "ok" 或超时),会进行重试 - 最多重试 10 次 - 重试间隔:失败次数 × 5 分钟 **建议:** 1. 接口必须在 5 秒内返回 "ok" 2. 使用异步处理复杂逻辑 3. 即使处理失败也返回 "ok",避免重复回调 ## 安全建议 1. **启用签名验证**:防止伪造回调 2. **记录所有回调**:便于排查问题 3. **限制访问频率**:防止恶意请求 4. **使用 HTTPS**:保护数据传输安全 5. **IP 白名单**:只允许甘草服务器 IP 访问(可选) ## 监控和告警 ### 监控指标 1. 回调接收数量 2. 签名验证失败次数 3. 订单更新失败次数 4. 回调处理耗时 ### 告警规则 1. 签名验证失败率 > 10% 2. 订单更新失败率 > 5% 3. 回调处理耗时 > 3 秒 ## 测试清单 - [ ] 数据库字段已添加 - [ ] 路由已配置 - [ ] 回调 URL 已配置 - [ ] 签名验证正常 - [ ] 订单状态更新正常 - [ ] 日志记录正常 - [ ] 错误处理正常 - [ ] 已向甘草提供回调地址 - [ ] 已测试真实回调 ## 故障排查 ### 问题 1:收不到回调 **检查:** 1. 回调 URL 是否正确 2. 服务器是否能从公网访问 3. 防火墙是否开放端口 4. 路由是否配置正确 ### 问题 2:签名验证失败 **检查:** 1. appkey 是否正确 2. secret-key 是否正确 3. 签名算法是否正确 4. 请求体是否被修改 ### 问题 3:订单状态未更新 **检查:** 1. 订单是否存在 2. 数据库字段是否添加 3. 更新逻辑是否正确 4. 查看错误日志 ## 相关文档 - 甘草 API 文档:https://apidoc.igancao.com/service-doc/scm-outer-recipel.html#订单状态回调 - ThinkPHP 路由文档:https://www.kancloud.cn/manual/thinkphp6_0/1037493