网站负责「呈现」,Kai 负责「承接」
日历和申请表单由网站按自己的设计绘制。Kai 负责住宿者名簿、交易条件的公示、取消规定和刷卡支付。
01 四个接口
GET /api/calendar- 空房与价格
POST /api/quote- 报价(总额与取消费的阶梯)
POST /api/book- 申请(支持 Idempotency-Key)
GET /api/booking/:id- 查询预订
与页面走同一条路径。报价与库存的规则没有放在两个地方。 若分开放置,只改一处就会悄悄出现「页面拒绝、API 却通过」的情况;这会影响金额和库存,在账单开出之前无人察觉。
02 不把「订不到」笼统归为一种
每次拒绝都附带原因,并返回是哪几天。
available- 可以售出
occupied- 已售完。属正常
unpriced- 未录入价格。住宿设施补上即可售出
ambiguous- 两个同优先级的方案同时命中
closed- 有意关闭
overbooked- 重复预订。不归零处理
有些现成的预订系统,会把「未设价格」和「客满」都返回为同一个「无空房」。调用方无法区分,住宿设施漏填的价格在客人眼中就成了客满。 我们把两者分开,网站因此可以提示「请录入价格」。
03 接入的形态
目前设想从服务器端调用。 我们不输出 CORS 头,因此无法从浏览器直接调用。适用对象是像 WordPress 这样带有后端的网站。
页面跳转只发生在输入银行卡的那一刻。 那与其他支付页面的体验相同,跳转到另一个域名反而更让人安心。Kai 这一侧可以选择模板,颜色和字体能够保持一致。
是否开放静态网站直接调用,仍在考虑中。如有需要,请在咨询时一并说明。
04 每一次拒绝,都附带可行的下一步
只返回原因的名称,调用方仍不知道该做什么。Kai 会把原因归入六个类别返回。
input- 发送的内容有误。修正后重新发送
state- 再发多少次也不会通过。 客满、无价格、已过期等
retry- 只是当时繁忙。再试一次即可通过
auth- 权限问题
payment- 支付方的问题
internal- 我方的问题
我们没有把 retry 与 state 混在一起。 一旦混同,就会对永远无法通过的请求无休止地重试。请依据类别分支,而不是依据文案。
POST /api/book 接受 Idempotency-Key。头部名称与支付服务商保持一致。重复发送也不会产生两笔预订。
05 名簿无法交给网站一侧
我们不提供「只做支付」的形态。理由有三个。
- 名簿与价格计算相连。 儿童价按年龄分档,因此在谈及法规之前,报价就已经算不出来了。
- 出错的方式很特殊,而且看上去是对的。 需要护照号码的并非「外国籍人士」,而是「在日本国内没有住所的外国人」。即使弄反,页面照常运作,法规却已被违反。
- 三年保存的主体,以及谁在何时查阅过的记录,都会消失。 网站重做时会一并消失。