Files
shaguabijia-app-server/docs/integrations/pangle.md
T
ouzhou 04edb50acc feat(admin/ad): 提现自动对账后台开关 + 客户端广告 flags 端点 + 穿山甲多 m-key 验签 (#59)
- 自动对账接入 app_config 运行时配置(新增 bool 配置类型):env 部署总闸 + DB 运营日常开关
  双层;worker 每轮读 DB 即时生效,健康检查改报「env AND DB」实际生效态
- 新增 GET /api/v1/platform/flags(不鉴权)下发 comparing_ad_enabled 远程 kill-switch,
  客户端拉取后缓存;空库回退默认 True
- 穿山甲发奖回调支持多激励位 m-key(三命名项 PANGLE_REWARD_SECRET_TEST/_DEDICATED/_PROD
  + 旧逗号分隔合并去重),verify_callback_sign_any 逐个验签任一通过即受理;向后兼容旧单 key
- 补 test_platform / bool config 用例;app_config 文档同步

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: OuYingJun1024 <1034284404@qq.com>
Reviewed-on: #59
Co-authored-by: ouzhou <ouzhou@wonderable.ai>
Co-committed-by: ouzhou <ouzhou@wonderable.ai>
2026-06-17 10:37:54 +08:00

3.1 KiB
Raw Blame History

穿山甲激励视频发奖回调 — 验签(pangle)

文件:app/integrations/pangle.py | 关联接口:ad-pangle-callback | ← 集成索引

作用

穿山甲激励视频播完后,穿山甲服务器会 GET 回调我们的 /api/v1/ad/pangle-callback(带 user_id / trans_id / sign 等 query)。本模块负责验签,确认回调真来自穿山甲而非伪造请求;验签通过后由数据层(repositories/ad_reward)幂等发金币。客户端不参与发奖,被破解也刷不到钱。

验签方案(关键)

sign = SHA256("{m-key}:{trans_id}") 的十六进制串。

  • 普通 SHA256,不是 HMAC,也不是 RSA。
  • 只对 m-key:trans_id 这一个字符串签名,user_id / ecpm / extra 等其余参数不参与签名。它们的可信度由"能算出正确 sign = 知道 m-key"间接保证——伪造者没有 m-key 连合法 sign 都造不出,自然无法注入假 user_id
  • 这是穿山甲 GroMore「广告位 → 服务端激励回调」官方规范supportcenter/26240)。我们客户端是 useMediation(true) 融合,回调走 GroMore 广告位层级,不是联盟代码位层级。

函数

函数 说明
build_sign(trans_id, secret) -> str 计算 SHA256("{secret}:{trans_id}") hex。自验签测试 / 模拟回调脚本共用,保证两端一致
verify_callback_sign(params, secret) -> bool 单个 m-key 校验回调签名。密钥空 / 缺 trans_id 一律失败;比较用 hmac.compare_digest 定长比较防时序侧信道
verify_callback_sign_any(params, secrets) -> bool 一组 m-key 逐个验签、任一通过即接受(多激励位共用同一回调 URL 时用)。空列表 → 失败

配置(多激励位 = 多 m-key)

每个 GroMore 激励位的 m-key 由后台各自生成、互不相同,但本服务用同一个回调 URL 接所有位的回调,因此把用到的位的 m-key 都配上;验签时 verify_callback_sign_any 逐个试、任一过即接受(仍安全:伪造者须知道其中某个 m-key 才能造出合法 sign)。m-key 在后台「GroMore 聚合管理 → 搜广告位 ID → 编辑」处获取。settings.pangle_reward_secrets 把下列来源汇总去重:

配置项 说明
PANGLE_REWARD_SECRET_TEST 测试应用 激励位 104099649 的 m-key
PANGLE_REWARD_SECRET_TEST_DEDICATED 测试应用 专属激励位 104127529 的 m-key
PANGLE_REWARD_SECRET_PROD 正式应用 激励位 104099389 的 m-key
PANGLE_REWARD_SECRET 旧用法:单个或逗号分隔多个 m-key,仍兼容(与上面三个命名项合并去重)

踩坑

  • 别用联盟代码位那套:联盟代码位层级用的是另一套 Security Key + isValid 响应体,与 GroMore 广告位层级不通用。我们走 GroMore,别接错。
  • 验签失败时 api 层返 403(留给真请求重试);验签过但参数缺/坏或 user 不存在,则受理不发奖、不让穿山甲重试。
  • 本地无公网、回调打不到时,用 ad-test-grant 模拟(仅联调,开关控制)。