hyapp-server/docs/flutter对接/Flutter App 通知与钱包余额对接.md

14 KiB
Raw Permalink Blame History

Flutter App 通知与钱包余额对接

本文只定义 App 需要对接的 HTTP 接口和 IM 私有事件契约,不约束 Flutter 端内部状态管理实现。

通用 HTTP 约定

Base URL

https://{api_host}

本地开发:

http://127.0.0.1:13000

Headers

Header 必填 说明
Authorization: Bearer {access_token} 登录后后端返回的 App 访问令牌
Content-Type: application/json POST 必填 请求体为 JSON
X-App-Code 多 App 包场景可传;通常由 gateway 按包名解析
X-App-Platform android / ios,部分钱包商品接口使用

响应 Envelope

所有 /api/v1 业务接口使用统一响应:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_xxx",
  "data": {}
}

失败时没有 data

{
  "code": "UNAUTHORIZED",
  "message": "unauthorized",
  "request_id": "req_xxx"
}

错误代码

HTTP code message 说明
200 OK ok 成功
400 INVALID_JSON invalid json JSON 格式错误
400 INVALID_ARGUMENT invalid argument 参数缺失或非法
401 UNAUTHORIZED unauthorized 未登录、token 过期或 token 无效
403 PROFILE_REQUIRED profile required 用户资料未完成
403 PERMISSION_DENIED permission denied 无权限
404 NOT_FOUND not found 资源不存在
409 INSUFFICIENT_BALANCE insufficient balance 金币/余额不足
409 LEDGER_CONFLICT conflict 钱包幂等冲突
409 IDEMPOTENCY_CONFLICT conflict command_id 重复但请求内容不同
409 ROOM_CLOSED room closed 房间已关闭
409 CONFLICT conflict 当前状态不允许操作
429 RATE_LIMITED rate limited 触发限流
500 INTERNAL_ERROR internal error 服务端内部错误
502 UPSTREAM_ERROR upstream service error 内部依赖不可用

App 处理建议:UNAUTHORIZED 重新登录;UPSTREAM_ERROR 可提示重试;INSUFFICIENT_BALANCE 引导充值;其它错误按页面语义提示。

1. 获取腾讯 IM 登录票据

GET /api/v1/im/usersig

Headers

Header 必填
Authorization

Query 参数

无。

返回值 data

{
  "sdk_app_id": 1400000000,
  "user_id": "10001",
  "user_sig": "xxx",
  "expire_at_ms": 1710000000000,
  "join_groups": [
    {
      "group_id": "hy_lalu_bc_g",
      "type": "global_broadcast",
      "region_id": 0
    }
  ]
}
字段 类型 说明
sdk_app_id int64 腾讯云 IM AppID
user_id string 腾讯云 IM identifier直接用于 IM 登录
user_sig string 腾讯云 IM 登录票据
expire_at_ms int64 票据过期时间UTC epoch ms
join_groups array App 登录 IM 后需要加入的服务端群

可能错误

UNAUTHORIZEDPROFILE_REQUIREDPERMISSION_DENIEDINTERNAL_ERRORUPSTREAM_ERROR

2. 获取我的钱包余额

GET /api/v1/wallet/me/balances

Headers

Header 必填
Authorization

Query 参数

参数 类型 必填 说明
asset_type string/repeated 可重复传,也可逗号分隔;不传默认只返回 COIN
asset_types string/repeated asset_type

示例:

GET /api/v1/wallet/me/balances?asset_type=COIN&asset_type=DIAMOND&asset_type=HOST_SALARY_USD&asset_type=AGENCY_SALARY_USD&asset_type=BD_SALARY_USD&asset_type=ADMIN_SALARY_USD

返回值 data

{
  "balances": [
    {
      "asset_type": "COIN",
      "available_amount": 1123123,
      "frozen_amount": 0,
      "version": 18
    }
  ]
}
字段 类型 说明
asset_type string COIN / DIAMOND / HOST_SALARY_USD / AGENCY_SALARY_USD / BD_SALARY_USD / ADMIN_SALARY_USD / GIFT_POINT
available_amount int64 可用余额
frozen_amount int64 冻结余额
version int64 该资产余额版本,用于和 IM 通知去重/防乱序

可能错误

UNAUTHORIZEDPROFILE_REQUIREDINVALID_ARGUMENTUPSTREAM_ERROR

3. 获取钱包首页摘要

GET /api/v1/wallet/me/overview

Headers

Header 必填
Authorization

Query 参数

无。

返回值 data

{
  "balances": [
    {
      "asset_type": "COIN",
      "available_amount": 1123123,
      "frozen_amount": 0,
      "version": 18
    },
    {
      "asset_type": "DIAMOND",
      "available_amount": 200,
      "frozen_amount": 0,
      "version": 4
    },
    {
      "asset_type": "HOST_SALARY_USD",
      "available_amount": 1500,
      "frozen_amount": 0,
      "version": 2
    }
  ],
  "feature_flags": {
    "recharge_enabled": true,
    "diamond_exchange_enabled": true
  }
}
字段 类型 说明
balances array 钱包首页需要展示的资产余额
feature_flags.recharge_enabled bool 是否允许充值
feature_flags.diamond_exchange_enabled bool 是否允许钻石兑换

可能错误

UNAUTHORIZEDPROFILE_REQUIREDUPSTREAM_ERROR

4. 送礼

POST /api/v1/rooms/gift/send

Headers

Header 必填
Authorization
Content-Type: application/json

Body 参数

{
  "room_id": "lalu_xxx",
  "command_id": "gift_1700000000000_10001",
  "target_type": "user",
  "target_user_ids": [10002],
  "gift_id": "car_001",
  "gift_count": 1
}
参数 类型 必填 说明
room_id string 房间 ID
command_id string 本次用户动作幂等键HTTP 重试必须复用同一个值
target_type string 当前支持 user;后续扩展 all_micall_roomcouple
target_user_ids int64[] 收礼用户 IDtarget_type=user 时必须且只能 1 个
target_user_id int64 单目标兼容字段;新代码优先用 target_user_ids
gift_id string 礼物 ID
gift_count int32 礼物数量

返回值 data

{
  "result": {
    "applied": true,
    "room_version": 14,
    "server_time_ms": 1710000000000
  },
  "billing_receipt_id": "br_xxx",
  "room_heat": 123456,
  "gift_rank": [],
  "room": {}
}
字段 类型 说明
result.applied bool 本次命令是否实际落地;幂等重放可能为 false
result.room_version int64 房间版本
result.server_time_ms int64 服务端时间
billing_receipt_id string 钱包扣费回执
room_heat int64 房间热度
gift_rank array 房间礼物榜快照
room object 房间快照

送礼成功不代表 App 必须从该响应里更新钱包余额。金币余额以 WalletBalanceChanged IM 私有事件或 /wallet/me/balances 刷新结果为准。

可能错误

UNAUTHORIZEDPROFILE_REQUIREDINVALID_ARGUMENTINSUFFICIENT_BALANCEROOM_CLOSEDLEDGER_CONFLICTIDEMPOTENCY_CONFLICTUPSTREAM_ERRORINTERNAL_ERROR

IM 私有事件:钱包余额变更

事件名称

WalletBalanceChanged

IM 通道

腾讯云 IM C2C 自定义消息。

字段
MsgType TIMCustomElem
Desc WalletBalanceChanged
Ext / extension wallet_notice
To_Account 当前登录用户的 IM identifier
CloudCustomData TIMCustomElem.Data 相同的 JSON 字符串

Headers

无。IM 私有事件不是 HTTP 请求,没有 HTTP header。

参数 / Payload

TIMCustomElem.Data 是 JSON 字符串:

{
  "event_type": "WalletBalanceChanged",
  "event_id": "wev_xxx",
  "app_code": "lalu",
  "transaction_id": "tx_xxx",
  "command_id": "gift_1700000000000_10001",
  "user_id": "10001",
  "asset_type": "COIN",
  "available_delta": -9900,
  "frozen_delta": 0,
  "available_after": 1123123,
  "frozen_after": 0,
  "balance_version": 18,
  "created_at_ms": 1710000000000,
  "source_created_at_ms": 1710000000000,
  "metadata": {}
}
字段 类型 必填 说明
event_type string 固定 WalletBalanceChanged
event_id string 事件幂等键
app_code string App 租户
transaction_id string 钱包交易 ID
command_id string 触发该余额变化的业务命令 ID
user_id string 当前用户 ID 字符串
asset_type string 资产类型
available_delta int64 可用余额变化量
frozen_delta int64 冻结余额变化量
available_after int64 变化后的可用余额
frozen_after int64 变化后的冻结余额
balance_version int64 该用户该资产的新版本
created_at_ms int64 钱包事件创建时间
source_created_at_ms int64 源 outbox 创建时间
metadata object 业务附加信息,不作为余额展示依赖

返回值

无。该事件由服务端单向投递给 AppApp 不需要回调后端确认。

错误代码

无 HTTP 错误代码。App 本地处理规则:

场景 处理
Desc 不是 WalletBalanceChanged 忽略
Ext/extension 不是 wallet_notice 忽略
JSON 解析失败 忽略并记录客户端日志
event_id 已处理 忽略
本地 asset_typeversion >= balance_version 忽略
长时间未收到通知 GET /api/v1/wallet/me/balances 兜底刷新

App 最小对接顺序

  1. 登录后调用 GET /api/v1/im/usersig
  2. 用返回的 user_id/user_sig/sdk_app_id 登录腾讯云 IM。
  3. GET /api/v1/wallet/me/balances 拉取初始余额。
  4. 监听 C2C 自定义消息 WalletBalanceChanged
  5. 送礼调用 POST /api/v1/rooms/gift/send
  6. 送礼后的余额以 IM 私有事件或余额刷新接口为准。