客人与会员积分
客人就是预订所归属的人。每位客人都属于某一家酒店,并可以带一个会员积分账户,在已确认的住宿上赚取积分,并可用于抵扣。
POST /guests权限范围: guests:write
按 (property, email) 找出客人,找不到就创建一个。它对邮箱是幂等的:用同一个邮箱再调一次,会关联到已有客人而不是创建重复档案,因此在每次结账时调用都很安全。
| 请求体字段 | 必填 | 说明 |
|---|---|---|
email | 是 | 用作匹配键。 |
first_name | 是 | |
last_name | 是 | |
phone | 否 | |
nationality | 否 | 自由文本或 ISO 国家代码。 |
curl -X POST "$VRDN_BASE/guests" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "first_name": "Ada", "last_name": "Lovelace", "nationality": "GB" }'{ "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34", "created": true }新建客人时返回 201 且 "created": true;关联到已有客人时返回 200 且 "created": false。
GET /guests/{id}权限范围: guests:read(个人身份信息字段还需要 guests:read:pii)
curl "$VRDN_BASE/guests/3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34" -H "Authorization: Bearer $VRDN_KEY"只持有 guests:read 时:
{
"id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34",
"first_name": "Ada",
"last_name": "Lovelace",
"nationality": "GB",
"status": "active",
"is_local_verified": false
}持有 guests:read:pii 时,响应会额外包含 email、phone、address、date_of_birth、id_type 与 id_number。
| 字段 | 类型 | 说明 |
|---|---|---|
status | string | active、vip 或 blocked。 |
is_local_verified | boolean | 该客人是否已核验为本地居民(用于解锁仅限本地居民的房价)。 |
PATCH /guests/{id}权限范围: guests:write
更新任意可变字段。只发送有变化的部分。管理流程就是通过设置 local_verified 把客人标记为已核验的本地居民(同时会记下核验时间)。
| 请求体字段 | 说明 |
|---|---|
first_name、last_name、phone、nationality、address | 档案字段。 |
status | active、vip 或 blocked。 |
local_verified | 布尔值。true 会为这位客人解锁仅限本地居民的房价。 |
curl -X PATCH "$VRDN_BASE/guests/3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{ "local_verified": true }'返回更新后的客人,结构与 GET /guests/{id} 相同。
GET /guests/{id}/loyalty权限范围: loyalty:read
返回一位客人的积分余额、累计积分、当前等级、距下一等级的进度,以及最近的流水。还没有任何积分活动的客人会返回一个清零的账户,而不是 404。
curl "$VRDN_BASE/guests/3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34/loyalty" -H "Authorization: Bearer $VRDN_KEY"{
"points_balance": 1260,
"lifetime_points": 1260,
"tier": "Coral",
"next_tier": { "name": "Lagoon", "min_points": 5000 },
"points_to_next_tier": 3740,
"recent_transactions": [
{ "type": "earn", "points": 1260, "description": "Stay B7XKQ4M2NZ", "created_at": "2026-06-19T08:46:00.000Z" }
]
}| 字段 | 类型 | 说明 |
|---|---|---|
points_balance | integer | 可使用的积分。 |
lifetime_points | integer | 累计赚取的积分(决定等级,永不扣减)。 |
tier | string | 当前等级名称。 |
next_tier | object | null | 下一个等级及其门槛;已在最高等级时为 null。 |
recent_transactions | array | 最近最多 10 条流水(earn、redeem、expire、adjust)。 |
POST /loyalty/redemptions权限范围: loyalty:write
扣减客人的积分,并记录一条 redeem 流水。余额校验是原子的,因此兑换绝不会透支;超额兑换会返回 409 insufficient_points。
| 请求体字段 | 必填 | 说明 |
|---|---|---|
guest_id | 是 | 必须属于这家酒店。 |
points | 是 | 正整数。 |
reservation_id | 否 | 把这次兑换关联到一次住宿;必须属于这家酒店和这位客人。 |
curl -X POST "$VRDN_BASE/loyalty/redemptions" \
-H "Authorization: Bearer $VRDN_KEY" \
-H "Content-Type: application/json" \
-d '{ "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34", "points": 1000, "reservation_id": "7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27" }'{
"redeemed_points": 1000,
"redeemed_value_usd": 10,
"new_balance": 260,
"tier": "Coral"
}在你自己的结账流程里,把 redeemed_value_usd 当作要抵扣的金额。以美元结算的已确认住宿会自动赚取积分(参见预订)。