hyapp-server/docs/flutter对接/币商列表Flutter对接.md
2026-05-26 03:40:01 +08:00

4.8 KiB
Raw Permalink Blame History

币商列表 Flutter 对接

本文描述 Flutter App 获取当前用户所在区域启用币商列表的接口。币商身份、状态和区域过滤由 user-service 维护App 只展示 gateway 返回的列表,不传 region_id,也不在本地缓存为跨区域通用数据。

接口

GET /api/v1/wallet/coin-sellers

登录接口,需要 Authorization: Bearer <access_token>。接口按当前登录用户的 users.region_id 查询同区域、状态为 active、资产类型为 COIN_SELLER_COIN 的币商。

请求头:

Header 必填 说明
Authorization App 登录 access token。
X-App-Code App 编码,默认 lalu
X-Request-ID 客户端链路 ID服务端也会生成并在响应中返回。

Query无。不要传 region_idcountry_iduser_id

示例:

GET /api/v1/wallet/coin-sellers
Authorization: Bearer <access_token>
X-App-Code: lalu

成功响应:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_abc",
  "data": {
    "items": [
      {
        "user_id": "801",
        "display_user_id": "900801",
        "username": "Seller One",
        "avatar": "https://cdn.example/avatar.png",
        "country_id": 86,
        "country_code": "CN",
        "country_name": "China",
        "country_display_name": "中国",
        "region_id": 30,
        "region_code": "east-asia",
        "region_name": "East Asia",
        "status": "active",
        "merchant_asset_type": "COIN_SELLER_COIN",
        "updated_at_ms": 1700000001000
      }
    ],
    "total": 1
  }
}

字段规则:

字段 说明
user_id 币商用户长 IDJSON 中按字符串返回,避免 Dart/JS 大整数精度问题。
display_user_id 当前展示短号,可用于转账页展示和输入确认。
username 币商昵称;为空时客户端可展示短号。
avatar 币商头像 URL为空时展示默认头像。
country_id 币商用户当前国家 ID。
country_code 国家编码,例如 CN
country_name 英文或标准国家名。
country_display_name 客户端展示优先使用的国家名。
region_id 币商用户当前区域 ID应与当前用户区域一致。
status 当前只会返回 active
merchant_asset_type 当前固定为 COIN_SELLER_COIN
updated_at_ms 币商身份最近更新时间Unix epoch milliseconds。

Flutter 解析示例

class CoinSellerList {
  CoinSellerList({
    required this.items,
    required this.total,
  });

  final List<CoinSeller> items;
  final int total;

  factory CoinSellerList.fromJson(Map<String, dynamic> json) {
    return CoinSellerList(
      items: (json['items'] as List<dynamic>? ?? const [])
          .map((item) => CoinSeller.fromJson(item as Map<String, dynamic>))
          .toList(),
      total: (json['total'] as num?)?.toInt() ?? 0,
    );
  }
}

class CoinSeller {
  CoinSeller({
    required this.userId,
    required this.displayUserId,
    required this.username,
    required this.avatar,
    required this.countryId,
    required this.countryDisplayName,
    required this.regionId,
    required this.status,
    required this.merchantAssetType,
    required this.updatedAtMs,
  });

  final String userId;
  final String displayUserId;
  final String username;
  final String avatar;
  final int countryId;
  final String countryDisplayName;
  final int regionId;
  final String status;
  final String merchantAssetType;
  final int updatedAtMs;

  String get title => username.isNotEmpty ? username : displayUserId;

  factory CoinSeller.fromJson(Map<String, dynamic> json) {
    return CoinSeller(
      userId: json['user_id'] as String? ?? '',
      displayUserId: json['display_user_id'] as String? ?? '',
      username: json['username'] as String? ?? '',
      avatar: json['avatar'] as String? ?? '',
      countryId: (json['country_id'] as num?)?.toInt() ?? 0,
      countryDisplayName: json['country_display_name'] as String? ?? '',
      regionId: (json['region_id'] as num?)?.toInt() ?? 0,
      status: json['status'] as String? ?? '',
      merchantAssetType: json['merchant_asset_type'] as String? ?? '',
      updatedAtMs: (json['updated_at_ms'] as num?)?.toInt() ?? 0,
    );
  }
}

客户端处理

  1. 先解析外层 envelope只有 code == "OK" 时读取 data.items
  2. 空列表表示当前区域暂无启用币商;展示空状态,不切换到其他区域。
  3. 点击币商进入转账或联系流程时,使用 display_user_id 做用户可见确认,实际后续接口仍以服务端解析结果为准。
  4. 用户切换国家或完成资料变更后重新拉取本接口,不复用旧区域列表。
  5. 请求失败时记录 request_id,按登录失效、参数错误、服务错误分别处理。