支付回调、物流轨迹、电商订单推送,都以入站 Webhook 打进 Odoo 19。正确模式是:验签 → 快速 ACK(HTTP 200)→ 业务异步入队;错误模式是:在控制器里同步建单过账,外部一超时重试,你这边就双单。本文覆盖签名校验、时间窗、幂等键、控制器职责边界与重放台。
验签与密钥管理
按对方文档校验签名头(HMAC、时间戳、nonce)。密钥放 ir.config_parameter 或密钥管理,不写死仓库。时间窗过期直接 401/403;IP 允许列表作为纵深防御。日志记录验签失败次数,防止暴力探接口。
快速 ACK:控制器只做两件事
验签通过后:写入「待处理」队列/日志行(含原始 payload 摘要与外部事件 id),立即返回 200。真正的 sale.order 创建、库存、过账放到 job 或 cron 消费者。响应体保持轻量;不要在 ACK 前访问慢外部系统。
幂等:外部事件 id 去重
用外部事件 id 做唯一约束。重试到达时返回「已处理」,不新建第二张业务单。业务消费者也要幂等:即使队列重复投递,也不会二次过账。建议状态机:received → processing → done/failed。
失败可重放
处理失败保留 payload 与错误;后台提供重放按钮(校验权限与幂等)。财务相关入站重放需人工确认。监控错误率与积压,并入「队列/邮件/Webhook」告警通道。
验收标准
- 错误签名被拒绝;正确签名快速 200。
- 同一事件 id 只生成一张业务单。
- 消费者失败可在后台重放并留操作人痕迹。
控制器与消费者的职责切分示例
控制器:读签名头 → 校验时间窗 → 按外部事件 id 查重 → 写入 inbox 行 → 返回 200。 消费者:加锁领取 inbox → 映射为业务单据 → 写回 inbox 状态 → 失败写入错误并通知集成负责人。 inbox 表保留原始 body(注意脱敏与留存周期)。压测时用重放工具连打同一事件 id, 断言业务单始终一张。密钥轮换要有双密钥窗口,避免切换瞬间大量 401。
入站接口文档对外只暴露:URL、签名算法、时间窗、事件 id 字段、响应码含义;不暴露内部模型名给不必要的人。
安全测试用例(上线前必过)
1)缺签名/错签名 → 401/403 且不落业务单;2)过期时间戳 → 拒绝;3)同一事件 id 重放 10 次 → 业务单仍 1 张;
4)正确签名但消费者抛错 → HTTP 已 200,inbox 为 failed,可重放;5)超大 body → 拒收或截断策略符合文档。
密钥仅存 ir.config_parameter 或密钥服务;代码库扫描禁止出现真实密钥。
接入新渠道复制「验签+ACK+幂等」模板,禁止每个开发自创一套。
生产打开详细 payload 日志时注意个保与脱敏;默认只留哈希与关键业务键。
新渠道接入复用验签中间件,禁止复制粘贴后改半套算法。
预生产勾选表需覆盖文章编号 316 全部验收点后再约生产窗口。
将文章编号 316 的配置变更记入发版说明,便于回滚对照。
将文章编号 316 的配置变更记入发版说明,便于回滚对照。
将文章编号 316 的配置变更记入发版说明,便于回滚对照。
将文章编号 316 的配置变更记入发版说明,便于回滚对照。
中国Odoo网|对照 Odoo 19 企业版入站 Webhook 实践:验签、快速 ACK、事件 id 幂等,业务异步消化。