1. 回调事件示例
当任务完成(如人脸生成、视频生成、订单状态变更等)后,FacePick 会通过 Webhook 主动向您配置的地址发送事件通知,帮助您实时获取处理结果。当人物生成完成时,您将收到如下 JSON 数据(示例来自原型 30.png,占位地址统一为 api.demo.invalid,本工程不会真实推送):
{
"event": "face_generate.completed",
"request_id": "req_20250820_123456",
"status": "success",
"data": {
"face_id": "face_123",
"image_url": "https://api.demo.invalid/demo/xxx.png",
"resolution": "1024x1536"
},
"timestamp": "2025-08-20T10:24:36Z",
"signature": "fp_demo_not_valid_signature_example"
}示例中的 https://api.demo.invalid 与 fp_demo_not_valid_… 均为占位演示值;复制示例不会执行任何网络请求。
| 本页事件(原型 30) | 28 页事件列表 | 说明 |
|---|---|---|
| face_generate.completed | generation.completed(内容生成完成) | 本页主示例;字段含 face_id / image_url / resolution |
| order.completed | order.completed(订单完成) | 两页同名同字段(order_id / status / data) |
| character.online | character.online(角色上架) | 两页同名同字段(face_id / online_at) |
| character.offline | character.offline(角色下架) | 两页同名同字段(face_id / offline_at) |
| review.notified | review.notified(审核结果通知) | 两页同名同字段(review_id / result) |
| billing.charged | billing.charged(计费扣款) | 两页同名同字段(order_id / amount) |
原型差异已登记:30 页主示例使用事件名 face_generate.completed,与 28 页「内容生成完成」事件 generation.completed 命名不一致。上表明确了两页的对应关系;本页与 28 页共用同一份事件数据,不自行发起回调,也不各自发明事件。
2. 验证回调签名
为确保数据安全,FacePick 会在请求头中携带签名(X-FacePick-Signature),请使用你的密钥进行验证。以下为参考实现,基于原始请求体原文计算 HMAC-SHA256,并使用安全比较方式(常数时间比较,避免时序攻击):
import hmac
import hashlib
secret = b"fp_demo_webhook_secret_not_valid" # 演示 secret;生产由控制台签发并仅存服务端
body = request.get_data() # 原始请求体原文(不重排、不重编码)
signature = request.headers.get("X-FacePick-Signature", "")
expected = hmac.new(secret, body, hashlib.sha256).hexdigest()
# 使用安全比较(常数时间),避免时序攻击
if hmac.compare_digest(signature, expected):
print("签名验证通过")
else:
print("签名验证失败")示例中的 https://api.demo.invalid 与 fp_demo_not_valid_… 均为占位演示值;复制示例不会执行任何网络请求。
| 情形 | 处理建议 |
|---|---|
| 缺少签名 | 直接拒绝请求并返回明确的错误说明;不执行回调业务逻辑。 |
| 签名错误 | 拒绝请求,记录 request_id 与时间;排查 secret 是否一致、是否基于原始请求体原文计算。 |
| 重复事件 | 按 request_id / event_id 做幂等处理:已处理过的事件直接返回成功,不重复执行。 |
| 过期事件 | 按 timestamp 判断事件是否过期(示例阈值 5 分钟,以最终签名协议为准),过期事件丢弃并记录。 |
生产签名协议尚未确定并接入:以上为参考结构与演示 secret(fp_demo_webhook_secret_not_valid),不代表本工程已部署验签、防重放、审计或合规认证。接入真实回调能力时以正式协议与密钥为准。
3. 注意事项
- Webhook 地址必须使用 HTTPS,并建议在 5 秒内返回 200(与 28 页「如何配置 Webhook?」的配置要求一致)。
- 按 request_id / event_id 做幂等去重;重复事件直接返回成功,不重复执行业务。
- 签名 secret 只保存在服务端:不写入代码仓库、浏览器前端或日志。
- 本页与 28 页互相可达:28 讲如何配置,30 讲收到事件后如何处理;复制代码只复制文本,不运行代码、不探测填写的地址。
这篇文章对你有帮助吗?