房价管理
商品目录与优惠接口都是只读的。这里的接口让集成可以管理整个房价体系:创建房价方案、叠加季节定价、打包包含项与额度,以及带促销码做促销。酒店就是靠它们从自己的官网或后台驱动 Veridien 里的定价。
这里的每个接口都需要 rates:write 权限范围,只有管理类的读取(GET)需要 rates:read。
促销就是一个房价方案
促销是一个 kind: "promotion" 且从某个基础方案推导而来的房价方案。这里没有单独的促销
接口:你通过同一组 /rate-plans 接口来创建和编辑它,只需设置 kind、derived_from_id、
derivation_type 与 derivation_value。
幂等
这里的每一次写入都是变更类请求。请发送 Idempotency-Key 头让重试变得安全,
做法见接口约定。
POST /rate-plans| 字段 | 必填 | 说明 |
|---|---|---|
room_type_id | 是 | 这个方案为哪个房型定价。 |
name | 是 | 内部名称(1 到 100 个字符)。 |
base_price | 是 | 每晚价格,十进制字符串,例如 "120.00"。 |
currency | 否 | 必须是酒店的本位币或已配置的币种。默认取本位币。 |
public_name | 否 | 给客人看的名称。 |
description | 否 | 给客人看的简介。 |
image_url | 否 | 绝对 URL。 |
extra_guest_charge | 否 | 超出基础入住人数后,每位客人每晚的加收金额。默认为 "0.00"。 |
single_guest_discount | 否 | 默认为 "0.00"。 |
single_guest_discount_type | 否 | fixed 或 percent。默认为 fixed。 |
min_los / max_los | 否 | 住宿天数的上下限(按晚计)。 |
booking_window_start / _end | 否 | 该方案可被预订的时间范围(YYYY-MM-DD)。 |
stay_window_start / _end | 否 | 该方案可被入住的时间范围。 |
active_for_booking_engine | 否 | 默认为 false。 |
active_for_channels | 否 | 默认为 false。 |
kind | 否 | standard(默认)或 promotion。 |
derived_from_id | 否 | 促销专用:它所派生自的基础方案。 |
derivation_type | 否 | percent、fixed 或 perPerson。与 derived_from_id 一同必填。 |
derivation_value | 否 | 带符号的十进制字符串。负数表示折扣,例如 "-20.00"。与 derived_from_id 一同必填。 |
curl -X POST "$VRDN_BASE/rate-plans" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{
"room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
"name": "Bed & Breakfast",
"base_price": "120.00",
"public_name": "Bed & Breakfast",
"description": "A full breakfast for two each morning.",
"active_for_booking_engine": true
}'{ "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02" }设置 kind、父方案,以及一个负的推导值。要把它锁在促销码之后,就添加一个促销码(见下文)并设置 requires_promo_code: true。
curl -X POST "$VRDN_BASE/rate-plans" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{
"room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
"name": "Advance Purchase, save 20%",
"base_price": "120.00",
"kind": "promotion",
"derived_from_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02",
"derivation_type": "percent",
"derivation_value": "-20.00",
"active_for_booking_engine": true
}'派生方案必须同时给出 derivation_type 与 derivation_value,否则请求会被拒绝。它的价格永远是父方案当前价格套上推导规则的结果,因此会自动跟随父方案的季节定价。
PATCH /rate-plans/{id}只发送你要改的字段。接受与创建相同的字段(room_type_id 除外),另加 is_active。
{ "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02", "updated": true }DELETE /rate-plans/{id}默认房价方案不能删除(403)。已经按某个被删除方案订出的预订,仍保留当初报给客人的价格。
{ "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02", "deleted": true }区间会在方案的基础价之上,叠加与日期相关的定价和住宿规则。同一个方案下的区间不得重叠;范围重叠会返回 409。
GET /rate-plans/{id}/intervals需要 rates:read。
POST /rate-plans/{id}/intervals| 字段 | 必填 | 说明 |
|---|---|---|
name | 是 | 例如「旺季」。 |
start_date / end_date | 是 | YYYY-MM-DD。开始必须早于结束。 |
price_mon … price_sun | 否 | 按星期几的价格。留空的那天回落到基础价。 |
min_stay / max_stay | 否 | 这段范围内的住宿天数规则。 |
closed_to_arrival / closed_to_departure / stop_sell | 否 | 房量控制标记。默认 false。 |
extra_guest_charge / single_guest_discount | 否 | 按季节覆盖的值。默认 "0.00"。 |
curl -X POST "$VRDN_BASE/rate-plans/5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02/intervals" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "High Season",
"start_date": "2026-12-01",
"end_date": "2027-03-31",
"price_mon": "180.00", "price_fri": "210.00",
"min_stay": 3
}'{ "interval_id": "d8a4c2f6-5e9b-4d7a-8f1c-3b6e0a9d5c28" }PATCH /intervals/{id}
DELETE /intervals/{id}PATCH 接受任意区间字段,并会重新校验不重叠规则。
包含项要么是权益(一个固定包含的项目),要么是额度(可在某个类别里消费的定额,例如水疗额度)。包含项是整体设置的:一次 POST 会替换该方案的全部包含项。
GET /rate-plans/{id}/inclusions需要 rates:read。
POST /rate-plans/{id}/inclusions| 字段 | 必填 | 说明 |
|---|---|---|
label | 是 | 给客人看的名称,例如「水疗额度」。 |
allocated_amount | 是 | 金额,十进制字符串。免费权益填 "0.00"。 |
frequency | 是 | perStay、perNight、perGuest 或 perGuestPerNight。 |
inclusion_kind | 否 | perk(默认)或 credit。 |
revenue_category | 是 | room、fnb、spa、excursions、activities 或 other。对额度而言,这是它适用的类别。 |
service_item_id | 否 | 关联到商品目录中的一个服务项。 |
currency | 否 | 默认取该方案的币种。 |
included_quantity | 否 | 默认为 1。 |
curl -X POST "$VRDN_BASE/rate-plans/5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02/inclusions" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{
"inclusions": [
{ "label": "Daily breakfast for two", "allocated_amount": "20.00", "frequency": "perGuestPerNight", "revenue_category": "fnb" },
{ "label": "Spa credit", "allocated_amount": "150.00", "frequency": "perStay", "inclusion_kind": "credit", "revenue_category": "spa" }
]
}'{ "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02", "count": 2 }促销码解锁一个促销。折扣在促销里,所以促销码本身从不携带优惠。把促销码挂到它所解锁的方案上。
GET /rate-plans/{id}/promo-codes需要 rates:read。
POST /rate-plans/{id}/promo-codes| 字段 | 必填 | 说明 |
|---|---|---|
code | 是 | 3 到 40 个字符。以大写形式存储和匹配。 |
valid_from / valid_to | 否 | YYYY-MM-DD 有效期。 |
max_redemptions | 否 | 总使用次数上限。不填表示不限。 |
max_per_guest | 否 | 每位客人的使用次数上限。 |
curl -X POST "$VRDN_BASE/rate-plans/e2a9d7c4-3f6b-4c1e-9a8d-7b5f0c2e4a19/promo-codes" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{ "code": "EARLYBIRD25", "max_redemptions": 100 }'{ "promo_code_id": "a5e2c8f1-7d4b-4a6e-b9c3-0f8d2a5e7c41", "code": "EARLYBIRD25" }PATCH /promo-codes/{id}
DELETE /promo-codes/{id}PATCH 接受 valid_from、valid_to、max_redemptions、max_per_guest 与 is_active。促销码字符串本身不能修改,因为预订会冻结下单时所用的码;需要改就删掉它再建一个新的。删除一个促销码,不影响已经用它订出的预订。