活动接口
平台采用插件式活动框架,每种活动有一个 kind 标识,已注册的 kind 包含:
account_tasks / agent_rebate / battle_pass / cumulative_recharge / daily_bankrupt_pack / daily_checkin / first_recharge_bonus / free_register_bonus / loss_rescue / lucky_compensation / magnate / mystery_bonus / rakeback / recharge_bonanza / red_packet_rain / rescue_bonus / treasure_box / vip / weekly_cashback / weekly_rescue_bonus / win_back
其中 daily_bankrupt_pack(每日幸运补偿) 为限时触发型活动,不支持 claim,奖励由充值订单自动发放。free_register_bonus(免费注册奖金) 的 detail 匿名可访问且下发配置,claim 按拆笔逐笔领取。lucky_compensation(幸运补偿) 为限时触发型,claim 是开宝箱领补偿本金,加赠随新存款自动发放。win_back(捞回活动) 的 claim 领取宝箱赠送奖金;玩家须在存款页主动选择该来源,合格充值订单绑定具体宝箱并在到账时结算一次加倍奖金。
下面 5 个接口对所有 kind 通用;具体活动的领取参数 / detail 数据结构由各 kind 决定(见对应专章)。
奖励钱包与打码规则
双钱包版本待发布,需完成配套数据库迁移后生效;本文不是上线公告。完整规则见 打码任务。
- 活动奖励有打码要求时计入奖金余额
bonus_money并生成奖励任务,无打码要求时计入现金余额user_money,不生成任务。余额接口的总余额total = user_money + bonus_money。bet_multiple描述本次奖励的要求,不再直接增加旧bet_amount。 - 领取成功表示奖励已入账,不表示已解锁或可提现。所有待完成任务及旧打码均清零后才满足提现打码门槛;单个活动任务完成不会单独释放对应奖金。
- 各活动独立配置
can_abandon,未开启时按不可放弃处理;发奖创建任务时将生效倍数与放弃权限固化,后续活动配置变更不改写已有任务。兑换码按该兑换码配置固化,充值本金任务始终不可放弃。 - 上述规则覆盖宝箱、战令、累计充值、签到、拼多多、神秘奖金、返水、红包雨、救援金、每周返现、每周救援金、代理返佣、首充奖励、充值大酬宾、VIP、兑换码和每日幸运补偿。活动详情与领取响应并没有统一新增
can_abandon字段,已发放奖励以任务列表中的can_abandon为准。 - 只有全部待完成任务都可放弃时,才可调用 整体放弃;它会清空当前全部奖金,不支持只放弃某个活动。现金和旧打码不变。
- 活动待领奖励的领取期限、礼包倒计时与已入账打码任务的状态分开处理;不要把活动的
expire_at/expire_days当成打码任务到期时间。
领取或自动发奖后,重新获取 余额 与 任务列表;保留各活动原有请求参数,不要给通用 claim 额外添加任务接口的 request_id。
活动列表
返回该商户当前启用(is_active=true)的所有活动。游客可访问,但 claim / purchase 仍需登录。
活动投放设置:商户可让活动只对部分推广商 / 渠道的会员开放,并划出一部分会员作为对照组。登录会员不在开放范围内或落在对照组时,该活动对他的表现与「活动未开启」完全一致:不出现在 data / triggered / enabled_kinds,不计入 unclaimed_count,活动详情 / 批量活动详情 不返回该活动,领取 / 购买 报「活动未启用」。游客不受影响。分组只按会员注册渠道与固定规则判定,客户端无需额外处理。
URL: GET /promotion/list
Query:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| with_unclaimed | bool | 否 | 传 1 / true 时额外计算并下发顶层 unclaimed_count 与 data[].unclaimed_count(口径见 可领奖励项数);不传则这两个字段不出现,服务端也不做任何额外计算(老客户端零开销)。游客传了也不下发 |
输出:
| 字段 | 类型 | 说明 |
|---|---|---|
| data | list<object> | 常驻活动入口卡片列表(商户开启「在活动列表展示」的 kind,每 kind 一行) |
| triggered | list<object> | 触发态入口列表(会员名下已激活的限时 / 阶段性记录,每条记录一行,按 expire_at 升序、不限时项在后);匿名恒为 []。同一 kind 可同时出现在 data 与 triggered(如「幸运充值礼包」常驻卡 + 手上一张 15 分钟礼包);kind 未开启列表展示时只出现在 triggered |
| enabled_kinds | list<string> | 商户当前已开启且平台已上架的活动 kind;不受「在活动列表展示」开关影响,未开启时为空数组;不含该会员投放范围外 / 对照组的 kind |
| unclaimed_count | int | 仅 with_unclaimed=1 且已登录时下发。全站可领奖励项数,口径同 可领奖励项数;覆盖商户当前已开启的全部 kind(含未开启列表展示、仅弹窗触达的),不是 data[] 逐行相加 |
data 单项字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| kind | string | 活动 kind |
| banner_url | string | banner 图(商户未配置时回退到平台默认) |
| icon_url | string | icon 图(同上) |
| sort_order | int | 展示排序(商户自定义排序优先,未配置回退平台默认) |
| has_unclaimed | bool | 是否有未领取奖励(游客按 kind 默认红点判定)。老字段,判定逻辑与缓存未变;部分 kind 的红点语义是「可参与」而非「有奖励待领」(如存款加赠类「今日未参加」、拼多多「今日可转动」),因此可能出现 has_unclaimed=true 而 unclaimed_count=0 |
| unclaimed_count | int | 仅 with_unclaimed=1 且已登录时下发。该 kind 当前可领奖励项数(口径见 可领奖励项数);无手动领取项的 kind 恒为 0 |
| payload | object | 可选,部分 kind 下发的卡片摘要(无该能力的 kind 不下发此字段):daily_deposit_bonus / deposit_first_n_bonus → 与各自 detail.data 同结构(含 can_join 等字段),前端应以 can_join 判断卡片是否可参与展示,不要用 is_active(is_active 只代表后台开关,未考虑今日已参与 / 次数用完等资格);loss_rescue → 与 活动详情 的 data 完全同结构(含 pending/in_progress/windows 等),常驻卡/领取卡不必再单独请求 GET /promotion/loss_rescue/detail |
triggered 单项字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| kind | string | 活动 kind,点击仍走 GET /promotion/{kind}/detail |
| entry_id | string | 触发记录 id(offer_id / record_id 等),前端以 kind + entry_id 作唯一键与「已关闭」记忆 |
| banner_url / icon_url | string | 同 data |
| expire_at | string | null | 限时截止(UTC);null = 不限时 |
| server_now | string | 服务端当前时间(UTC),倒计时请用 expire_at - server_now 校时 |
| sort_order | int | 展示排序,与 data 同一 kind 取值一致,供前端统一排序 data + triggered |
| payload | object | 卡片摘要,按 kind 自定义:daily_bankrupt_pack → {offer_id, seq, bonus_type, group_index, tiers, recommended_tier_index, description};free_register_bonus → {stage, gate, free_money, target_amount, min_total_deposit, reached_target, cap_reached, granted_at, expire_at, remaining_seconds, has_deposit, total_deposit}(stage ∈ playing / locked / unlocking),已锁定 / 解锁中另有 {total_amount, claimed_amount, claimed_count, chunk_count},解锁中再加 {current_amount, current_bet_required, current_bet_progress};win_back → {status, expire_at, boost_enabled},开启充值宝箱且已领取时另有 {gift_amount, boost_min_amount, multiplier_min, multiplier_max, boost_bet_multiple},仅免费宝箱领取后不再返回入口;entry_id 为活动记录 ID |
渲染建议:
triggered排在data之前。老客户端只读data即行为不变(data的生成逻辑与排序未改)。triggered只读现有记录、不会新建触发(如幸运充值礼包 offer 仍由site_content/config弹窗链路生成)。
可领奖励项数
返回当前玩家在商户全部已开启活动中的可领奖励项数,供首页角标 / 个人中心入口展示,不需要拉整张活动列表。与 GET /promotion/list?with_unclaimed=1 顶层 unclaimed_count 同源。游客可访问,恒返回 0。
URL: GET /promotion/unclaimed_count
输出:
| 字段 | 类型 | 说明 |
|---|---|---|
| data.count | int | 可领奖励项数(各 kind 之和) |
口径:一“项”= 一次独立领取动作能领到的单元,只统计当前就能调 claim 成功的奖励(已达领取门槛);存款加赠类(需充值才触发)、拼多多与兑换码不计入。不下发金额。
| kind | 一“项”的定义 |
|---|---|
treasure_box |
每个未过期待领宝箱 |
loss_rescue |
每笔已结算未过期的待领救援金(pending[]);到期未结算的窗口不计 |
cumulative_recharge |
每个已达标未领的阶梯 |
battle_pass |
每个已解锁未领的节点奖励(free / 已购 premium 各算一项) |
vip |
升级礼金(所有未领等级一键领,算 1 项)+ 本期周俸 + 本期月俸,最多 3 项 |
agent_rebate / rakeback / daily_checkin / weekly_cashback / rescue_bonus / weekly_rescue_bonus / free_register_bonus / mystery_bonus |
单项类:与该 kind 的 has_unclaimed 完全一致,true 即 1 |
red_packet_rain |
当前就能领(在窗口内、今日次数未满、本窗口未领;不含充值门槛)算 1 项,与 can_claim 一致,实时判定不走缓存 |
daily_bankrupt_pack / daily_deposit_bonus / deposit_first_n_bonus / first_recharge_bonus / recharge_bonanza / magnate / redeem_code |
无手动领取项(或红点语义为「可参与」),恒 0 |
结果按会员×kind 缓存 1 分钟,
claim/purchase成功后即时失效(与has_unclaimed红点同一套失效时机;单项类 kind 直接复用红点缓存,不产生额外查询)。free_register_bonus与red_packet_rain例外:前者逐笔打码解锁的达标由下注推进、拆笔由充值触发,后者随时间进出窗口,红点与可领项数都实时判定、不走缓存。领取后建议直接重拉本接口或/list?with_unclaimed=1刷新角标,不要在客户端自行减 1。
活动详情
返回某个 kind 的详细配置 + 当前玩家进度。游客可访问,登录后字段更完整。
URL: GET /promotion/{kind}/detail
Path:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kind | string | 是 | 活动 kind |
输出:
| 字段 | 类型 | 说明 |
|---|---|---|
| data | object | 活动详情,结构由 kind 决定 |
批量活动详情
一次请求返回多个 kind 各自的 detail(与逐个调用 GET /promotion/{kind}/detail 完全等价,只是合并成一次请求,减少并行请求数);不经过 活动列表 的 show_in_list 过滤,即使某 kind 未开启列表展示(仅靠自己的入口,如充值页展示存款类活动费率)也能拿到详情。游客可访问,登录后字段更完整。未知 / 无效 kind 静默跳过,不中断其它 kind。
URL: GET /promotion/detail_batch
Query:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kinds | string | 是 | 逗号分隔的 kind 列表,如 daily_deposit_bonus,deposit_first_n_bonus,first_recharge_bonus |
输出:
| 字段 | 类型 | 说明 |
|---|---|---|
| data | object | key 为 kind,value 为该 kind 的 detail.data(结构与单独调用 /detail 完全一致);请求的 kind 不存在或该 kind detail 报错时,该 key 直接缺失(不是 null) |
领取活动奖励
需要登录。body 字段由各 kind 自行约定(如 treasure_box 接受可选的 box_id),未约定时传 {}。
URL: POST /promotion/{kind}/claim
Path:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kind | string | 是 | 活动 kind |
输入: kind 自定义的 JSON 对象
输出: kind 自定义的对象(典型字段:amount、claimed_box_ids 等)
可选字段 data.new_reward_granted 表示本次是否实际新增发奖,由后端生成,不接受客户端输入控制。明确返回布尔 false 时不触发本次领奖风控钩子;true 或字段缺失保留原行为,类型异常记录日志并保留原行为。旧活动无需补字段。账号任务奖励首次入账在事务提交成功后返回 true,重复领取返回 false。
购买活动
需要登录。仅支持声明了 purchase 入口的 kind(如 battle_pass),其它 kind 返回「活动不存在或不支持购买」。
URL: POST /promotion/{kind}/purchase
Path:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| kind | string | 是 | 活动 kind |
输入: 无
输出: kind 自定义的对象