feat(weibo): 增加微博微豆基础自动化
This commit is contained in:
@@ -0,0 +1,696 @@
|
||||
---
|
||||
type: 协议确认
|
||||
description: 微博微豆自动化唯一协议,覆盖 CK 登录态、微信/QQ 绑定二维码、助力充值、支付二维码、微豆明细、商城列表、兑换和兑换记录。
|
||||
tags: [微博, 微豆, VPlus, 助威, 充值, 兑换, 微信小程序, QQ小程序, URL Scheme, 二维码, CK]
|
||||
generated:
|
||||
by: ai/codex
|
||||
at: 2026-11-07T19:03:41+08:00
|
||||
status: stable
|
||||
verified:
|
||||
- { by: ai/codex, at: 2026-11-07T19:03:41+08:00 }
|
||||
---
|
||||
|
||||
# 微博微豆 CK 接口与兑换链路确认
|
||||
|
||||
确认日期:2026-11-07
|
||||
|
||||
原始样本:用户提供的 `充值1元-查询明细-兑换列表-兑换1天会员.har`。该 HAR 含账号 Cookie、用户标识、昵称和支付数据,不纳入仓库。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
微博业务接口只需要微博登录 Cookie(下文简称 CK),未观察到独立的 access token、CSRF token 或客户端签名 Header。绑定二维码转换接口 `GenMiniappScheme` 不需要微博、微信或 QQ 的账号 Cookie,但仍依赖微博链接内层的 `code`、`nonce`、`sig`、`t` 业务参数。
|
||||
|
||||
核心链路:
|
||||
|
||||
```text
|
||||
CK + F
|
||||
-> GET /aj/mall/home 获取用户、绑定状态、余额、任务、商城入口
|
||||
|
|
||||
+-> 未绑定:game_role.bind_url
|
||||
| -> POST GenMiniappScheme
|
||||
| -> 微信/QQ urlScheme
|
||||
| -> 生成绑定二维码
|
||||
|
|
||||
+-> 助威得微豆:
|
||||
GET /aj/vmember/gfsupport 获取助力目标 uid/vuid
|
||||
GET /aj/paycomponent/cashierinfo 获取收银台、商品档位、活动参数
|
||||
POST /aj/paycomponent/createorder 创建充值订单
|
||||
打开 data.url,读取收银台 HTML 中的支付二维码
|
||||
POST /aj/pay/status 轮询支付状态
|
||||
GET /aj/point/get_point_recharge_history 查询微豆获取明细
|
||||
|
|
||||
+-> 微豆兑换:
|
||||
GET /aj/mall/list 查询商城列表与余额
|
||||
GET /aj/mall/detail 查询商品详情
|
||||
GET /aj/game/exchangegoods 执行兑换
|
||||
GET /aj/mall/list 复核余额和库存
|
||||
GET /aj/mall/exchange 查询兑换记录
|
||||
```
|
||||
|
||||
## 2. 共同会话与 Header
|
||||
|
||||
### 2.1 必需状态
|
||||
|
||||
- 微博 CK:必需。实测不带 Cookie 时:
|
||||
- `/aj/mall/home` 返回 `code=400002`、`msg=未登陆`。
|
||||
- `/aj/point/get_point_recharge_history` 返回 `code=400000`、`msg=user not login`。
|
||||
- `F`:活动来源标识。样本为 `bowen_tjg`,应作为活动入口参数配置,不要推导算法。
|
||||
- `uid`:微博用户 ID,从 `/aj/vmember/gfsupport`、收银台响应或页面状态获取。
|
||||
- `vuid`:被助威的 V+ 账号 ID,从 `/vmember/subscribe` URL、`task_list.action_url` 或对应接口获取。
|
||||
|
||||
CK 是否可缩减为只有 `SUB` 尚未验证。样本请求中同时出现 `SUB`、`SUBP`、`SCF`、`ALF`、`PC_TOKEN`、`v!pay` 等 Cookie,建议先维护完整 Cookie Jar,再逐步做最小化测试。
|
||||
|
||||
### 2.2 请求头
|
||||
|
||||
样本未观察到:
|
||||
|
||||
- `Authorization`
|
||||
- `X-CSRF-Token`
|
||||
- 自定义签名 Header
|
||||
- 客户端加密 Body
|
||||
|
||||
GET 请求至少携带:
|
||||
|
||||
```http
|
||||
Cookie: <微博 CK>
|
||||
Referer: <对应页面 URL>
|
||||
```
|
||||
|
||||
POST 请求使用:
|
||||
|
||||
```http
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Origin: https://vipclub.weibo.com
|
||||
Referer: https://vipclub.weibo.com/vmember/subscribe?...
|
||||
Cookie: <微博 CK>
|
||||
```
|
||||
|
||||
前端每个 GET 请求都会自动追加毫秒时间戳:
|
||||
|
||||
```text
|
||||
_t=<Date.now()>
|
||||
```
|
||||
|
||||
`_t` 是缓存破坏参数,未观察到参与签名。
|
||||
|
||||
## 3. 用户、绑定和任务入口
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/mall/home?F=<F>&_t=<毫秒时间戳>
|
||||
```
|
||||
|
||||
关键响应字段:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| --- | --- |
|
||||
| `data.user_info.uid` | 当前登录微博 uid |
|
||||
| `data.game_role.is_bound` | 是否已绑定游戏角色 |
|
||||
| `data.game_role.role_name` | 已绑定角色 |
|
||||
| `data.game_role.bind_url` | 微博小程序绑定链接 |
|
||||
| `data.game_role.can_rebind` | 当前是否允许换绑 |
|
||||
| `data.game_role.rebind_remain_days` | 下次可换绑的剩余天数 |
|
||||
| `data.weidou_balance.balance` | 当前微豆余额 |
|
||||
| `data.task_list` | 微豆任务列表 |
|
||||
| `data.recommend_list` | 推荐商品 |
|
||||
| `data.mall_url` | 商城入口 |
|
||||
|
||||
### 3.1 微信/QQ 绑定二维码
|
||||
|
||||
本次 HAR 的状态是:
|
||||
|
||||
```json
|
||||
{
|
||||
"is_bound": true,
|
||||
"can_rebind": false
|
||||
}
|
||||
```
|
||||
|
||||
因此本次没有重新走绑定动作。页面逻辑是:
|
||||
|
||||
- `is_bound=false`:展示“绑定角色”,点击后打开 `game_role.bind_url`。
|
||||
- `is_bound=true && can_rebind=true`:进入换绑。
|
||||
- `is_bound=true && can_rebind=false`:前端直接提示剩余天数,不打开链接。
|
||||
|
||||
`bind_url` 形如:
|
||||
|
||||
```text
|
||||
sinaweibo://wbdiversion?username=<username>&path=<encoded-path>
|
||||
```
|
||||
|
||||
输入也可能直接来自其他微博小程序跳转:
|
||||
|
||||
```text
|
||||
sinaweibo://wbdiversion?username=gh_<username>&path=/pages/gameAccountBind/index?<inner_query>
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `username=gh_...` 是微博侧小程序标识,不传给来联接口。
|
||||
- `sinaweibo://wbdiversion` 只用于微博客户端唤起,不传给来联接口。
|
||||
- `<inner_query>` 是 `path=/pages/gameAccountBind/index?` 后面的全部原始 Query。
|
||||
|
||||
实测内层业务参数包括:
|
||||
|
||||
```text
|
||||
actId
|
||||
code
|
||||
faceUrl
|
||||
gameId
|
||||
gameIdList
|
||||
livePlatId
|
||||
nickName
|
||||
nonce
|
||||
sig
|
||||
t
|
||||
v
|
||||
```
|
||||
|
||||
必须保留原始百分号编码。不要先 `URLDecoder`、`parse_qs` 或重新拼 Query,否则 `code`、`faceUrl` 中的多重编码可能被改变。
|
||||
|
||||
#### 3.1.1 生成微信/QQ URL Scheme
|
||||
|
||||
页面入口是:
|
||||
|
||||
```text
|
||||
https://livelink.qq.com/h5-open-mp/wx?<inner_query>
|
||||
https://livelink.qq.com/h5-open-mp/qq?<inner_query>
|
||||
```
|
||||
|
||||
PC 页面不会直接展示二维码,而是请求:
|
||||
|
||||
```http
|
||||
POST https://livelinkbind.game.qq.com/livelink?c=Sdk&a=GenMiniappScheme&<path内层参数>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
微信请求体:
|
||||
|
||||
```json
|
||||
{"accountType":"wx"}
|
||||
```
|
||||
|
||||
QQ 请求体:
|
||||
|
||||
```json
|
||||
{"accountType":"qq"}
|
||||
```
|
||||
|
||||
成功响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"iRet": 0,
|
||||
"sMsg": "ok",
|
||||
"jData": {
|
||||
"urlScheme": "<小程序 URL Scheme>"
|
||||
},
|
||||
"v": 2,
|
||||
"apiName": "GenMiniappScheme"
|
||||
}
|
||||
```
|
||||
|
||||
二维码必须编码 `jData.urlScheme` 的完整字符串,不应编码原 `livelink.qq.com` 页面地址。
|
||||
|
||||
#### 3.1.2 Scheme 格式
|
||||
|
||||
微信:
|
||||
|
||||
```text
|
||||
weixin://dl/business/?appid=wx707e2eb408780a5b&path=pages/gameAccountBind/index&query=scheme_id%3D<dynamic>
|
||||
```
|
||||
|
||||
QQ:
|
||||
|
||||
```text
|
||||
mqqapi://miniapp/open?_atype=0&_mappid=1111906964&_miniapptype=1&_mvid=&_path=pages%2FgameAccountBind%2Findex&_vt=3&via=qq_txyxll&_sig=<dynamic>&_nq=<encoded-inner-query>
|
||||
```
|
||||
|
||||
本次样本确认:
|
||||
|
||||
| 字段 | 微信 | QQ |
|
||||
| --- | --- | --- |
|
||||
| 小程序 AppID | `wx707e2eb408780a5b` | `1111906964` |
|
||||
| 页面路径 | `pages/gameAccountBind/index` | `pages/gameAccountBind/index` |
|
||||
| 动态凭证 | `scheme_id` | `_sig`、`_nq` 内的业务参数 |
|
||||
| 二维码内容 | 返回的 `urlScheme` | 返回的 `urlScheme` |
|
||||
|
||||
AppID、路径和渠道字段只代表本次活动样本;业务参数不能写死为常量。
|
||||
|
||||
#### 3.1.3 鉴权与时效
|
||||
|
||||
`GenMiniappScheme` 实测只发送:
|
||||
|
||||
```http
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
没有发送:
|
||||
|
||||
- 微博 Cookie
|
||||
- 微信/QQ Cookie
|
||||
- Bearer Token
|
||||
- 微信/QQ access token
|
||||
- 微信/QQ OAuth 回调参数
|
||||
- 用户登录会话
|
||||
|
||||
微信和 QQ 两个请求均返回 HTTP 200、`iRet=0`,响应没有 `Set-Cookie`。
|
||||
|
||||
这里的“不需要鉴权”只表示 Scheme 生成接口不依赖账号登录态。`code`、`nonce`、`sig`、`t` 仍是来联业务的防篡改和时效参数,不能删除或改写。
|
||||
|
||||
- `t` 是 Unix 秒时间戳。
|
||||
- `scheme_id` 和 QQ `_sig` 由服务端动态生成。
|
||||
- 样本在 `t` 后约 54 分钟仍可生成 Scheme,但不足以确定固定 TTL。
|
||||
- 每次都应从新的微博链接或新的 `bind_url` 提取内层 Query,不能长期缓存。
|
||||
|
||||
微信页面在“微信内直接唤起小程序”的分支会调用 `/api/common/getWxJsApiTicket` 配置 `wx-open-launch-weapp`;该 JS-SDK 分支不是二维码生成链路,二维码生成不需要它。
|
||||
|
||||
本次没有抓到 `is_bound=false` 的独立样本,因此未绑定场景下 `bind_url` 的值仍需下一次抓包确认;但当前已绑定响应中同样存在 `bind_url`,且同一 `GenMiniappScheme` 链路已实测可用。
|
||||
|
||||
## 4. 助威得微豆与充值
|
||||
|
||||
### 4.1 助威入口
|
||||
|
||||
`/aj/mall/home` 的 `task_list` 样本中包含:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "助威得微豆",
|
||||
"button_type": "cashier",
|
||||
"action_url": "sinaweibo://transparentbrowser?url=<encoded-subscribe-url>"
|
||||
}
|
||||
```
|
||||
|
||||
解码后进入:
|
||||
|
||||
```text
|
||||
https://vipclub.weibo.com/vmember/subscribe?vuid=<vuid>&source_itemid=20601&F=<F>
|
||||
```
|
||||
|
||||
### 4.2 获取助力目标
|
||||
|
||||
```http
|
||||
GET https://vipclub.weibo.com/aj/vmember/gfsupport?vuid=<vuid>&source_itemid=20601&F=<F>&_t=<ms>
|
||||
```
|
||||
|
||||
响应提供:
|
||||
|
||||
- `data.uid`
|
||||
- `data.vuid`
|
||||
- `data.u_name`
|
||||
- 被助威账号信息
|
||||
- 是否已助力/会员
|
||||
|
||||
### 4.3 获取收银台和商品档位
|
||||
|
||||
```http
|
||||
GET https://vipclub.weibo.com/aj/paycomponent/cashierinfo
|
||||
?F=<F>
|
||||
&tab_id=536
|
||||
&cashier_id=205
|
||||
&cashier_version=0.2.3
|
||||
&vuid=<vuid>
|
||||
&source_itemid=20601
|
||||
```
|
||||
|
||||
页面输入还包含空值参数:
|
||||
|
||||
```text
|
||||
appName=&from=&wm=&profileuid=&device_id=&tab_type=&bid=
|
||||
```
|
||||
|
||||
这些空参数可以保留以贴合浏览器行为,尚未逐一测试是否可省略。
|
||||
|
||||
关键响应:
|
||||
|
||||
```text
|
||||
data.cashier_id
|
||||
data.tab_info[].tab_id
|
||||
data.tab_info[].tab_type
|
||||
data.tab_info[].menu[]
|
||||
data.user_info.uid
|
||||
```
|
||||
|
||||
样本“1 元 = 100 微豆”档位:
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| `commodity_id` | `2060101` |
|
||||
| `subitemid` | `2060101` |
|
||||
| `itemid` | `20601` |
|
||||
| `appkey` | `2000` |
|
||||
| `cashier_id` | `205` |
|
||||
| `tab_type` | `8` |
|
||||
| `max_money` | `1000` |
|
||||
| `discount_info.desc` | `1元=100微豆` |
|
||||
|
||||
页面允许自定义 1–1000 元,提交时把金额换算成:
|
||||
|
||||
```text
|
||||
single_reward = 金额(元) * 100
|
||||
```
|
||||
|
||||
所以 1 元对应 `single_reward=100`。
|
||||
|
||||
### 4.4 创建充值订单
|
||||
|
||||
```http
|
||||
POST https://vipclub.weibo.com/aj/paycomponent/createorder?<与 Body 相同的业务参数>
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Origin: https://vipclub.weibo.com
|
||||
Referer: https://vipclub.weibo.com/vmember/subscribe?vuid=<vuid>&source_itemid=20601&F=<F>
|
||||
Cookie: <微博 CK>
|
||||
```
|
||||
|
||||
样本核心 Body:
|
||||
|
||||
```text
|
||||
subitemid=2060101
|
||||
itemid=20601
|
||||
appkey=2000
|
||||
commodity_id=2060101
|
||||
num=1
|
||||
cashier_id=205
|
||||
F=<F>
|
||||
is_from_cashier=1
|
||||
cashierpw=1
|
||||
vuid=<vuid>
|
||||
tab_type=8
|
||||
cashier_version=0.2.3
|
||||
single_reward=100
|
||||
ext={"bid":"<bid>","send_blog":1}
|
||||
```
|
||||
|
||||
其他样本字段:
|
||||
|
||||
```text
|
||||
salestrategy_id=
|
||||
discount_id=
|
||||
from=
|
||||
device_id=
|
||||
level_up_tag=0
|
||||
to_uid=
|
||||
return_url=
|
||||
ori_t_id=
|
||||
will_auto_renew=0
|
||||
subpw=
|
||||
account=
|
||||
follow=false
|
||||
coupon_id=
|
||||
gc=
|
||||
bid=
|
||||
mid=
|
||||
```
|
||||
|
||||
浏览器前端拦截器会把同一组参数同时放进 URL Query 和 form Body。样本服务端接受了这种重复传参。实现时建议保持 Query + Body 一致,除非后续实测证明只传 Body 也可以。
|
||||
|
||||
样本 Body 中还有 `is_eligible=undefined`,这是前端直接序列化未定义值产生的字符串,不应作为可靠业务参数。
|
||||
|
||||
成功响应关键字段:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| --- | --- |
|
||||
| `data.url` | 微博支付收银台 URL |
|
||||
| `data.orderid` | 支付订单号,后续微豆明细的 `source_id` |
|
||||
| `data.pay_return_url` | 支付完成后的业务回跳地址 |
|
||||
| `data.return_url` | 带订单号的回跳地址 |
|
||||
| `data.channel` | 样本为 `weibo_web` |
|
||||
|
||||
### 4.5 支付收银台和二维码
|
||||
|
||||
使用同一 Cookie 打开 `data.url`,经过:
|
||||
|
||||
```text
|
||||
GET /api/merchant/pay/cashier
|
||||
-> 302 /pay/pc/cashier
|
||||
-> 200 收银台 HTML
|
||||
```
|
||||
|
||||
收银台 HTML 内直接包含支付信息:
|
||||
|
||||
```html
|
||||
<input type="hidden" name="pay_id" value="<pay_id>">
|
||||
<img node-type="QRCode" src="https://qr.weibo.cn/inf/gen?...">
|
||||
<a href="https://pay.sc.weibo.com/pay/pc/comb?pay_id=<pay_id>...">立即支付</a>
|
||||
```
|
||||
|
||||
支付二维码由收银台服务端生成带 `api_key`、`data`、`sign` 的 `qr.weibo.cn/inf/gen` URL。客户端不需要自行计算该签名,按 HTML 解析即可。
|
||||
|
||||
### 4.6 支付状态轮询
|
||||
|
||||
```http
|
||||
POST https://pay.sc.weibo.com/aj/pay/status
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
X-Requested-With: XMLHttpRequest
|
||||
Origin: https://pay.sc.weibo.com
|
||||
Referer: <收银台 URL>
|
||||
Cookie: <微博 CK>
|
||||
|
||||
pay_id=<pay_id>&ispage=1&_t=0
|
||||
```
|
||||
|
||||
样本状态:
|
||||
|
||||
```text
|
||||
code=100000
|
||||
data.status=PAY_STATUS_PENDING
|
||||
data.sub_status=PAY_SUB_STATUS_INITIAL
|
||||
```
|
||||
|
||||
样本约每 1 秒轮询一次,共 16 次待支付状态;用户在支付宝扫码并完成支付后,流程跳转成功页。支付动作本身属于外部支付流程,不应由 CK 自动完成或绕过。
|
||||
|
||||
### 4.7 到账确认
|
||||
|
||||
支付完成后再次请求 `/aj/mall/home`:
|
||||
|
||||
```text
|
||||
data.weidou_balance.balance = 100
|
||||
```
|
||||
|
||||
微豆明细出现:
|
||||
|
||||
```json
|
||||
{
|
||||
"source_type": 101,
|
||||
"record_type": 208681,
|
||||
"source_id": "<createorder.data.orderid>",
|
||||
"source_name": "V+助威",
|
||||
"point_num": 100
|
||||
}
|
||||
```
|
||||
|
||||
本次充值 1 元,到账 100 微豆。
|
||||
|
||||
### 4.8 `pay/modular/prepare`
|
||||
|
||||
样本还出现:
|
||||
|
||||
```http
|
||||
POST https://pay.sc.weibo.com/aj/pay/modular/prepare
|
||||
```
|
||||
|
||||
请求体是页面初始“超能爆发”档位的 `total_amount=6000`,响应为空。本次 1 元自定义订单没有从该响应读取任何字段,实际下单依赖的是 `/aj/paycomponent/createorder`。暂不把它列入 1 元充值必需链路。
|
||||
|
||||
## 5. 微豆明细
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/point/get_point_recharge_history
|
||||
?F=<F>
|
||||
&page_no=1
|
||||
&page_size=20
|
||||
&_t=<ms>
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```text
|
||||
data.page_num
|
||||
data.page_size
|
||||
data.total
|
||||
data.list[]
|
||||
data.expire_remind
|
||||
```
|
||||
|
||||
样本明细:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| --- | --- |
|
||||
| `id` | 明细 ID |
|
||||
| `source_type` | 来源类型,样本为 `101` |
|
||||
| `record_type` | 记录类型,样本为 `208681` |
|
||||
| `source_id` | 支付订单号 |
|
||||
| `source_name` | 来源名,样本为 `V+助威` |
|
||||
| `point_num` | 到账微豆,样本为 `100` |
|
||||
| `create_time` | 到账时间 |
|
||||
| `expire_time` | 微豆过期时间 |
|
||||
|
||||
该接口从名称和样本看是“微豆获取/充值明细”。兑换消耗记录使用 `/aj/mall/exchange`,不要把两个接口混为一谈。
|
||||
|
||||
## 6. 微豆商城列表
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/mall/list?F=<F>&_t=<ms>
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```text
|
||||
data.list[]
|
||||
data.weidou_balance
|
||||
data.exchange_url
|
||||
```
|
||||
|
||||
商品字段:
|
||||
|
||||
```text
|
||||
id
|
||||
goods_name
|
||||
goods_image
|
||||
price
|
||||
remain_count
|
||||
is_sold_out
|
||||
goods_desc
|
||||
```
|
||||
|
||||
本次抓包中的商品 ID:
|
||||
|
||||
| goods_id | 商品 | 价格/微豆 |
|
||||
| --- | --- | ---: |
|
||||
| 21 | 汪仔布丁大礼包 | 28000 |
|
||||
| 22 | 套装-暮夜私语 | 9880 |
|
||||
| 23 | 套装-墨青刃影 | 7880 |
|
||||
| 12 | 套装-暗影哥特 | 8880 |
|
||||
| 14 | 套装-浪漫天命 | 3600 |
|
||||
| 13 | 黑色高级特训官上衣 | 3600 |
|
||||
| 18 | 幸运币礼包(小) | 200 |
|
||||
| 19 | 幸运币礼包(中) | 3000 |
|
||||
| 20 | 幸运币礼包(大) | 9000 |
|
||||
| 15 | 荣耀勋章礼包(小) | 200 |
|
||||
| 16 | 荣耀勋章礼包(中) | 3000 |
|
||||
| 17 | 荣耀勋章礼包(大) | 9000 |
|
||||
| 42 | 微博VIP年卡 | 10800 |
|
||||
| 41 | 微博VIP月卡 | 1000 |
|
||||
| 40 | 微博VIP周卡 | 400 |
|
||||
| 39 | 微博会员5天卡 | 300 |
|
||||
| 38 | 微博会员3天卡 | 200 |
|
||||
| 37 | 微博会员1天卡 | 100 |
|
||||
|
||||
`remain_count` 是实时库存,不能写成常量。
|
||||
|
||||
## 7. 商品详情与兑换
|
||||
|
||||
### 7.1 商品详情
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/mall/detail?F=<F>&goods_id=<goods_id>&_t=<ms>
|
||||
```
|
||||
|
||||
响应包含:
|
||||
|
||||
```text
|
||||
goods_info
|
||||
weidou_balance
|
||||
payment_button
|
||||
nickname
|
||||
game_nickname
|
||||
```
|
||||
|
||||
只有 `payment_button.clickable=true` 且 `payment_button.type=exchange` 时,前端才允许兑换。
|
||||
|
||||
### 7.2 执行兑换
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/game/exchangegoods?F=<F>&goods_id=<goods_id>&_t=<ms>
|
||||
```
|
||||
|
||||
请求参数只有 `F`、`goods_id`、`_t`,没有额外确认 Token。
|
||||
|
||||
成功响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 100000,
|
||||
"msg": "success",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
样本兑换 `goods_id=37`(微博会员1天卡)后再次请求 `/aj/mall/list`:
|
||||
|
||||
- `data.weidou_balance` 从 `100` 变为 `0`;
|
||||
- goods 37 的 `remain_count` 从 `4639` 变为 `4638`。
|
||||
|
||||
因此 `code=100000` 表示请求成功,但仍应刷新商城列表确认余额和库存变化。
|
||||
|
||||
注意:这是使用 GET 执行状态变更的接口。不能做自动重试、并发点击或把一次成功当成幂等。
|
||||
|
||||
### 7.3 兑换记录
|
||||
|
||||
```http
|
||||
GET https://vipclub.e.weibo.com/aj/mall/exchange
|
||||
?F=<F>
|
||||
&page=1
|
||||
&page_size=20
|
||||
&_t=<ms>
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```text
|
||||
data.page
|
||||
data.pageSize
|
||||
data.list
|
||||
data.totalCount
|
||||
```
|
||||
|
||||
本次在兑换前查询两次,结果均为空列表。兑换后没有再请求该接口,因此兑换成功后的记录字段仍需补抓一次。
|
||||
|
||||
## 8. 同一页面的辅助接口
|
||||
|
||||
以下接口出现在页面加载流程中,但不是上述业务的必需前置:
|
||||
|
||||
| 接口 | 用途 |
|
||||
| --- | --- |
|
||||
| `/aj/paycomponent/userinfo` | 获取收银台 tab |
|
||||
| `/aj/paycomponent/couponlist` | 优惠券状态 |
|
||||
| `/aj/strategy/info` | 活动策略提示 |
|
||||
| `/aj/paycomponent/privilege` | V+ 权益展示 |
|
||||
| `/actionlog` | 前端埋点 |
|
||||
|
||||
## 9. 实现约束
|
||||
|
||||
1. 所有微博业务接口都依赖与目标用户一致的 Cookie;先验证 `/aj/mall/home` 返回 `code=100000`。
|
||||
2. 使用 Cookie Jar,保留响应和收银台页面产生的 Cookie 更新。
|
||||
3. `_t` 使用当前毫秒时间,不复用抓包值。
|
||||
4. `uid`、`vuid`、`cashier_id`、`tab_id`、`itemid`、`appkey` 和 `single_reward` 来自页面响应,业务代码只保留活动配置。
|
||||
5. 充值金额以 `single_reward` 为准:1 元填 `100`。
|
||||
6. 兑换接口是 GET 状态变更,必须设置本地防重锁并禁止自动重试。
|
||||
7. 支付二维码从 `createorder.data.url` 对应的收银台 HTML 中解析,不要重新计算 `qr.weibo.cn` 的 `sign`。
|
||||
8. 不记录或回显完整 Cookie、支付 URL、二维码短链、uid、vuid、昵称和订单号。
|
||||
|
||||
## 10. 鉴权与错误处理
|
||||
|
||||
已确认:
|
||||
|
||||
- 没有独立业务 Token;CK 是核心认证状态。
|
||||
- 没有观察到 CSRF Header 或请求签名算法。
|
||||
- 未登录时接口会返回 `400002`、`400000` 或跳转微博登录页。
|
||||
|
||||
建议处理:
|
||||
|
||||
| code | 处理 |
|
||||
| --- | --- |
|
||||
| `100000` | 成功 |
|
||||
| `100002` | 登录失效,停止任务并要求更新 CK |
|
||||
| `100004` | 进入微博错误页,停止任务 |
|
||||
| `400002` | `未登陆`,CK 无效 |
|
||||
| `400000` | `user not login`,CK 无效 |
|
||||
| 其他 | 保留服务端 `msg` 和 `trace_id`,不要盲目重试状态变更接口 |
|
||||
|
||||
## 11. 尚未确认
|
||||
|
||||
- 是否只需要 `SUB`,还是必须完整 Cookie Jar。
|
||||
- 本次未抓 `is_bound=false` 的绑定响应。
|
||||
- 本次未抓兑换后的 `/aj/mall/exchange` 记录。
|
||||
- `/aj/game/exchangegoods` 在余额不足、重复兑换、角色未绑定时的错误码。
|
||||
- 支付订单在支付宝侧取消、超时、退款后的业务状态。
|
||||
- 各活动的 `F`、`itemid`、`source_itemid`、`cashier_id`、`tab_id` 是否跨活动变化;实现时应从页面动态读取。
|
||||
Reference in New Issue
Block a user