Skip to content
登录
Veridien Docs

预订

一条预订分两步创建:先在客人付款期间锁定库存,再把这次锁房确认成预订。这样拆开之后,客人一决定就立刻占住房量,而预订只有在收款成功后才最终生效。

预订的生命周期

POST /holds 创建一条暂定预订,把一间房锁住 15 分钟。POST /holds/{id}/confirm 把它变成已确认的预订,并记录付款。未被确认的锁房会自动过期,并把房量释放回去。


POST /holds

权限范围: reservations:write · 支持 Idempotency-Key

创建一条暂定预订,按某个房价方案锁住某个房型的这段日期。这段住宿会被定价(房晚加适用税费)并入账到一张新账单上。在确认或 15 分钟窗口失效之前,这次锁房都会占用房量。

请求体字段必填说明
room_type_id必须属于这家酒店。
rate_plan_id该房型下启用的方案;它的可见性规则会被重新校验。
check_inYYYY-MM-DD
check_outYYYY-MM-DD,晚于 check_in;最长 30 晚。
guest_id这次锁房是为哪位客人。
adults整数 1–20;人数必须装得进 max_occupancy
children整数 0–20,默认 0
child_ages儿童年龄数组(整数 ≥ 0)。一旦传了它,它就是准确的儿童人数,并据此按年龄段做加人计价。
bed_config客人选择的床型配置标签;必须是该房型提供的选项之一。会记在预订上供客房清洁使用。
add_ons客人选择的附加项数组(最多 10 个),在锁房时就逐项定价入账,因此都包含在收取的总额里。字段见下。
promo_code如果所选房价方案需要促销码,则必填。

add_ons 中的每一项都引用一个客人可预订的服务

附加项字段必填说明
service_id要添加的服务。
modifier_values该服务信息采集字段的 { modifier_key: value } 对象。默认为 {}
quantity附加项的数量(整数 1–99)。默认为 1
curl -X POST "$VRDN_BASE/holds" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1d2c9a-8b3e-4a17-9c2f-1e5b7d0a4c83" \
  -d '{
    "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
    "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02",
    "check_in": "2026-08-01",
    "check_out": "2026-08-04",
    "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34",
    "adults": 2
  }'
{
  "reservation_id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27",
  "folio_id": "1a6c3e9f-4d2b-4e8a-b5c7-9f0e6d4a2c81",
  "hold_expires_at": "2026-06-19T08:45:00.000Z",
  "total": "1260.00",
  "currency": "USD",
  "status": "tentative"
}
错误出现时机
409 no_availability该房型在这段日期已售罄。
404 rate_plan_not_found方案已停用,或它的可见性规则把这位客人/这个上下文排除在外。
400 party_too_largeadults + children 超过了该房型的 max_occupancy

POST /holds/{id}/confirm

权限范围: reservations:write · 支持 Idempotency-Key

在你自己的流程里收款,然后带上 payment_reference 确认这次锁房。Veridien 会重新校验房量(不把这次锁房自己算进去),把预订及其住宿单元标记为 confirmed,把付款记到账单上,并对以美元结算的住宿按房费收入发放会员积分。

方式 1 是基于信任的声明模型,请读这一段

这个接口是基于信任的。你的 payment_reference你已经收到钱的一个声明,是一种主张,绝不是证明。Veridien 不会核实这笔钱是否真的到账:你的酒店才是记录商户,资金、争议与退款都归你负责。因此:

  • 每次预订都要发送一个真实且唯一的凭据。绝不要跨预订复用或改写同一个付款 id。
  • 每一次确认都会作为付款声明写入审计日志(谁声明的、凭据是什么、金额多少)。
  • 确认时的校验会挡掉明显错误的输入,但它无法验证钱是否真的易手。

如果你希望由 Veridien 自己核实付款(Stripe 托管、平台核实的收款),那属于托管式预订引擎(方式 2),不是这套 API。

请求体字段必填说明
payment_reference你的付款标识:一个未经核实的、声称你已收款的凭据。确认对这个值是幂等的。
payment_currency可选的 ISO-4217 币种,声明你实际收取的币种。与预订币种不一致会被拒绝。
payment_amount可选金额,声明你实际收取的数额。与账单总额不一致会被拒绝。
curl -X POST "$VRDN_BASE/holds/7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27/confirm" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9a2e7c10-4b3f-4d28-8c1f-2e6b8d0a5d94" \
  -d '{ "payment_reference": "pay_abc123", "payment_currency": "USD", "payment_amount": 1260.00 }'
{
  "reservation_id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27",
  "status": "confirmed",
  "check_in_date": "2026-08-01",
  "check_out_date": "2026-08-04",
  "currency": "USD",
  "folio_balance": "0.00",
  "already_confirmed": false
}
错误出现时机
409 hold_expired你确认之前,这次锁房的 15 分钟付款窗口已经过去。请重新创建一次锁房。
409 no_availability从锁房到确认之间,这次锁房丢掉了它占的房量。
409 not_confirmable这条预订不是一次可确认的暂定锁房(例如已经取消了)。
400 currency_mismatchpayment_currency 与预订币种不一致。
400 amount_mismatchpayment_amount 与账单总额不一致。

两种意义上的幂等

重复确认一条已确认的预订,或重放同一个 payment_reference,都会返回已有的确认结果并带上 "already_confirmed": true,不会有第二次付款,也不会有第二条预订(一个 (folio, reference) 唯一索引保证了并发安全)。再配合 Idempotency-Key,确认可以放心重试。

会员积分以美元计

会员积分按美元房费收入赚取。非美元的住宿不会悄悄地赚到零分;被跳过的这次赚取会被记录下来以便对账,直到多币种赚取功能上线。


GET /reservations

权限范围: reservations:read

返回这家酒店的预订,按入住日期从早到晚排序,并带上每条预订未结清的账单余额。

查询参数说明
guest_id只看某一位客人。
status按状态筛选:tentativeconfirmedchecked_inchecked_outcancelledno_show
limit每页条数,默认 25,最大 100
offset跳过多少条记录。
curl "$VRDN_BASE/reservations?guest_id=3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34&limit=10" -H "Authorization: Bearer $VRDN_KEY"
{
  "has_more": false,
  "data": [
    {
      "id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27",
      "status": "confirmed",
      "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34",
      "check_in_date": "2026-08-01",
      "check_out_date": "2026-08-04",
      "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
      "room_type_name": "Deluxe Ocean Villa",
      "nightly_rate": "420.00",
      "currency": "USD",
      "folio_balance": "0.00",
      "balances": []
    }
  ]
}

分页取数参见接口约定


GET /reservations/{id}

权限范围: reservations:read

返回单条预订,带上它的住宿单元(这次住宿按房间拆开的各段)和账单余额。

curl "$VRDN_BASE/reservations/7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27" -H "Authorization: Bearer $VRDN_KEY"
{
  "id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27",
  "status": "confirmed",
  "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34",
  "check_in_date": "2026-08-01",
  "check_out_date": "2026-08-04",
  "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
  "room_type_name": "Deluxe Ocean Villa",
  "nightly_rate": "420.00",
  "currency": "USD",
  "adults": 2,
  "children": 0,
  "number_of_guests": 2,
  "booking_source": "direct_web",
  "special_notes": null,
  "folio_id": "1a6c3e9f-4d2b-4e8a-b5c7-9f0e6d4a2c81",
  "folio_balance": "0.00",
  "balances": [{ "currency": "USD", "charges": "1310.40", "payments": "1310.40", "balance": "0.00" }],
  "accommodations": [
    {
      "id": "2b9e6f4d-8a3c-4e1b-9d5f-7a0c4e8b2d63",
      "room_id": null,
      "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
      "check_in_date": "2026-08-01",
      "check_out_date": "2026-08-04",
      "status": "confirmed",
      "nightly_rate": "420.00"
    }
  ]
}

POST /reservations/{id}/cancel

权限范围: reservations:write

取消一条 tentativeconfirmed 的预订,并释放它占用的房量。已入住、已退房或已取消的预订无法通过 API 取消(409 not_cancellable)。账单与任何发票都会作废(保留以备审计),如果这条预订已付款,会在释放房量之前按政策发起退款。

请求体字段必填说明
reason作为取消原因保存下来。
curl -X POST "$VRDN_BASE/reservations/7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27/cancel" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Guest changed plans" }'
{ "reservation_id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27", "status": "cancelled", "refund_minor": 0, "refund_provider": null }
字段类型说明
refund_minorinteger退款金额,以最小货币单位(分)计。预订未付款或政策不退款时为 0
refund_providerstring | null处理这笔退款的服务方;没有退款时为 null