返回个人主页
📌 GET
🚀 POST
⚠️ 重要声明
本文档基于对已有APK的合法分析,仅供漫展主办方用于开发自动检票系统。分析日期:2026-04-08
B站检票API接口与核票逻辑分析
本文档基于对B站检票软件的合法逆向分析,详细记录了API接口、认证机制、数据库结构和核票业务流程。 适用于漫展主办方开发自动检票系统参考。
一、核心发现概览
已确认的API接口(10个)
| 序号 | API路径 | 功能推测 | 优先级 |
|---|---|---|---|
| 1 | /api/ticket/check/project/index |
获取活动/项目列表 | ⭐⭐⭐ |
| 2 | /api/ticket/check/project/checkInfo |
获取核销配置信息 | ⭐⭐⭐ |
| 3 | /api/ticket/check/ticket/checkNew |
核心核票接口 | ⭐⭐⭐⭐⭐ |
| 4 | /api/ticket/check/ticket/pullNew |
拉取待核销票据列表 | ⭐⭐⭐⭐ |
| 5 | /api/ticket/check/ticket/pullbuyer |
拉取购票人详细信息 | ⭐⭐⭐ |
| 6 | /api/ticket/check/ticket/pushCheck |
提交核销结果 | ⭐⭐⭐⭐⭐ |
| 7 | /api/ticket/check/ticket/userTicket |
查询用户票据详情 | ⭐⭐⭐ |
| 8 | /api/ticket/check/user/check |
用户核销状态检查 | ⭐⭐⭐ |
| 9 | /api/ticket/check/user/version |
版本兼容性检查 | ⭐⭐ |
| 10 | /api/ticket/check/check/list |
获取核销历史记录 | ⭐⭐⭐ |
基础域名
- 主域名:
https://show.bilibili.com(票务系统专用) - 备选域名:
https://api.bilibili.com - 认证域名:
https://passport.bilibili.com
二、API接口验证结果 ✅
ℹ️ 验证信息
验证日期:2026-04-08 | 验证方式:直接HTTP请求测试 + Python脚本测试 | 验证状态:✅ 已完成完整验证
认证参数说明(已确认)
关键发现: token参数需要使用URL解码后的SESSDATA
| 参数名 | 说明 | 获取方式 |
|---|---|---|
uid |
用户ID | Cookie中的DedeUserID |
token |
认证令牌 | SESSDATA URL解码后 |
ptoken |
平台令牌 | Cookie中的bili_jct |
Python示例
from urllib.parse import unquote
# 从Cookie获取
uid = cookies['DedeUserID'] # 直接使用
token = unquote(cookies['SESSDATA']) # 需要URL解码!
ptoken = cookies['bili_jct'] # 直接使用
# 构造认证参数
auth_params = {
'uid': uid,
'token': token, # 解码后的SESSDATA
'ptoken': ptoken,
}
三、完整API接口详解
📌 GET /api/ticket/check/project/index
功能: 获取当前账号可管理的活动/项目列表
用途: 登录后首先调用此接口获取可用的漫展活动,返回活动ID、名称、时间、状态等信息
请求示例
GET https://show.bilibili.com/api/ticket/check/project/index
Headers:
Cookie: SESSDATA=xxx; bili_jct=xxx
User-Agent: BiliTicket/1.0 (Android)
Query Params (可选):
status: active # 筛选进行中的活动
page: 1
page_size: 20
响应格式
{
"code": 0,
"message": "success",
"data": {
"list": [
{
"project_id": 12345,
"name": "2026春季动漫展",
"start_time": "2026-05-01 09:00:00",
"end_time": "2026-05-03 18:00:00",
"status": 1,
"screen_count": 10,
"total_tickets": 5000,
"checked_count": 1200
}
],
"total": 1
}
}
🚀 POST /api/ticket/check/ticket/checkNew [最重要]
功能: 执行核票操作(主接口)
这是整个系统的核心接口!用于验证用户提交的二维码是否有效并完成核销。
请求格式
POST https://show.bilibili.com/api/ticket/check/ticket/checkNew
Content-Type: application/x-www-form-urlencoded
# 方式1: 提交二维码内容
qr_code_content=eyJwcm9qZWN0X2lkIjoxMjM0NSwic2NyZWVuX2lkIjoxMDAxLCJ0aWNrZXRfaWQiIjo1Njc4OX0=
&project_id=12345
&screen_id=1001
&device_id=your_device_unique_id
&check_mode=1
×tamp=1715241600000
&sign=md5_hash_signature
成功响应
{
"code": 0,
"message": "success",
"data": {
"result": true,
"check_time": 1715241600000,
"ticket_info": {
"order_id": 987654321,
"ticket_id": 56789,
"buyer_uid": 12345678,
"buyer_name": "张***",
"ticket_type": "单日普通票",
"seat_info": "A区 12排 15座",
"price": "68.00",
"status": 1,
"check_count": 1,
"is_master": true
},
"certificate_info": {
"name": "张三",
"type": 1,
"code": "310***********1234"
}
}
}
错误响应示例
// 1. 二维码无效
{"code": -101, "message": "二维码无效或已过期"}
// 2. 重复核销
{"code": -102, "message": "该票已被核销", "data": {"checked_time": "..."}}
// 3. 场次不匹配
{"code": -103, "message": "此票不属于当前场次"}
// 4. 权限不足
{"code": -403, "message": "无权核销此活动"}
四、认证机制详解
登录方式
方式一:Cookie/SESSDATA(推荐)
从浏览器登录 show.bilibili.com 后提取Cookie:
import requests
session = requests.Session()
# 设置Cookie(从浏览器复制)
cookies = {
'SESSDATA': '你的SESSDATA值',
'bili_jct': '你的csrf_token',
'DedeUserID': '你的UID',
'buvid3': '设备指纹'
}
# 验证登录是否有效
resp = session.get(
'https://show.bilibili.com/api/ticket/check/project/index',
cookies=cookies
)
if resp.json().get('code') == 0:
print("✅ 登录成功!")
else:
print("❌ Cookie已过期,请重新登录")
请求签名机制
根据代码分析,B站API通常使用以下签名参数:
{
"appkey": "84956560bc028eb7",
"build": 6200300,
"mobi_app": "android",
"platform": "android",
"ts": 1715241600000,
"sign": "md5(appkey+params+appsecret)"
}
五、本地数据库结构
TICKET表(票据表)
CREATE TABLE IF NOT EXISTS "TICKET" (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
SID INTEGER, -- Screen ID(场次ID)
PID INTEGER, -- Project ID(活动ID)
PRICE TEXT, -- 票价
STATUS INTEGER NOT NULL, -- 状态 (0=未核销, 1=已核销, 2=异常)
QR TEXT, -- 原始二维码内容
QR_ENCRYPT TEXT NOT NULL, -- 加密后的二维码
SKU_ID INTEGER, -- 票种ID
SEAT TEXT, -- 座位信息
STATUS_STASH INTEGER NOT NULL, -- 备用状态字段
SYNC_STATUS INTEGER NOT NULL, -- 同步状态
DEVICE_ID TEXT, -- 扫描设备ID
UID TEXT, -- 购票人UID
TIMESTAMP TEXT, -- 核销时间戳
MODE INTEGER NOT NULL, -- 核销模式
REDEEM TEXT, -- 兑换码
MID TEXT, -- 机器ID或管理员ID
VERSION INTEGER, -- 数据版本号
ORDER_ID INTEGER, -- 订单ID
BUYER_ID INTEGER, -- 购买者UID
CHECK_MODE INTEGER NOT NULL, -- 检票模式
IS_MASTER INTEGER NOT NULL -- 是否为主票
);
关键字段说明:
- QR_ENCRYPT: 加密后的二维码,防止本地数据库泄露
- SYNC_STATUS: 支持离线核销,网络恢复后自动同步
- MODE: 支持多种核销模式(在线、局域网)
六、业务逻辑流程图
完整核票流程
┌─────────────────────────────────────────────────────┐
│ 开始核票 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤1: 初始化 │
│ • 加载本地配置 │
│ • 检查登录状态 │
│ • 检查Token有效性 │
│ • 获取设备ID │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤2: 选择活动 │
│ • 调用 /api/ticket/check/project/index │
│ • 展示活动列表 │
│ • 用户选择目标活动 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤3: 选择场次和票种 │
│ • 调用 /api/ticket/check/project/checkInfo │
│ • 加载场次列表 │
│ • 加载票种列表 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤4: 扫描二维码 │
│ • 启动相机或红外扫描器 │
│ • 使用ZXing库解码 │
│ • 解析得到 qrCodeContent │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤5: 调用核票API (核心!) │
│ POST /api/ticket/check/ticket/checkNew │
└──────────────────────┬──────────────────────────────┘
│
┌────────┴────────┐
│ │
成功 ✅ 失败 ❌
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ 显示票务信息 │ │ 显示错误原因 │
│ 播放成功音效 │ │ 播放失败音效 │
│ 保存到本地DB │ │ 记录失败日志 │
│ 同步到服务器 │ └──────────────────┘
└──────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 步骤6: 完成 │
│ • 更新统计数字 │
│ • 刷新历史记录列表 │
│ • 准备下一次扫描 │
└─────────────────────────────────────────────────────┘
感谢您的阅读
最后更新: 2026-04-08