# POST /api/v1/ad/reward-noshow — 激励视频提前关闭/未发奖留痕 激励视频**展示了但用户提前关闭/跳过、未触发 S2S 发奖**时,客户端 best-effort 上报一条留痕记录, 让运营后台「广告数据」能呈现「有展示、没发金币」的原因。**不发金币**。 ## 鉴权 需要 Bearer token。`user_id` 由 JWT 取,不在 body。 ## 请求体 | 字段 | 类型 | 必填 | 说明 | |---|---|---:|---| | `ad_session_id` | string | 是 | 本次展示会话 id(与 eCPM 上报、S2S `extra.ad_session_id` 一致),8-64 字符 | | `watched_seconds` | int | 否 | 关闭前已观看秒数(仅留痕参考,**不入库**)。默认 0 | | `ecpm` | string\|null | 否 | 本次展示 eCPM(穿山甲 getEcpm 原值,分/千次展示) | | `adn` | string\|null | 否 | 实际投放 ADN(聚合后实际填充子渠道) | | `slot_id` | string\|null | 否 | 实际展示代码位(底层 mediation rit) | | `app_env` | string\|null | 否 | **我们的**应用环境:`prod`(傻瓜比价正式) / `test`(测试应用) | | `our_code_id` | string\|null | 否 | **我们后台配置的**代码位 ID(104xxx,非底层 rit) | ## 响应 | 字段 | 类型 | 说明 | |---|---|---| | `ok` | bool | 是否处理成功(落库或幂等命中) | | `status` | string | `closed_early`(已留痕) / `granted`(该次其实已发奖,跳过未写) | ## 说明 - 在 `onAdClose` 时若本次**未触发发奖**(无 `onRewardVerify`/`onRewardArrived`)调用。 - **幂等**:写入 `ad_reward_record`,`trans_id = noreward:{ad_session_id}`(每次展示唯一),重试不重复。 - **防与正常发奖重复**:若同一 `ad_session_id` 已有 `status='granted'` 记录(S2S 已发,说明用户其实看完了), 则跳过不写,返回 `status='granted'`。 - best-effort:客户端 fire-and-forget,失败只 log,不影响主流程。 - 信息流的「用户中途关闭」走 [ad-feed-reward](./ad-feed-reward.md) 的 `aborted=true`(记 `closed_early`),不走本接口。 ## 数据写入 - `ad_reward_record` 新增一行(`coin=0`、`status='closed_early'`、`reward_scene='reward_video'`)。 - **不**写 `coin_account` / `coin_transaction`(不发币)。