自营售票用户端接口.md 18 KB

自营售票 · 用户端接口(按调试顺序)

用户端前缀 /thirdParty。三种身份共用这一套路径,靠登录时写入 token 的类型区分:

身份 登录方式 能看到的票
微信公众号 wx 网页授权 票种勾了渠道 wx
微信小程序 wx-mini wx.login 换 code 票种勾了渠道 wx-mini
自营分销商 third-party 账号密码 票种勾了渠道 third-party 且管理端已授权给该分销商

请求头 token 名:satoken-thirdParty(和租户管理端的 satoken 不是同一个)。登录接口本身不带这个头。

统一 POST + application/json(登录里几个微信接口是 GET)。业务参数放在 data 里:

{ "data": { ... } }

成功:code = 200,业务数据在 data。写接口成功时 data 可能为空。

分页列表的 data 是 MyBatis-Plus 分页对象:

字段 说明
records 当前页列表
total 总条数
size 每页条数
current 当前页

公共分页字段(挂在 data 上):

字段 必填 说明
pageNum 否 页码,建议传 1
pageSize 否 每页条数。要一次拉全量可传 -1

删除类统一 data.idList。

哪些接口谁能调

模块 微信 / 小程序 自营分销商
登录、景点、票种、下单、订单、退单、开票 可以 可以
微信支付 /thirdParty/pay/wxPay 可以(待支付订单) 一般不用
当前登录 /thirdParty/auth/me 只回 token 回余额、资料、已授权票种
售票/核销统计、报表 调了会「无权访问」 只看自己的单

管理端配置走 自营售票管理端接口.md,不要从用户端调 /tenant/**。

接口目录(按联调顺序)

顺序 模块 方法 路径 备注
1 登录 GET /thirdParty/auth/wxAuth 仅公众号,302 跳微信
1 登录 GET /thirdParty/auth/wxLogin 仅公众号回调
1 登录 GET /thirdParty/auth/wxMiniLogin 仅小程序
1 登录 POST /thirdParty/auth/thirdPartyLogin 仅分销商
1 登录 POST /thirdParty/auth/me 已登录后刷新资料
2 景点 POST /thirdParty/selfScenic 列表 非分页
3 票种 POST /thirdParty/selfTicketType 列表 非分页,价格是底价
3 票种 POST /thirdParty/selfTicketType/get 某天详情 日历价、场次库存
4 订单 POST /thirdParty/order/create 下单
4 支付 POST /thirdParty/pay/wxPay 仅微信/小程序待支付单
4 订单 POST /thirdParty/order/list 我的订单
4 订单 POST /thirdParty/order/{id} 详情
4 订单 POST /thirdParty/order/cancel 退单
5 发票 POST /thirdParty/invoice/query 只能查自己的票
5 发票 POST /thirdParty/invoice/doInvoice
6 统计 POST /thirdParty/statistics/orderSaleStatistics 仅分销商
6 统计 POST /thirdParty/statistics/orderCheckStatistics 仅分销商
6 报表 POST /thirdParty/reportMission 列表 仅分销商
6 报表 POST /thirdParty/reportMission/delete 仅分销商

建议联调:先登录拿到 token → 景点列表有数据 → 票种列表有数据 → 用详情接口看某一天价格 → 再下单。分销商下单用余额;微信/小程序下单后走微信支付。


1. 登录 /thirdParty/auth

1.1 自营分销商登录

POST /thirdParty/auth/thirdPartyLogin

账号由管理端「自营分销商」创建。密码传输方式和现有管理端登录一样:前端 DES 加密后再放进 password,不要明文。

字段 必填 说明
projectName 是 租户项目名
userName 是 登录名(管理端的 loginName)
password 是 DES 加密后的密码

失败常见文案:用户名或密码不正确、账号已禁用。禁用后已登录的 token 也会被踢掉。

返回:

字段 说明
token 后续请求头 satoken-thirdParty
userThirdParty 分销商资料,不含密码

userThirdParty 主要字段:

字段 说明
id 分销商 id
name 名称,下单后订单渠道就是这个 name
loginName 登录名
balance 当前余额,不足不能用余额下单
contactName / phone / remark 资料
selfTicketTypeList 已授权票种(结构接近管理端票种详情)。售卖当天价仍以 3.2 详情为准

1.2 当前登录信息

POST /thirdParty/auth/me

body 可空:{ "data": {} }。必须带 token。

  • 分销商:刷新余额、资料、授权票种(账号被禁用会失败)
  • 微信/小程序:只回 token,没有 userThirdParty

1.3 微信公众号授权(引导跳转)

GET /thirdParty/auth/wxAuth?projectName={项目名}

浏览器打开这个地址,后端 302 到微信授权页。前端要做的是拼好 projectName 让用户点进去,不是 POST。

1.4 微信公众号登录回调

GET /thirdParty/auth/wxLogin?projectName={项目名}&code={code}&state={state}

微信授权回来带 code、state。返回 { token }。

网关如果把用户端映射成 /app/**,授权回调地址可能配的是 /app/auth/wxLogin,和这里是同一套登录,以实际部署的对外路径为准。

1.5 微信小程序登录

GET /thirdParty/auth/wxMiniLogin?projectName={项目名}&code={code}

小程序 wx.login 拿到 code 再调。返回 { token }。请求头同样是 satoken-thirdParty(不是 satoken-app)。


2. 景点列表 /thirdParty/selfScenic

景点本身没有单独的用户端筛选。后端按当前身份自动过滤:至少有一个当前渠道能买到的票种绑了这个景点。分销商还要这个票种已被授权。

data 可空对象。返回数组(不是分页)。

POST /thirdParty/selfScenic

每项:

字段 说明
id 景点 id
name 名称
address 地址
openingTime 开放时间文案
picture 轮播图,逗号分隔
isOpen 1 开放 / 0 关闭
publicAnnouncement 公告
scenicDescription 图文描述

列表接口前端不用传渠道、分销商 id,后端从 token 里取。


3. 票种 /thirdParty/selfTicketType

3.1 列表

POST /thirdParty/selfTicketType

data 可空。返回数组。价格是票种底价,某一天能不能买、卖多少钱,要调 3.2。

微信/小程序:只返回勾了对应渠道的票。分销商:渠道 third-party + 管理端授权。

列表每项主要字段:

字段 说明
id 自营票种 id,下单、详情都用这个
ticketTypeId 线下票种数字 id
category ticket 景区门票 / batch 场次 / member 年卡次卡
name 对客名称
isSale 票种自身在售;某一天还可能被日历改成禁售
price / highPrice 底价、划线价
realNameType 0 不限;1 一证一人;2 一证多人
saleDateStart / saleDateEnd 可售日期
saleTimeStart / saleTimeEnd 可售时段
saleMinNums / saleMaxNums 单订单张数限制,>0 才生效
saleMaxPreDays / saleMinPreDays 最多可订未来 X 天 / 最少提前 X 天
isAllowCancel 1 可退
isAgreeProtocol / buyProtocol 是否必须勾协议、协议正文
dayStock / totalStock 日库存 / 总库存,0 不限
useDays / useDateType / useDateStart / useDateEnd 门票有效期相关
memberActiveType 年卡:1 购买即激活 / 2 首次使用激活

列表不带绑定景点、场次。要展示景点、要算某天价,走详情。

3.2 某天详情(下单前必调)

POST /thirdParty/selfTicketType/get

字段 必填 说明
id 是 自营票种 id
playDateBegin 是 游玩日期 yyyy-MM-dd

未授权会「票种未授权」或「票种不存在」。

在列表字段基础上:

字段 说明
price / isSale 已被销售日历覆盖。下单时传入的票价必须等于这里的 price,否则「票价已更新」
scenicList 绑定景点
scenicList[].selfScenicId / selfScenicName 景点
batchConfigList 场次票的场次配置(时段、停售/停退规则)
batchList 该游玩日的场次实例:已售、剩余、是否可售

batchList 项:

字段 说明
batchConfigId 场次 id
batchDate 日期
maxSaleNums / soledNums / leftNums 最大、已售、剩余
status 1 可售

前端下单页:先选日期调这个接口,用返回的 price 填到每张票上。


4. 订单 /thirdParty/order

只能操作当前登录用户自己的单。订单渠道 otaSourceName:微信是「微信」,小程序是「微信小程序」,分销商是分销商 name。

4.1 下单

POST /thirdParty/order/create

字段 必填 说明
payWay 分销商余额支付时必填 分销商传 USER_BALANCE:校验余额、扣款、直接出票。不传或其它值:订单保持待支付,留给后续支付(如主扫)。微信/小程序可忽略,一律待支付
buyerName / buyerPhone 否 购买人
buyerIdentify / buyerIdentifyType 否 证件;类型见下表
ticketList 是 至少 1 张

ticketList 每一张:

字段 必填 说明
selfTicketTypeId 是 自营票种 id
price 是 必须等于详情接口当天价
playDateBegin 是 游玩日,不能早于今天
guestName / guestPhone 否 游客
guestIdentify / guestIdentifyType 视实名 realNameType=1 每张都要证件;=2 整单至少一张有证件

证件类型:0 身份证(默认),1 护照,2 军官证,3 台胞证,4 港澳通行证,5 大陆居民往来台湾通行证,6 港澳居民来往内地通行证,7 外国人永久居留证,8 港澳台居民居住证。

同一票种多张就往 ticketList 里重复加,张数受 saleMinNums / saleMaxNums、日库存、总库存限制。

金额为 0 会直接出票。分销商 USER_BALANCE 且余额不足会失败。账号禁用会「下单未授权」。

返回完整订单(含票),字段见 4.3。分销商余额支付成功后 payStatus=PAYED,票进入出票流程;微信/小程序此时一般是 WAIT_PAY,再调支付。

待支付单超时会被关掉(CLOSED)。

4.2 微信支付(微信 / 小程序)

POST /thirdParty/pay/wxPay

只处理当前用户、且 payStatus=WAIT_PAY 的订单。走微信 JSAPI。

字段 必填 说明
orderId 是 订单 id(4.1 返回的 id)
openId 是 当前微信用户 openId

返回微信 wx.requestPayment 所需字段(appId、timeStamp、nonceStr、package、signType、paySign 等)。支付成功由微信回调,前端轮询订单详情看是否已支付。

分销商余额下单不要调这个接口。

4.3 我的订单

POST /thirdParty/order/list

data 里目前没有业务筛选项,带分页即可。只返回当前用户的单,含票列表。

订单主要字段:

字段 说明
id 订单 id,详情、支付、退单用这个
orderNo / partnerOrderNo 订单号
otaSourceName 销售渠道
payStatus WAIT_PAY / PAYED / CLOSED
payTime / closeTime 支付、关闭时间
status 见下表
price 订单总额
buyerName / buyerPhone / buyerIdentify 购买人
isSelfOrder 自营单为 1
ticketList 票

订单 status:

值 含义
WAIT_PAY 待支付
WAIT_CONFIRM 待确认(出票中)
WAIT_USE 待使用
PART_USE 部分核销
REFUNDING 退款中
CANCELED 已取消
PART_CANCEL 部分退
COMPLETE 已完成
CLOSED 已关闭

票主要字段:

字段 说明
id 票 id,退单时用
ticketTypeName 票种名
ticketNo / otaTicketNo 线下票号 / 线上票号
qrcodeUrl 二维码
playDateBegin / playDateEnd 可用日期
status 见下表
price 售价
guestName / guestPhone / guestIdentify 游客
firstCheckTime / checkTime 首次/最近核销
cancelPrice / cancelCompleteTime 退款金额、完成时间

票 status:

值 含义
WAIT_USE 待使用
USED 已核销
REFUND_REQUEST 退款请求中
REFUNDING 退款中
CANCELED 已退
CLOSED 已关闭

4.4 订单详情

POST /thirdParty/order/{id}

路径上的 {id} 是订单 id。body 仍走统一 Request,data 可空。不是自己的单会「订单不存在」。结构同列表单项。

4.5 退单

POST /thirdParty/order/cancel

字段 必填 说明
orderId 是 订单 id
ticketCancelRequestList 是 要退的票,至少 1 张
ticketCancelRequestList[].ticketId 是 票的 id

两种情况:

  1. 待确认(WAIT_CONFIRM):必须一次退掉订单里全部票,不能部分退。
  2. 已出票成功:可以部分退。会转到线下确认,确认后票进入退款中;分销商余额支付的会把钱退回余额。

用户端不能退:未支付、已关闭、已核销、票种 isAllowCancel=0、已经在退款中/已退的票。管理端强制退不受这些限制,用户端会。


5. 发票 /thirdParty/invoice

只能开自己订单上的票。票号可以是 ticketNo 或 otaTicketNo。

5.1 开票查询

POST /thirdParty/invoice/query

字段 必填 说明
ticketNo 是 票号

不是自己的票会「门票不存在」。

若已经开过,返回里带 invoiceRecordList,前端展示已开记录即可。

尚未开过时,主要字段:

字段 说明
success 是否可开
orderNo / orderCreateTime 订单号、下单时间
price 本单可开总金额
ticketNos 本单可开的全部票号,开票时原样带回
ticketTypeNames 票种名
sellerGroups 按销售方拆开的金额。一张票可能拆成多家开
sellerGroups[].sellerName / price 销售方名称、金额

已开记录里前端常用:status、downloadUrl、qrcodeUrl、fpdm / fphm、买卖方信息。

开票 status:SUCCESS 已开、INVOICING 开票中、FAILED 失败、RED_INVOICING 红冲中、RED_SUCCESS 已红冲。

5.2 开票

POST /thirdParty/invoice/doInvoice

建议把 5.1 返回里需要的字段拷到请求里,再补买方信息。

字段 必填 说明
ticketNos 是 可开票号集合,来自查询
sellerGroups 是 来自查询
orderNo / orderCreateTime / price 否 来自查询,建议带回
invoiceBuyerName 是 买方名称
invoiceBuyerTaxNum 企业要税号 买方税号
invoiceBuyerAddress / invoiceBuyerPhone 否 地址、电话
invoiceBuyerBank / invoiceBuyerAccount 否 开户行
invoiceBuyerReceiveEmail / invoiceBuyerReceivePhone 否 收票邮箱、手机
remark 否 备注

已开或开票中会失败。提交后异步出票,再查 5.1 看状态和下载地址。


6. 售票统计 / 核销统计 / 报表(仅自营分销商)

微信、小程序调这些接口会「无权访问」。数据被后端写成当前分销商自己的订单,不用再传销售来源。

ticketTypeIdList 是线下票种数字 id(票种上的 ticketTypeId),不是自营票种 id。

导出:export=true 异步出 Excel,到 /thirdParty/reportMission 拿 downloadUrl。不要去租户的 /tenant/reportMission。exportDetail=true 时售票统计多售票/退票明细 sheet,核销统计多核销明细,需同时 export=true。

6.1 售票统计

POST /thirdParty/statistics/orderSaleStatistics

按票种 + 单价分组,最后一行是总计。

字段 必填 说明
timeBegin / timeEnd 是 yyyy-MM-dd HH:mm:ss。售票按购票时间,退票按退票完成时间
ticketTypeIdList 否 线下票种数字 id
groupByList 否 目前支持 orderDateDay(按天)
export / exportDetail 否 见上

otaSourceNameList 不用传,后端已按当前账号过滤。

返回数组,每项:

字段 说明
orderDateDay 按天时的日期;总计行为「总计」
otaSourceName 渠道(自己的分销商名)
ticketTypeName 票种
unitPrice 单价
saleNum / salePrice / saleSettlementPrice 售
cancelNum / cancelPrice / cancelSettlementPrice 退
actualNum / actualPrice / actualSettlementPrice 实售(售 − 退)

6.2 核销统计

POST /thirdParty/statistics/orderCheckStatistics

字段 必填 说明
checkTimeBegin / checkTimeEnd 是 首次核销时间
ticketTypeIdList 否 线下票种数字 id
groupByList 否 orderDateDay
export / exportDetail 否 同售票统计

返回:checkCount 张数、checkPrice 金额、checkSettlementPrice 结算价,以及票种、单价、日期。

6.3 报表列表

POST /thirdParty/reportMission

只看到自己导出的任务。

字段 必填 说明
createTimeBegin / createTimeEnd 否 任务创建时间
fileName 否 文件名
type 否 0 导出 / 1 导入
status 否 0 进行中 / 1 成功 / 2 失败

返回 records 每项:id、fileName、type、downloadUrl、status、createTime。

点导出后轮询列表,status=1 再用 downloadUrl。

6.4 删除报表

POST /thirdParty/reportMission/delete

data.idList。只能删自己的。


联调顺序(建议)

分销商端

  1. thirdPartyLogin 拿到 token 和余额
  2. /me 能刷到最新余额
  3. 景点列表、票种列表有管理端授权过的数据
  4. 票种详情换日期,确认日历价
  5. payWay=USER_BALANCE 下单,订单已支付、余额减少
  6. 订单列表 / 详情 / 退单(退成功后余额加回)
  7. 用票号查开票、开票
  8. 售票统计、核销统计;export=true 后到分销商报表列表下载

微信 / 小程序

  1. 对应登录拿到 token
  2. 景点、票种、详情
  3. 下单(待支付)→ wxPay → 轮询详情已支付
  4. 订单列表、退单、开票
  5. 不要接统计和报表

管理端没勾渠道、没给分销商授权,用户端列表就是空的,先查管理端配置。