GET 请求即可实时收到每个事件;连接中断时还能保证重放。
用事件流保持仪表盘实时更新(余额、入金到账、出金结算、卡授权、面向管理员的 KYT 警报);
用 Webhook 处理那些即使用户关闭浏览器也必须完成的逻辑。两个通道传递
完全相同的事件、相同的载荷和相同的 event_id,因此你只需要写一套映射。
打开事件流
该端点使用与其余 API 相同的Authorization: Bearer 凭证,因此浏览器原生的
EventSource(无法发送自定义请求头)不适用。请使用 fetch 并以流的方式读取响应体:
响应
无缝重连
连接中断后,携带最后处理的游标重新连接。服务端会先从日志中重放你错过的事件,再恢复实时推送, 因此不稳定的网络也不会丢事件。重放上限为 1000 条事件。如果断线时间过长、错过的事件更多,事件流会发送控制事件
replay_truncated;此时应使用 ?snapshot=true 或
GET /v1/events/history 进行对账,而不要假设数据连续。初始快照
以?snapshot=true 打开会先发送当前状态,然后才是增量。这消除了经典的竞态问题
(“先读 REST 接口再订阅,中间发生的事件就丢了”):游标是在订阅已经建立之后取的,
不会有任何遗漏。
balances
(字段与 GET /v1/balances 相同);组织管理员还会得到运营
health 计数。
按事件类型过滤
?types= 用于缩小接收范围。它只能收窄凭证已经可见的范围,绝不会扩大。未知类型会返回
400 invalid_event_type,而不是让你一直等待永远不会到达的事件。
范围:账户与组织管理员
一个账户永远看不到其他账户的事件,也看不到组织级合规视图。事件流绝不会返回该凭证通过 REST
无法读取的字段。
控制事件
除业务事件外,事件流还会发送协议事件。除snapshot 外,它们不带 id:,因此不会推进重放游标。
每 20 秒会发送一条
: ping 注释,避免代理断开空闲连接——请忽略以 : 开头的行。
限制
超出并发上限会返回
429 too_many_streams;超出开流配额会返回
429 rate_limited——该配额统计尝试次数,因此即使没有打开任何流,紧密循环
重连的客户端也会耗尽它。请始终遵守 retry:(3 秒)并配合指数退避。
可查询的历史
驱动事件流的同一份日志也可以通过 REST 读取——适用于审计、“我错过了什么”视图,或重放被截断时的对账。错误
完整列表见错误。
常见问题
事件流可以取代 Webhook 吗?
事件流可以取代 Webhook 吗?
不可以。事件流只在页面打开时存在;Webhook 即使无人在线也会送达你的后端。UI 使用事件流,
触发业务逻辑(对账、记账、通知)的部分使用 Webhook。
同一个事件会收到两次吗?
同一个事件会收到两次吗?
会。重连后的重放可能重复投递边界事件,而且两个通道(Webhook 与事件流)共享同一个
event_id。请按 event_id 去重,并把每个载荷视为绝对状态。为什么连接在 30 分钟后关闭?
为什么连接在 30 分钟后关闭?
这是设计使然。没有寿命上限的流会掩盖连接泄漏。服务端会先发送
reconnect 控制事件,
携带 Last-Event-ID 重连即可从中断处继续。需要像 Webhook 那样创建订阅吗?
需要像 Webhook 那样创建订阅吗?
不需要。事件流无需配置:它会推送凭证可见的全部事件。Webhook 订阅只控制发往你服务器的
HTTP 投递。
什么都收不到,连心跳也没有。
什么都收不到,连心跳也没有。
检查你的 HTTP 客户端是否缓冲了响应(在
fetch 中应以流方式读取 res.body,而不是等待
res.text()),以及你自己的代理是否缓冲了 text/event-stream。CBPay 侧已关闭缓冲。组织管理员可以只跟踪一个账户吗?
组织管理员可以只跟踪一个账户吗?
可以,使用
?account_id=。该过滤器只在你自己的组织内生效;其他情况返回 404。