vr-shopxo-plugin/docs/api/VR_TICKET_WALLET_VERIFY_API.md

10 KiB
Raw Blame History

VR票务插件 C端 API 文档

版本: 1.1.0 最后更新: 2026-05-28

本文档描述了 VR 票务插件(vr_ticket)的 C 端 UniApp API涵盖票夹、核销、核销记录三类接口适用于移动端用户及授权核销员使用。


一、概述

1.1 核心机制

机制 说明
动态 QR Payload QR 内容含 HMAC-SHA256 签名,默认 30 分钟 有效期,前端应动态刷新
悲观锁防并发 核销接口使用 FOR UPDATE 事务锁,杜绝重复核销
双重码格式 长码UUID v4与短码Base36 + Feistel 混淆API 自动识别
核销员白名单 C 端用户必须存在于 vr_verifiers 表且 status=1 才可执行核销操作

1.2 响应标准格式

所有 API 均返回以下 JSON 结构:

{
  "code": 0,
  "msg": "success",
  "data": { ... }
}

二、认证机制

2.1 请求头认证

所有 C 端 API 均需携带用户身份令牌。

Header Key: X-Token
Header Value: {user_token}

兜底方案(按优先级):

  1. X-Token / Authorization: Bearer {token}App 登录)
  2. user_info Cookie 解码Web 登录)
  3. Session传统页面

若均未找到,返回:

{
  "code": 401,
  "msg": "请先登录",
  "data": []
}

2.2 核销员身份鉴权

以下 API 除了要求 C 端登录外,还需验证用户是否为授权核销员:

// 未授权(非核销员)
{
  "code": -403,
  "msg": "你不是授权核销员,无权核销",
  "data": []
}

核销员身份由 vr_verifiers 表决定,管理员可在 ShopXO 后台添加。普通用户(非核销员)可正常使用票夹 API但不能执行核销。


三、通用错误码

code 说明
0 成功
-1 通用失败 / 参数错误
-2 该票已核销
-3 该票已退款
-4 QR 数据异常
-403 无核销权限(不是授权核销员)
-404 票不存在或无权访问
-999 系统异常(事务失败)
401 未登录 / 未授权

四、票夹 API

基础路由: /api.php?s=plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction={action} 认证: C 端登录态(无需核销员身份)

4.1 获取用户票列表

GET ...&pluginsaction=list
GET ...&pluginsaction=tickets  (别名)

成功响应 data:

{
  "tickets": [
    {
      "id": 123,
      "goods_id": 456,
      "goods_title": "周杰伦演唱会-北京站",
      "goods_image": "https://...jpg",
      "seat_info": "2026-06-01 20:00|国家体育馆|主厅|A区|A1",
      "seat_number": "A1",
      "session_time": "2026-06-01 20:00",
      "venue_name": "国家体育馆",
      "real_name": "张三",
      "phone": "138****5678",
      "verify_status": 0,
      "issued_at": 1716307200,
      "short_code": "000ca1b2"
    }
  ],
  "count": 1
}
字段 类型 说明
verify_status int 0=未核销 1=已核销 2=已退款
short_code string 9位短码可供核销员扫码
seat_info string 完整 5 维坐席信息,场次|场馆|演播室|分区|座位号

4.2 获取票详情(含 QR Payload

GET ...&pluginsaction=detail&id={ticket_id}

参数:

参数 类型 必填 说明
id int 票 ID

成功响应 data:

{
  "ticket": {
    "id": 123,
    "goods_id": 456,
    "goods_title": "周杰伦演唱会-北京站",
    "goods_image": "https://...jpg",
    "seat_info": "2026-06-01 20:00|国家体育馆|主厅|A区|A1",
    "session_time": "2026-06-01 20:00",
    "venue_name": "国家体育馆",
    "seat_number": "A1",
    "real_name": "张三",
    "phone": "138****5678",
    "verify_status": 0,
    "verify_time": 0,
    "issued_at": 1716307200,
    "short_code": "000ca1b2",
    "qr_payload": "eyJpZCI6MTIzLCJnIjo0NTYsImNvZGUiOiI4OTM1...",
    "qr_expires_at": 1716309000,
    "qr_expires_in": 1800
  }
}
字段 类型 说明
qr_payload string 二维码内容,含 HMAC-SHA256 签名,有效期 30 分钟
qr_expires_at int 过期时间戳(秒)
qr_expires_in int 剩余有效期(秒),固定 1800

失败响应:

// 票不存在或无权访问
{ "code": -404, "msg": "票不存在或无权访问", "data": [] }

// 票已核销(不返回 QR
{ "code": -2, "msg": "该票已核销", "data": [] }

// 票已退款
{ "code": -3, "msg": "该票已退款", "data": [] }

4.3 强制刷新二维码

重新生成 QR Payload重置 30 分钟有效期。

GET ...&pluginsaction=refreshQr&id={ticket_id}

参数: 同 detail

成功响应: 与 detail 完全一致(qr_payload 为新生成)。


4.4 检测核销员身份

轻量接口,用于前端快速判断是否展示核销员入口。

GET ...&pluginsaction=checkVerifier

成功响应 data:

{
  "is_verifier": true,
  "verifier_id": 3,
  "verifier_name": "张三"
}
字段 类型 说明
is_verifier bool 是否为授权核销员
verifier_id int 核销员 ID未授权时为 0
verifier_name string 核销员名称,未授权时为空字符串

五、核销 APIUniApp 授权核销员专用)

基础路由: /api.php?s=plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=verify 认证: C 端登录态 + 必须是 vr_verifiers 表中 status=1 的授权核销员

5.1 扫码核销

POST ...&pluginsaction=verify
Content-Type: application/x-www-form-urlencoded

请求参数:

参数 类型 必填 说明
ticket_code string 扫码得到的票码(短码或 UUID

自动识别规则:

  • 长度 < 20 且不含连字符 - → 短码Base36 + Feistel 混淆)
  • 包含连字符 - → UUID v4 长码

成功响应 (code: 0):

{
  "code": 0,
  "msg": "核销成功",
  "data": {
    "seat_info": "2026-06-01 20:00|国家体育馆|主厅|A区|A1",
    "real_name": "张三",
    "goods_name": "周杰伦演唱会-北京站"
  }
}

失败响应:

code msg 场景
-1 票码不存在 短码解码失败或票不存在
-2 该票已核销 重复核销
-3 该票已退款 票已退款
-403 你不是授权核销员,无权核销 C 端用户不在核销员白名单
401 请先登录 未登录
-999 核销失败,请重试 数据库事务异常

六、核销记录 APIUniApp 授权核销员专用)

基础路由: /api.php?s=plugins/index&pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=myVerifications 认证: C 端登录态 + 必须是 vr_verifiers 表中 status=1 的授权核销员

6.1 我的核销记录

GET ...&pluginsaction=myVerifications

请求参数:

参数 类型 必填 默认值 说明
page int 1 页码
page_size int 20 每页条数(最大 100

成功响应 data:

{
  "list": [
    {
      "id": 1,
      "ticket_id": 123,
      "ticket_code": "8935b3a3-a7b4-4e3d-8c1f-9b7e2a6f5d4c",
      "seat_info": "2026-06-01 20:00|国家体育馆|主厅|A区|A1",
      "real_name": "张三",
      "goods_title": "周杰伦演唱会-北京站",
      "created_at": 1716307200
    }
  ],
  "total": 50,
  "page": 1,
  "page_size": 20,
  "pages": 3
}

失败响应:

code msg 场景
-403 你不是授权核销员 非授权核销员
401 请先登录 未登录

七、QR 二维码前端最佳实践

7.1 动态刷新策略

  1. 倒计时渲染:使用 qr_expires_in 启动本地倒计时器
  2. 过期遮罩:剩余时间 ≤ 0 时显示模糊/遮罩 + "点击刷新"按钮
  3. 静默刷新:过期前 30 秒自动调用 refreshQr 重新获取并渲染

7.2 短码编码规则

短码结构:【4位 goods_id 明文 base36】【变长 ticket_id 混淆 base36】

  • 解码 O(1):前 4 位直接取 goods_id剩余部分用 Feistel 解密得到 ticket_id
  • 示例:000ca1b2goods_id=0, ticket_id=12345
  • 核销员 App 扫描时应获取完整短码字符串进行提交

附录:数据字典

vr_tickets 电子票表

字段 类型 说明
id int 票 ID自增
goods_id int 关联商品 ID
order_id int 关联订单 ID
user_id int 购票用户 ID
ticket_code string UUID v4 长码
qr_data string 格式 短码|payload,内部缓存
seat_info string 场次|场馆|演播室|分区|座位号
verify_status int 0=未核销 1=已核销 2=已退款
verify_time int 核销时间戳
verifier_id int 执行核销的核销员 ID
real_name string 观演人姓名
phone string 观演人手机
issued_at int 票发放时间戳
created_at int 创建时间戳

vr_verifiers 核销员表

字段 类型 说明
id int 核销员 ID自增
user_id int 关联的 C 端用户 IDShopXO 会员 ID
name string 核销员名称(后台显示用)
status int 1=启用 0=禁用
created_at int 创建时间戳

注意: user_id 关联的是 C 端用户 ID而非后台管理员 ID。C 端用户只需在 vr_verifiers 表中存在且 status=1 即可使用 UniApp 核销功能。

vr_verifications 核销记录表

字段 类型 说明
id int 记录 ID自增
ticket_id int 票 ID
ticket_code string 票长码快照
verifier_id int 执行核销的核销员 ID
verifier_name string 核销员名称快照
goods_id int 商品 ID
created_at int 核销时间戳