18 KiB
91porn 付费引导 Ping 下发接口文档
对接对象:App/H5 前端
文档状态:已按测试确认的最终规则更新,后端接口与 Web 配置能力已同步实现
目标:普通付费引导弹窗随 Ping 一次性下发,弹窗触发时不再临时请求接口;会员内容上新仍使用独立接口实时判断。
1. 调整概要
付费引导共有 7 个场景编码:
| 场景 | 说明 | 新版前端取值方式 |
|---|---|---|
HOME_NEW_USER_FREE_TRIAL |
首页新用户免费 X 次试看;X 取系统配置 totalWatchCount |
Ping 下发 |
HOME_OLD_USER |
首页老用户引导;与新用户免费试看场景共用首页开关 | Ping 下发 |
VIDEO_PREVIEW_END |
视频试看 3 秒引导 | Ping 下发 |
DISCOUNT_COUNTDOWN |
优惠倒计时弹窗 | Ping 下发 |
VIDEO_BACK |
退出视频时引导 | Ping 下发 |
VIP_CENTER |
会员中心引导 | Ping 下发 |
VIP_CONTENT_UPDATE |
会员内容上新引导 | 独立接口实时查询 |
新版前端处理规则:
- App/H5 启动时读取 Ping 中的
paymentGuide并缓存。 - 前 6 个普通场景在触发时直接读取 Ping 缓存,不再调用付费引导查询接口。
VIP_CONTENT_UPDATE必须实时查询最新视频、contentVersion及展示状态,继续调用独立接口。show字段保留。普通场景以 Ping 中的show为准,上新场景以独立接口的show为准。- 首页新用户免费试看、视频试看 3 秒、App 活跃 3 分钟等触发时机仍由前端控制。
DISCOUNT_COUNTDOWN的倒计时由前端在每次 App 冷启动时重新创建,固定为 2 小时;后端不计算或下发倒计时起止时间,也不使用durationSeconds作为倒计时。- 除
DISCOUNT_COUNTDOWN外,普通弹窗实际展示后,前端调用展示回执接口,并在本地立即将该场景的show设为false,防止同一次启动重复展示。
2. 枚举
2.1 场景 scene
HOME_NEW_USER_FREE_TRIAL
HOME_OLD_USER
VIDEO_PREVIEW_END
DISCOUNT_COUNTDOWN
VIDEO_BACK
VIP_CENTER
VIP_CONTENT_UPDATE
2.2 用户分层 segment
NEW_NEVER_PAID
OLD_NEVER_PAID
PAID_UPGRADE
MAX_VIP
NORMAL
UNREGISTERED
未付费用户的新老分层只按注册时间判断:注册不足 24 小时为 NEW_NEVER_PAID,达到 24 小时后为 OLD_NEVER_PAID。免费观看次数不会改变全局用户分层;次数用完时仅将 HOME_NEW_USER_FREE_TRIAL.show 置为 false。
3. Ping 全量接口
3.1 App
GET /api/app/ping/domain
3.2 H5
GET /api/app/ping/domain/h5
两个接口的 data 均新增 paymentGuide,其他字段保持不变。
3.3 响应示例
{
"code": 200,
"msg": "success",
"data": {
"paymentGuide": {
"enabled": true,
"segment": "OLD_NEVER_PAID",
"scenes": {
"HOME_NEW_USER_FREE_TRIAL": {
"enabled": false,
"show": false,
"totalWatchCount": 3
},
"HOME_OLD_USER": {
"enabled": true,
"show": true,
"configId": "6889f2014a4fcb5012340001",
"style": "BOTTOM_SHEET",
"title": "开通会员",
"description": "开通会员后可观看完整影片",
"cover": "20260804/payment-guide/home-old-user.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"VIDEO_PREVIEW_END": {
"enabled": true,
"show": true,
"configId": "6889f2014a4fcb5012340002",
"style": "CENTER_POPUP",
"title": "试看 3 秒",
"description": "开通会员观看完整内容",
"cover": "20260804/payment-guide/preview-end.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"DISCOUNT_COUNTDOWN": {
"enabled": true,
"show": true,
"configId": "6889f2014a4fcb5012340006",
"style": "CENTER_POPUP",
"title": "现在下单获得优惠福利",
"description": "距优惠结束",
"cover": "20260804/payment-guide/discount-countdown.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"VIDEO_BACK": {
"enabled": true,
"show": false,
"configId": "6889f2014a4fcb5012340004",
"style": "CENTER_POPUP",
"title": "退出视频引导",
"description": "开通会员观看更多内容",
"cover": "20260804/payment-guide/video-back.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"VIP_CENTER": {
"enabled": true,
"show": true,
"configId": "6889f2014a4fcb5012340003",
"style": "CENTER_POPUP",
"title": "限时会员福利",
"description": "立即开通",
"cover": "20260804/payment-guide/vip-center.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 7200,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"VIP_CONTENT_UPDATE": {
"enabled": true
}
}
}
}
}
3.4 paymentGuide 字段
| 字段 | 类型 | 说明 |
|---|---|---|
enabled |
Boolean | 付费引导全局开关;为 false 时所有场景均不展示 |
segment |
String | 当前用户的付费引导分层 |
scenes |
Object | 按场景编码索引的引导配置 |
3.5 普通场景字段
| 字段 | 类型 | 必定返回 | 说明 |
|---|---|---|---|
enabled |
Boolean | 是 | 当前场景是否有匹配用户分层、在有效期内且已启用的配置 |
show |
Boolean | 是 | 当前用户此次是否允许展示;已展示过对应配置时为 false |
configId |
String | enabled=true 时 |
配置 ID,展示回执时原样传回 |
style |
String | enabled=true 时 |
弹窗样式编码 |
title |
String | enabled=true 时 |
标题 |
description |
String | enabled=true 时 |
描述,可为空字符串 |
cover |
String | enabled=true 时 |
封面图,可为空字符串;相对路径按现有静态资源域名规则拼接 |
productId |
String | enabled=true 时 |
会员商品 ID,可为空字符串 |
durationSeconds |
Number | enabled=true 时 |
配置中的兼容时长字段,可为 0;不用于 DISCOUNT_COUNTDOWN 的前端 2 小时倒计时 |
action.type |
String | enabled=true 时 |
操作类型:VIP_PRODUCT/INTERNAL/EXTERNAL/NONE |
action.value |
String | enabled=true 时 |
会员商品 ID、内链地址、外链地址或空字符串 |
只要普通场景存在有效配置,以上卡片字段都会完整返回,与 show 是 true 还是 false 无关。无有效配置、全局开关关闭或首页共用开关关闭时,对应场景只返回 enabled=false、show=false。
enabled 与 show 的区别:
enabled |
show |
含义 |
|---|---|---|
false |
false |
无有效配置,或全局开关已关闭 |
true |
false |
配置有效,但当前用户已展示过或不满足该场景的实时展示条件;仍返回完整卡片字段 |
true |
true |
配置有效且当前用户可展示 |
DISCOUNT_COUNTDOWN 不使用后端历史展示记录进行拦截:只要配置有效且相关开关开启,Ping 中始终返回 enabled=true、show=true。同一次启动只弹一次由前端本地控制;下次 App 冷启动重新开始本地 2 小时倒计时。
HOME_NEW_USER_FREE_TRIAL 和 HOME_OLD_USER 共用同一个首页引导开关。新用户免费试看场景额外返回 totalWatchCount;当新用户剩余免费观看次数为 0 时,该场景保持 enabled=true 并返回完整卡片配置,但 show=false。HOME_NEW_USER 仅保留后端兼容识别,不再通过 Ping 或 Web 配置列表返回。
VIP_CONTENT_UPDATE 在 Ping 中只返回 enabled;前端不得使用 Ping 推断该场景的 show,必须调用第 5 节的独立接口。
4. Ping 增量刷新
GET /api/app/ping/domain/refresh?keys=paymentGuide
适用时机:
- 用户登录成功。
- 用户退出登录。
- 会员购买成功或会员状态变化。
- 前端需要主动更新 Ping 缓存时。
不应在准备弹出普通弹窗时调用此接口。
响应示例:
{
"code": 200,
"msg": "success",
"data": {
"paymentGuide": {
"enabled": true,
"segment": "PAID_UPGRADE",
"scenes": {
"HOME_NEW_USER_FREE_TRIAL": {
"enabled": false,
"show": false,
"totalWatchCount": 3
},
"HOME_OLD_USER": {
"enabled": false,
"show": false
},
"VIDEO_PREVIEW_END": {
"enabled": false,
"show": false
},
"DISCOUNT_COUNTDOWN": {
"enabled": false,
"show": false
},
"VIDEO_BACK": {
"enabled": true,
"show": true,
"configId": "6889f2014a4fcb5012340004",
"style": "CENTER_POPUP",
"title": "升级会员",
"description": "升级后可观看更多内容",
"cover": "20260804/payment-guide/upgrade.png",
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 0,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
},
"VIP_CENTER": {
"enabled": false,
"show": false
},
"VIP_CONTENT_UPDATE": {
"enabled": true
}
}
}
}
}
5. 会员内容上新引导
5.1 获取引导
GET /api/app/payment/guide?scene=VIP_CONTENT_UPDATE
Authorization: {App用户token}
调用前建议先判断:
paymentGuide.enabled == true
&& paymentGuide.scenes.VIP_CONTENT_UPDATE.enabled == true
满足后再调用独立接口。最终是否展示必须以该接口返回的 show 为准。
5.2 show=true 响应
{
"code": 200,
"msg": "success",
"data": {
"show": true,
"configId": "6889f2014a4fcb5012340005",
"contentVersion": "4a7cbdb742c44a47",
"segment": "OLD_NEVER_PAID",
"style": "BOTTOM_SHEET",
"title": "查看完整影片",
"description": "开通会员后可观看",
"cover": "20260804/payment-guide/content-update.png",
"videos": [
{
"id": "videoId",
"title": "视频标题",
"cover": "20260804/video/cover.jpg",
"coverThumb": "20260804/video/cover-thumb.jpg",
"playTime": 1384,
"playCount": 12000
}
],
"productId": "6889f2014a4fcb5012349999",
"durationSeconds": 7200,
"action": {
"type": "VIP_PRODUCT",
"value": "6889f2014a4fcb5012349999"
}
}
}
5.3 show=false 响应
{
"code": 200,
"msg": "success",
"data": {
"show": false,
"segment": "OLD_NEVER_PAID"
}
}
show=false 时不展示弹窗。常见原因:
- 付费引导全局开关已关闭。
- 无匹配当前场景、用户分层和有效期的配置。
- 当前
contentVersion已展示过。 - 当前没有符合条件的最新会员视频。
视频数量由 Web 后台对应配置的 videoLimit 控制;未配置或为 0 时默认 4 条,最大 20 条。
6. 展示回执
POST /api/app/payment/guide/impression
Authorization: {App用户token}
Content-Type: application/json
6.1 普通场景(不含优惠倒计时)
{
"configId": "6889f2014a4fcb5012340002",
"scene": "VIDEO_PREVIEW_END",
"contentVersion": "",
"videoId": "videoId",
"requestId": "6f2e26f7-6e86-40eb-9276-6d45f79eae9f"
}
6.2 会员内容上新场景
{
"configId": "6889f2014a4fcb5012340005",
"scene": "VIP_CONTENT_UPDATE",
"contentVersion": "4a7cbdb742c44a47",
"videoId": "videoId",
"requestId": "e14ae540-a5d2-4a6a-8740-c3e9877545f1"
}
6.3 请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
configId |
String | 是 | Ping 或上新引导接口返回的配置 ID |
scene |
String | 是 | 实际展示的场景 |
contentVersion |
String | 上新场景必填 | 普通场景传空字符串;VIP_CONTENT_UPDATE 必须原样传回 |
videoId |
String | 否 | 相关视频 ID,无视频上下文时传空字符串或省略 |
requestId |
String | 是 | 本次回执的 UUID;重试必须复用同一个 UUID |
成功响应:
{
"code": 200,
"msg": "success",
"data": ""
}
前端注意:
- 只有弹窗真正展示成功后才上报,接口返回
show=true但未展示时不上报。 - 上报发起后立即在本地将对应场景的
show设为false,避免同一次启动重复展示。 - 网络失败可使用相同
requestId有界重试,不要为同一次展示生成多个requestId。 DISCOUNT_COUNTDOWN无需调用展示回执;其同一次启动去重和每次冷启动重置均由前端本地处理。兼容版本即使上报该场景,也不会影响后续 Ping 的show。
7. Web 后台配置接口
现有付费引导配置接口结构保持不变:
GET /api/web/admin/payment-guide/list?scene={scene}&pageNumber=1&pageSize=20
POST /api/web/admin/payment-guide/add
POST /api/web/admin/payment-guide/edit
DELETE /api/web/admin/payment-guide/delete?id={id}
列表响应新增 sceneOptions,后台下拉应直接使用该字段,不再硬编码场景名称。示例:
{
"sceneOptions": [
{
"label": "首页新用户免费3次试看",
"value": "HOME_NEW_USER_FREE_TRIAL",
"totalWatchCount": 3
}
]
}
HOME_NEW_USER 不会出现在 sceneOptions 或默认配置列表中,也不能再新增、编辑为该旧场景。
全局开关新增系统配置:
vCode: paymentGuideEnabled
type: bool
首页新用户免费试看、老用户共用开关新增系统配置:
vCode: paymentGuideHomeEnabled
type: bool
全局开关继续复用现有系统配置查询和更新接口,不新增 Web API。
首页引导只提供一个开关,同时控制 HOME_NEW_USER_FREE_TRIAL 和 HOME_OLD_USER;两个场景的用户分层、素材和弹窗内容仍可分别配置。后台不得再展示旧 HOME_NEW_USER 或两个独立的首页开关。
DISCOUNT_COUNTDOWN 按普通付费引导场景配置卡片内容、用户分层、启用状态和有效期。倒计时固定 2 小时并由前端每次 App 冷启动重新开始,后端配置中的 durationSeconds 不参与该倒计时。
8. 兼容性
GET /api/app/payment/guide?scene={scene}支持当前 7 个可配置场景;旧HOME_NEW_USER仍可被后端识别但固定不展示。- 新版前端只在
VIP_CONTENT_UPDATE场景调用该接口。 - 原接口的
show字段保留,不做破坏性删除。 - Ping 新增字段对旧版本属于向后兼容的增量字段。
- 旧的
paymentStatusPopupConfig在旧客户端完成淘汰前继续保留,新客户端不得同时展示旧弹窗和新付费引导弹窗。
9. 前端接入流程
9.1 启动与缓存
- 调用全量 Ping。
- 使用成功响应的
paymentGuide覆盖本地缓存。 - Ping 网络失败时可使用最近一次成功缓存;首次安装且无缓存时默认不展示,不得自行假定
show=true。
9.2 普通场景(不含优惠倒计时)
- 前端达到场景触发条件。
- 检查
paymentGuide.enabled。 - 检查
paymentGuide.scenes[scene].enabled和show。 - 两者均为
true时展示 Ping 中的弹窗配置。 - 展示成功后上报回执,并在本地将该场景的
show设为false。
9.3 会员内容上新
- 前端达到上新弹窗检查时机。
- 检查 Ping 的全局开关及
VIP_CONTENT_UPDATE.enabled。 - 启用时调用上新引导接口。
- 只有接口返回
show=true时才展示。 - 展示成功后携带原始
contentVersion上报回执。
9.4 优惠倒计时
- 读取
paymentGuide.scenes.DISCOUNT_COUNTDOWN。 enabled=true且show=true时展示倒计时弹窗。- 每次 App 冷启动在前端本地重新创建固定 2 小时倒计时;不读取
durationSeconds、绝对结束时间或旧配置的lastDiscountTime。 - 同一次启动只展示一次由前端本地状态控制;无需调用展示回执,下次冷启动可再次展示。
9.5 用户状态变化
登录、退出或会员状态变化后,调用 Ping 增量刷新并替换本地 paymentGuide 缓存。
10. 联调检查项
- 全局开关关闭时,所有普通场景不展示,上新场景不调用独立接口。
- 场景无有效配置时,返回
enabled=false和show=false。 - 配置有效但已展示时,返回
enabled=true、show=false和完整卡片字段。 - 注册不足 24 小时且剩余免费观看次数为 0 时,仍返回
segment=NEW_NEVER_PAID;仅HOME_NEW_USER_FREE_TRIAL.show=false,不得匹配仅配置给OLD_NEVER_PAID的其他场景。 - 用户分层改变后,增量刷新返回新分层的配置。
HOME_NEW_USER_FREE_TRIAL和HOME_OLD_USER由同一个首页开关控制;旧HOME_NEW_USER不再返回。VIDEO_PREVIEW_END的业务含义为“视频试看 3 秒”,不再使用“视频试看结束”文案。DISCOUNT_COUNTDOWN无有效配置时不展示;有有效配置且开关开启时 Ping 始终返回完整卡片及show=true。DISCOUNT_COUNTDOWN每次 App 冷启动由前端重新创建固定 2 小时倒计时,后端不计算倒计时,也不依据展示回执抑制下一次启动。- 普通场景触发时不发起付费引导查询请求。
- 上新场景仅在 Ping 对应开关开启时调用独立接口。
- 上新场景的
show=false、视频空列表和无新contentVersion均不展示。 - 除优惠倒计时外,展示回执成功后后续 Ping 返回
show=false;优惠倒计时的同一次启动去重由前端本地控制。 - 新客户端不同时使用旧
paymentStatusPopupConfig和新paymentGuide。