7.1 KiB
7.1 KiB
幸运礼物 Flutter 对接
本文只描述 App 需要接入的 HTTP、送礼返回、错误处理和腾讯云 IM 自定义消息。所有接口响应都使用 gateway 业务 envelope:
{
"code": "OK",
"message": "",
"request_id": "req_xxx",
"data": {}
}
1. 送礼前检查
POST /api/v1/activities/lucky-gifts/check
请求头:
| 参数 | 必填 | 说明 |
|---|---|---|
Authorization |
是 | Bearer <access_token> |
X-App-Code |
否 | 不传时使用默认 App |
请求体:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
room_id |
string | 是 | 当前房间 ID |
gift_id |
string | 是 | 实际送出的礼物 ID,例如 rose |
pool_id |
string | 是 | 幸运礼物奖池 ID,例如 lucky、super_lucky;当前 check 接口必填 |
返回 data:
| 字段 | 类型 | 说明 |
|---|---|---|
enabled |
bool | 是否可按幸运礼物发送 |
reason |
string | enabled、not_configured、disabled |
room_id |
string | 请求房间 ID |
gift_id |
string | 请求礼物 ID |
pool_id |
string | 生效奖池 ID |
gift_price |
int | 单次抽奖价格,金币 |
rule_version |
int | 后端规则版本 |
target_rtp_ppm |
int | RTP 目标,ppm |
experience_pool |
string | novice、intermediate、advanced |
客户端处理:
enabled=true:允许用户继续点击送礼。enabled=false:不要走幸运礼物送礼;可降级普通礼物或提示当前不可用。- 检查结果只用于展示和拦截,最终仍以送礼接口为准。
2. 发送礼物
POST /api/v1/rooms/gift/send
请求体关键字段:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
room_id |
string | 是 | 房间 ID |
command_id |
string | 是 | 本次送礼动作幂等键;同一次超时重试必须复用 |
target_user_id |
int/string | 兼容 | 旧单目标字段;新客户端优先使用 target_user_ids |
target_user_ids |
int[] | 是 | 当前 target_type=user 时必须且只能 1 个 |
target_type |
string | 否 | 当前只支持 user,为空按 user |
gift_id |
string | 是 | 礼物 ID,例如 rose |
gift_count |
int | 是 | 数量,必须大于 0 |
pool_id |
string | 幸运礼物必填 | lucky 或 super_lucky |
返回 data.lucky_gift:
| 字段 | 类型 | 说明 |
|---|---|---|
draw_id |
string | 抽奖 ID,客户端去重锚点 |
command_id |
string | 送礼命令 ID |
pool_id |
string | 生效奖池 |
gift_id |
string | 礼物 ID |
rule_version |
int | 抽奖规则版本 |
experience_pool |
string | 体验池 |
selected_tier_id |
string | 命中奖档 |
multiplier_ppm |
int | 倍率,2000000 表示 2 倍 |
base_reward_coins |
int | RTP 基础返奖 |
room_atmosphere_reward_coins |
int | 房间气氛池返奖 |
activity_subsidy_coins |
int | 活动补贴返奖 |
effective_reward_coins |
int | 用户实际获得金币 |
reward_status |
string | 有返奖或阶段反馈时初始通常为 pending,到账和房间 IM 由后端 outbox 补偿 |
stage_feedback |
bool | 是否阶段反馈,可播放轻量中奖表现 |
high_multiplier |
bool | 是否高倍 |
created_at_ms |
int | UTC epoch ms |
客户端处理:
data.lucky_gift != null:立即调用_applyLuckyGiftResult(),播放中奖或阶段反馈表现。effective_reward_coins > 0 && reward_status == "pending":展示中奖金额和“奖励处理中”,余额不要本地相加。effective_reward_coins > 0 && reward_status == "granted":可以展示已到账状态;余额仍以WalletBalanceChanged或余额刷新为准。data.lucky_gift == null:按普通礼物表现处理。
3. 错误处理
| code | 场景 | 客户端处理 |
|---|---|---|
INVALID_ARGUMENT |
参数缺失、数量非法、pool_id 缺失、target_user_ids 非单目标 |
停止提交,提示用户重试或刷新礼物面板 |
UNAUTHENTICATED |
token 失效 | 重新登录 |
INSUFFICIENT_BALANCE |
金币不足 | 打开充值入口或提示余额不足 |
RULE_NOT_ACTIVE |
幸运礼物规则未启用 | 降级普通礼物或刷新礼物配置 |
UPSTREAM_ERROR/UNAVAILABLE |
内部服务或 IM/钱包临时不可用 | 不重复扣本地余额;允许用户稍后重试 |
IDEMPOTENCY_CONFLICT/CONFLICT |
同一 command_id 对应的请求参数变化,或规则/奖池/风控冲突 |
参数变化时重新生成 command_id;规则冲突时刷新礼物面板 |
送礼失败时后端不会返回 lucky_gift,客户端不要播放中奖 UI。送礼成功但返奖到账延迟时,房间 IM 和钱包 IM 会继续补偿。
幂等规则:
- HTTP 超时、断网、502:同一次用户动作使用原
command_id重试。 - 已收到成功响应或钱包余额已扣减:不要生成新
command_id再发同一笔礼物。 - 需要重新点击送礼:生成新的
command_id。
4. 房间 IM
腾讯云 IM 群自定义消息:
| 字段 | 值 |
|---|---|
MsgType |
TIMCustomElem |
Desc |
lucky_gift_drawn |
Ext |
room_system_message |
Data |
JSON 字符串 |
Data 示例:
{
"event_type": "lucky_gift_drawn",
"event_id": "lucky_gift_drawn:lucky_draw_xxx",
"draw_id": "lucky_draw_xxx",
"command_id": "cmd_xxx",
"pool_id": "super_lucky",
"room_id": "room_1",
"gift_id": "rose",
"gift_count": 1,
"user_id": 42,
"sender_user_id": 42,
"target_user_id": 99,
"coin_spent": 100,
"rule_version": 1,
"experience_pool": "novice",
"selected_tier_id": "novice_2x",
"multiplier_ppm": 2000000,
"base_reward_coins": 200,
"room_atmosphere_reward_coins": 0,
"activity_subsidy_coins": 0,
"effective_reward_coins": 200,
"stage_feedback": true,
"high_multiplier": false,
"created_at_ms": 1760000000000
}
处理规则:
- 只处理
Desc == "lucky_gift_drawn"且event_type == "lucky_gift_drawn"。 - 用
event_id或draw_id去重;同一抽奖不要重复播放。 - 当前用户已通过 HTTP 送礼响应播放过同一
draw_id时,收到 IM 只更新状态,不重复播放。 effective_reward_coins > 0但还没有收到钱包余额 IM 时,只展示中奖结果和处理中状态,不本地加金币。
5. 钱包余额 IM
中奖金币到账后,wallet-service 会写 WalletBalanceChanged,notice-service 通过腾讯云 IM C2C 投递。
| 字段 | 值 |
|---|---|
MsgType |
TIMCustomElem |
Desc |
WalletBalanceChanged |
Ext |
wallet_notice |
客户端处理:
- 只处理
Desc == "WalletBalanceChanged"。 - 用
event_id去重。 - 当
asset_type == "COIN"时,用available_after更新金币余额;字段缺失时调用GET /api/v1/wallet/me/balances刷新。
6. 接入顺序
- 礼物面板拿到
pool_id后调用 check。 - check 可用后调用送礼接口,并把
pool_id放入请求。 - 送礼响应含
data.lucky_gift时立即播放本机中奖 UI。 - 房间内监听
lucky_gift_drawn,给其他用户同步中奖 UI。 - 私聊监听
WalletBalanceChanged,更新金币余额。