5.9 KiB
WalletMan 后端对接文档
前端对接见 walletman前端对接.md
Android 宿主通过 HTTP + WebSocket + FCM 与 walletman 服务端通信。服务端默认 :16000。
1. 架构
Android 宿主 ◄── HTTP/WS ──► walletman :16000 ◄── 代理 TCP ──► 钱包 API
◄── FCM data-only ──► Firebase
| 链路 | 用途 |
|---|---|
| HTTP REST | 登录、绑钱包、业务 |
WebSocket /ws |
设备注册、TCP 代理、心跳 |
| FCM | WS 断线拉活、token 过期重绑 |
clientId: 设备唯一 ID,WS 注册 key + FCM 目标 key,需与 App 侧 DeviceInfo.getUniqueIdSync() 一致。
2. 启动与配置
cd servers/walletman/cmd/server
go run . -tls android
测试页:http://localhost:16000/test/index.html
FCM 服务账号:
servers/walletman/cmd/server/config/fcm-service-account.json
或 FCM_SERVICE_ACCOUNT=/path/to/json。须与宿主 App google-services.json 同一 Firebase 项目。
3. 通用约定
响应:
{ "success": true, "message": "说明", "data": {} }
需登录接口请求头:
Content-Type: application/json
X-User-ID: 10000
4. HTTP 接口
POST /login
// req
{ "username": "test123", "password": "123456" }
// data
{ "userId": 10000, "userToken": "10000" }
POST /register
Token 绑钱包。
{
"walletType": "paytm",
"params": {
"type": "paytm",
"token": "...",
"refreshToken": "...",
"mobile": "9xxxxxxxxx",
"deviceId": "...",
"chType": "ipay",
"chVersion": "3"
}
}
// data
{ "walletId": "paytm_9xxxxxxxxx", "walletType": "paytm" }
walletId = {walletType}_{phone}。
常用 walletType:paytm | phonepe | mobikwik | freecharge | paytm business | phonepe business。
POST /request-otp / POST /verify-otp
OTP 绑钱包,见 http_handler.go。
GET /wallets
{
"wallets": [{
"id": "paytm_9876543210",
"walletType": "paytm",
"phone": "9876543210",
"upi": "xxx@paytm",
"status": "active",
"otpMode": false
}]
}
inactive + 非 OTP → 可能触发 FCM 重绑(maybeNotifyWalletRebind)。
POST /fcm/register
{ "clientId": "设备ID", "fcmToken": "..." }
与 WS register.data.fcmToken 等价,均 storeFcmToken。
POST /fcm/send-wake
{ "clientId": "xxx" }
// 或 { "userId": 10000 }
POST /fcm/send-rebind
{
"walletId": "paytm_9876543210",
"walletType": "paytm",
"phone": "9876543210",
"retry": false,
"notify": true
}
clientId 可省略,按 wallet owner 查 GetFcmClientID。
GET /fcm/clients
已注册 FCM 的 clientId 列表。
5. WebSocket /ws
URL:ws://host:16000/ws 或 wss://...
客户端 → 服务端
register(连上即发)
{
"type": "register",
"messageId": "register_1700000000000",
"clientId": "设备ID",
"data": { "userId": 10000, "fcmToken": "可选" }
}
- 存
clientId → Client userManager.SetProxy(userId, clientId, ...)- 同 clientId 新连接踢旧连接
ping(建议 10s)
{ "type": "ping", "messageId": "ping_xxx" }
proxyReady / proxyData / proxyClose
| type | 说明 |
|---|---|
| proxyReady | TCP 已连 host:port |
| proxyData | data.data = base64 |
| proxyClose | 结束 |
服务端 → 客户端
proxyRequest
{
"type": "proxyRequest",
"messageId": "req_1700000000000",
"data": { "host": "api.phonepe.com", "port": 443 }
}
443 端口服务端侧做 TLS,再 HTTP/2 转发。
服务端行为
| 事件 | 行为 |
|---|---|
| WS 断开 | cleanupClient → sendFcmWake(clientId) |
| 45s 无活动 | 心跳超时清理 + wake |
| 代理时 client 离线 | requestProxy 失败 → wake |
| 钱包 API 请求 | proxyRoundTripper → requestProxy |
代码:websocket_handler.go、proxy.go、fcm.go。
6. FCM 下发(data-only)
重绑 不发 notification 块,避免绕过 App 静默逻辑。
| data key | 说明 |
|---|---|
| msg | 文案(客户端 AIDL 失败才本地弹) |
| cmd | wake_proxy | rebind_wallet |
| params | JSON 字符串 |
wake_proxy
{ "cmd": "wake_proxy", "params": "{}" }
rebind_wallet
{
"cmd": "rebind_wallet",
"msg": "Paytm 已过期,点我自动重绑",
"params": "{\"walletId\":\"paytm_xxx\",\"walletType\":\"paytm\",\"phone\":\"9xxx\",\"retry\":false,\"tryGtkAnyway\":false}"
}
PhonePe 默认 retry=true。
自动触发
wallet.GetStatus() == inactive 且 !GetOTPMode() → sendFcmRebind(..., notify=true)。
发送实现
sendFcmToClient → FCM HTTP v1 projects/{id}/messages:send。
7. 时序(服务端视角)
代理请求
walletman HTTP 出网
→ GetProxyClientID(userId)
→ requestProxy(clientId, host, 443)
→ WS proxyRequest → 等 proxyReady
→ 双向 proxyData
断线拉活
WS cleanupClient
→ sendFcmWake(clientId)
→ 客户端 wakeFromPrefs → 重连 WS register
重绑
inactive 检测 / 手动 /fcm/send-rebind
→ FCM rebind_wallet
→ 客户端静默 AIDL → POST /register(宿主实现)
→ 失败则客户端弹通知,用户点击后走前端 handler
8. 调试
# 服务端日志
go run . -tls android
# 测试页
http://localhost:16000/test/index.html
| 接口 | 用途 |
|---|---|
| GET /fcm/clients | 看已注册设备 |
| POST /fcm/send-wake | 手动拉活 |
| POST /fcm/send-rebind | 手动重绑 |
| 现象 | 排查 |
|---|---|
| FCM send failed | 服务账号路径、project_id |
| no FCM token for clientId | App 未 POST /fcm/register 或 WS 未带 fcmToken |
| Client not connected | WS 未连;发 wake 后重试 |
| 重绑发了客户端无反应 | 查 FCM send ok 日志;Firebase 项目是否一致 |