跳转到内容

广告奖励概览

Kasskeep 只负责激励广告中的一层:证明用户确实把广告看完了。它接收广告网络的服务端奖励回调,校验、去重,然后给你的后端发一个 ad.reward 事件,签名和投递方式与购买事件完全相同。

竞价和填充仍由你的聚合平台负责。每日上限、发什么奖励、发不发,仍由你的后端决定。

广告网络 回调 校验方式
AdMob GET /v1/ads/admob/:app_id/ssv 用 Google 公布的公钥校验 ECDSA 签名
AppLovin MAX GET /v1/ads/applovin/:app_id/s2s sha1(event_id + Event Key)
Unity LevelPlay GET /v1/ads/levelplay/:app_id/s2s md5(timestamp + eventId + appUserId + rewards + privateKey)、时间戳窗口、可选 IP 允许列表
  1. 把你的统一广告位名映射到各广告网络的广告位 id。见广告位映射。
  2. 在 App 里调用 Kasskeep.ads.showRewarded({ adUnit: "revive" })。SDK 把用户 id 和参数传给你的广告 SDK,让它们随服务端回调一起返回。
  3. 广告网络回调 Kasskeep。Kasskeep 校验、映射广告位,并只记录一次奖励。
  4. 你的后端收到 ad.reward,发放奖励。
{
"id": "evt_...",
"type": "ad.reward",
"created_at": "2026-11-06T08:00:01.000Z",
"app_user_id": "6f1c...",
"platform": "android",
"environment": "production",
"product_id": null,
"transaction_id": "9b3e1c6a-1f2d-4c0e-9a77-5d4f3b2a1c00",
"original_transaction_id": null, "purchased_at": null, "expires_at": null, "price_micros": null, "currency": null, "ownership": null,
"data": {
"app_user_id": "6f1c...",
"network": "applovin",
"ad_unit": "revive",
"network_ad_unit_id": "a1b2c3d4e5f60718",
"reward_type": "gems",
"reward_amount": 5,
"network_transaction_id": "9b3e1c6a-1f2d-4c0e-9a77-5d4f3b2a1c00",
"custom_data": "stage=3",
"environment": "production",
"occurred_at": "2026-11-06T08:00:00.000Z"
}
}

data 的十个字段总是存在(未知时为 null)。顶层 platform 在 MAX 提供时为 ios 或 android,AdMob 和 LevelPlay 为 null,测试模式下为 test。奖励不会出现在客户的购买或订阅里。

奖励在 App、广告网络和广告网络交易 id(AdMob 的 transaction_id、MAX 的 event_id、LevelPlay 的 eventId)的组合内唯一。重试返回 200 {"outcome": "duplicate", "event_id": ...},绝不会产生第二个事件。事件 id 由同一个键派生,所以一次观看只有一个 id,不管收到多少次回调。

回调响应:

结果 含义
recorded 首次收到,已创建事件
duplicate 已记录过,event_id 相同
unmapped_ignored 广告位未映射,且该 App 拒绝未映射的广告位
ignored 签名有效但没有用户 id,比如广告网络控制台的测试
  1. 像处理其他事件一样校验签名。
  2. 按事件 id 去重。
  3. 正式环境中拒绝 environment: "test"。
  4. 执行你自己的上限和规则。Kasskeep 不限制一个用户能拿多少奖励。
  5. custom_data 来自客户端。用它做关联(比如关卡编号),绝不要用它决定奖励数量。

用户最近的奖励可以从 GET /v1/customers/:app_user_id/ad-rewards 读取,用于展示和客服。奖励只能根据回调发放。