活动系列与自助选座
活动系列将共用座位布局的赛季或赛事活动组织在一起,例如俱乐部主场比赛或锦标赛摄影位置。系列内每个活动均从同一模板创建,继承价格、座位分配和座位属性,创建后即可预订。
结合预订会话,获授权人员可在 Renderer 中为每个活动选择自己的座位;您的系统以资质 ID 等已知引用确认,并按单场或整个系列读取结果。
适用场景
- 同一布局的赛季:反复使用相同场地和座位图。只需为模板设置一次价格和座位属性,再按比赛、演出或服务日期添加活动。
- 自助选座:人员自己选座,不通过座位图付款。门户负责身份,座位图负责座位。
- 媒体与工作人员位置:摄影位、记者席或工作桌,每名获授权人员每场占一个位置,计划变化时可释放。
不重复的单场活动无需系列;下述预订会话流程适用于任何已发布活动。
概念
| 术语 | 含义 |
|---|---|
| 模板 | 组织内已发布活动,系列活动复制其价格、座位分配及座位属性。 |
| 系列 | 包含名称、模板、场地时区和 ACTIVE、PAUSED、ARCHIVED 状态的容器。 |
| 活动 | 系列中的一次场次,按开始时间创建;每个开始时间对应一个活动,创建后开始时间固定。 |
| 会话 | 浏览器端购物车,由 Renderer 无需 API 密钥地创建和驱动,在选座期间持有座位。 |
| 引用 | 系统确认会话时存储的标识,例如资质 ID;一个引用每场只能有一个已确认会话。 |
| 属性 | 系统随已确认会话存储的 JSON 对象,如姓名、机构或证件号,从不公开。 |
授权
组织侧调用在 X-API-Key 头中发送组织令牌。将其视为不透明字符串,预先配置到服务器凭据存储并原样发送。
X-API-Key: {organizationToken}
Renderer 使用的公共会话端点无需密钥,会话 ID 即凭据。组织令牌留在服务器,浏览器只调用公共端点。
1. 创建系列
发布模板活动,分配价格,并按 Renderer 需要设置座位属性,然后创建系列:
POST /api/private/v2.0/series/
{
"name": "Champions League 2026/27",
"templateEventId": "123e4567-e89b-12d3-a456-426614174000",
"timeZone": "Europe/Paris"
}
响应返回系列 id、schemaId 和 ACTIVE 状态。时区为场地的 IANA 时区,开场关闭公共预订时按该时区解释开始时间。
模板必须属于您的组织、已发布,且本身不属于系列。之后更换模板可向 PUT /api/private/v2.0/series/{id} 发送新的 templateEventId;新模板必须使用相同座位图,已创建活动保留原来的分配。
2. 添加活动
POST /api/private/v2.0/series/{id}/events/
{
"start": "2026-09-15T21:00:00",
"end": "2026-09-15T23:00:00",
"name": "Paris v Munich"
}
新活动自动发布并继承模板价格、座位分配和属性,返回 201。每个开始时间只创建一个活动;重复相同开始时间返回已有活动和 200,因此可安全重试。名称可选,默认由系列名称加开始时间组成。
系列活动的开始时间固定。通过 PUT 修改开始时间会返回 409 EVENT_BOUND_TO_SERIES,名称和结束时间仍可修改。PAUSED 或 ARCHIVED 系列拒绝新活动,返回 409 SERIES_NOT_BOOKABLE。
按时间从早到晚列出系列活动:
GET /api/private/v2.0/series/{id}/events/
3. 让用户在 Renderer 中选座
在人员已登录门户的页面嵌入 Renderer,加载所选比赛的活动。包中导出的 BookingSessionClient 从浏览器驱动公共会话端点:
- create 为活动创建会话。每次新尝试使用新的幂等键,响应含会话 ID、到期时间和座位上限。
- lock 保留所选座位,在会话有效期内持续保留,用户继续选择时刷新有效期。
- checkout 冻结购物车,等待您的系统确认。
将会话 ID 连同人员身份交给后端。公共端不记录人员身份,座位图只知道会话。
若要求每人每场一个座位,在部署中将 global.bookingSessions.maxSeats 设为 1(默认 10)。Renderer 从会话读取上限,拒绝向购物车添加第二个座位。
4. 从您的系统确认
后端使用已知引用及要保存的对象确认冻结会话:
POST /api/private/v2.0/session/{id}/confirm
{
"reference": "ACC-2026-0042",
"properties": { "name": "Ada Lovelace", "agency": "Reuters", "badge": "P-12" }
}
座位变为已售,会话变为 CONFIRMED,响应包含引用和属性。properties 可为任意 JSON,序列化后最多 16 KB。它在会话、按引用读取的座位分配及下文系列级读取中返回,绝不经公共端点或 Renderer 暴露。
同一引用每场仅能有一个已确认会话。第二次以相同引用确认同场活动会返回 409 REFERENCE_TAKEN;已知持有者时在 sessionId 中返回。被拒绝会话仍冻结,可取消以立即释放座位,或等待过期。确认前应检查此人是否已有座位,并按状态筛选,排除已释放预订:
GET /api/private/v2.0/session/?eventId={eventId}&reference=ACC-2026-0042&state=CONFIRMED
释放后的取消会话保留 reference,同一引用可以再次确认。
之后要修改已存对象,在已确认会话上替换:
PUT /api/private/v2.0/session/{id}/properties
请求正文就是新对象,完全替换旧值。
5. 读取座位
按活动读取,并包含每个座位所属会话:
GET /api/private/v2.0/event/{eventId}/prices/assignments/?reference=ACC-2026-0042
reference 筛选选择座位。通用入场容量按区域而非按人计数,应从会话本身读取。
seatsOnEvent 中每个座位包含 state、holdType(会话持有或购买时为 CART)、座位自己的 properties,以及含 sessionId 和 reference 的 booking 对象;使用 reference 筛选时还包含会话 properties。不传 reference 时,如之前一样返回活动所有座位,无论是否预订。
读取整个系列,最早活动在前:
GET /api/private/v2.0/series/{id}/assignments/?reference=ACC-2026-0042
每项包含 eventId、eventName、start,以及上述相同字段的座位。不传 reference 时,列出系列所有活动中由会话持有或购买的座位。
6. 释放座位
资质撤销或计划变化时,从您的系统释放已确认会话:
POST /api/private/v2.0/session/{id}/release
座位和 GA 容量返回可用库存,会话变为 CANCELLED,reference 可再次预订该场活动。只用此调用释放已确认会话库存。操作幂等,对已取消会话重复调用返回当前状态。尚未确认时返回 409 SESSION_NOT_CONFIRMED,请改用 cancel 取消有效会话。没有公共对应端点,用户无法从座位图自行释放已确认座位。
开始时关闭预订
系列活动到开始时间后关闭公共预订:create、lock、checkout 返回 409 BOOKING_CLOSED,开始时间按系列时区解释。非系列活动不受影响,开始后仍可预订。读取、解锁、取消继续可用,所有组织侧调用(含 confirm、release)均不受影响,因此后台延迟确认仍可完成。
错误
| 代码 | 状态 | 含义 |
|---|---|---|
REFERENCE_TAKEN |
409 | 同场已有其他已确认会话占用引用。 |
BOOKING_CLOSED |
409 | 活动已开始,公共流程不再接受更改。 |
SESSION_NOT_CONFIRMED |
409 | 对未确认会话调用 release 或替换属性。 |
PROPERTIES_TOO_LARGE |
400 | 属性对象序列化后超过 16 KB。 |
SERIES_NOT_BOOKABLE |
409 | 系列暂停或归档,拒绝新活动。 |
EVENT_BOUND_TO_SERIES |
409 | 请求会移动系列活动的开始时间。 |
INVALID_SERIES_TEMPLATE |
400 | 模板属于系列,或使用与系列不同的座位图。 |
另请参阅
- 直接销售端点:无需会话,一次调用出售座位。
- Renderer 集成:嵌入座位图并读取购物车。