版本与兼容性
版本在路径里:所有端点都在 /v1 下。
没有版本请求头,也不接受你指定版本 —— 同一个 URL 在同一时刻对所有商户
返回同一份契约。规格文件(openapi/*.yaml)上那个 info.version 是文档的版本号,
不是可以拿来钉住行为的东西。
什么算破坏性变更
判据只有一条:照着旧文档写的、正确的接入方,会不会因为这次变更而出错。
会 —— 破坏性。不会 —— 非破坏性,我方随时可以发。
| 变更 | 破坏性? | 你要注意什么 |
|---|---|---|
| 响应里新增字段 | 否 | 你的解析器必须忽略未知字段。严格模式的 JSON 反序列化(比如 Go 的 DisallowUnknownFields、某些 Java 配置)会在这里炸 |
| 请求里新增可选字段 | 否 | 不传即旧行为 |
| 新增枚举值(订单状态、事件类型…) | 否 | 见下一节 —— 这是最需要你提前防的一类 |
| 新增错误码 | 否 | 见下一节 |
改 message 的英文措辞 | 否 | message 是给人看的,我方保留随时改写的自由。按 code 分支,不要按 message 分支 |
| 新增一个端点 | 否 | |
| 删字段、改字段类型、改字段含义 | 是 | |
改 code 的名字 | 是 | |
| 请求里新增必填字段,或收紧已有字段的校验 | 是 | 收紧校验在效果上与新增必填一样:昨天能过的请求今天过不去 |
| 删枚举值 / 删端点 | 是 | |
| 收窄某个字段的取值范围(比如金额精度位数变少) | 是 |
⚠ 有一类看起来像修 bug、实际需要你动手的:同一个失败从 5xx 改成 4xx
(或反过来)。2026-08-12 就发生过一次 —— 一批合法的业务拒绝原本以
500 api_error 返回,改成了带明确 code 的 4xx。为「对 500 也重试」写过绕行
代码的接入方必须把那段拆掉,否则重试逻辑会开始对一批永远不会成功的请求
无限重试。这类变更在变更日志里标着「需要你动手」。
我方对枚举值的承诺
新增状态值会提前在变更日志里登记。
这是我方给出的承诺,也正因如此,它反过来对你提了一个要求:
你的
default分支应当按「未知」处理并告警,而不是假装认识它。
三个必须有兜底分支的地方:
| 在哪 | 认不出来时该怎么办 |
|---|---|
订单/申请单的 status | 当作「还在进行中」保留,不要归进成功或失败任何一边,并告警 |
| Webhook 的事件类型 | 回 2xx(否则我方会一直重投),把它原样存下来,并告警 |
错误响应的 code | 按 type 与 HTTP 状态归档处置(见错误码页的三条重试规则),并告警 |
⚠ 反面写法是 default: 里塞一个「处理中」或「失败」。它不报错、不告警,
只会让某一类新状态被静默地讲错 —— 而你要到用户投诉那天才知道。
我方自己在服务端踩过同一个坑,现在的纪律是「认不出的上游状态一律挂起告警,
绝不 default 成处理中」。
同理,不要用穷尽式的枚举校验去卡响应。收到一个没见过的状态值不该让你的
消费者进程崩掉 —— 那会把一次纯增量的变更变成你那一侧的一次停机。
出现破坏性变更时怎么通知
两个页面是我方维护的事实源:
- 变更日志 —— 每条都标注是否需要你动手。标「需要」的,
不做会在某一天出问题;标「不需要」的是纯增量。
这份日志从 2026-08-12 开始维护,在此之前的变更没有逐条记录;
- 已知问题 —— 还没修的缺陷与绕行办法。修好之后条目会转成
「已修复」并保留一段时间,不会直接删掉 —— 删掉等于让照着旧行为写过绕行
代码的人无从知道可以拆了。
⚠ 这一页不给提前通知期、不给旧版本并行时长、不给任何 SLA。
需要一份写进合同的承诺(提前多少天通知、以什么方式通知到你的技术联系人、
/v1 会维持多久),与你的客户经理确认。凭这份文档去做容量或排期假设是不安全的。
你这一侧的三条最低要求
不做这三条,纯增量的变更也可能把你打挂:
- 忽略未知字段。 别用会因为多一个字段就报错的反序列化配置;
- 每个 switch 都有 default,且 default 会告警。 见上一节;
- 按
code分支,不要按message、也不要只按 HTTP 状态码。
400 里同时混着「你发错了」和「这一单做不成」,两者的重试方式相反。