后端已全部上线并实测通过。C端(miniprogram-v2)页面属小齐域,波波不碰,本文是可直接照做的接线说明。
所有金额单位统一为元(后端存分,接口已转换,前端不要再做 /100)。
base:https://api.kailashi.cn/api/miniapp,走现有 services/api/request.ts 的 apiGet(path, query) / apiPost(path, data),需登录态。
| # | 方法 | 路径 | 用途 |
|---|---|---|---|
| 1 | GET | /hotel/room-types?merchantId= | 某商户在售房型(含三档价) |
| 2 | GET | /hotel/availability | 查某房型区间逐晚余量 + 报价(自动匹配渠道价) |
| 3 | POST | /hotel/bookings | 下单(建订单 + 占房量) |
| 4 | POST | /hotel/bookings/{id}/cancel | 取消(自动回补房量) |
| 5 | GET | /hotel/orders/{order_id}/charges | 按订单查待付收款单(账单入口) |
| 6 | GET | /hotel/charges/{id} | 收款单详情 |
| 7 | POST | /hotel/charges/{id}/prepay | 调起微信支付(JSAPI) |
GET /hotel/room-types?merchantId=1
{ "ok": true, "data": { "room_types": [
{ "id": 9, "name": "神山景观大床房", "bed_type": "大床", "max_guests": 2,
"total_rooms": 20, "base_price": 880, "weekend_price": 1080, "holiday_price": 1280 }
] } }
列表页展示 base_price 即可(起价),精确价格以下一步为准。
GET /hotel/availability?roomTypeId=9&checkIn=2026-10-01&checkOut=2026-10-03&roomsCount=2
{ "ok": true, "data": {
"nights": [
{ "date": "2026-10-01", "price": 1280, "total": 20, "left": 18, "available": true },
{ "date": "2026-10-02", "price": 1280, "total": 20, "left": 18, "available": true }
],
"total_price": 5120, // 折后总价(2 间 × 2 晚)
"list_price": 5120, // 折前总价
"rate_plan": null // 命中的房价计划,null=无折扣
} }
展示建议:
list_price > total_price 时,划掉原价显示折后价,并标 rate_plan.name(如"会员价 8 折")available:false → 整个区间不可订,按钮置灰left 是该晚剩余间数,roomsCount 不能超过各晚最小 leftPOST /hotel/bookings
{
"roomTypeId": 9, "checkIn": "2026-10-01", "checkOut": "2026-10-03",
"roomsCount": 2, "guests": 2,
"guestName": "张三", "guestPhone": "13800000000",
"contactName": "张三", "contactPhone": "13800000000",
"paymentType": "offline" // offline=到店付 / online=线上付
}
返回 data.bookingId(字符串,用前转 int)、data.orderId 等。
paymentType:"online" → 订单初始 pending_payment,需走现有支付流程(/pay/orders/{id}/prepay)paymentType:"offline" → 订单 booked,等商户接单POST /hotel/bookings/{id}/cancel —— 自动回补房量,只能取消自己的单。
不需要前端传任何渠道参数,后端会按渠道自动打折:
| 场景 | 命中渠道 | 说明 |
|---|---|---|
| 小程序直订(默认) | member | 会员 / 直订价,C端不传参就走这个 |
| OTA 渠道单 | ota | 需要前端在 availability 与下单时传 channel=ota |
| 前台代客下单 | walkin | B端开单场景 |
匹配规则(后端已实现):
ratePlanId → 用它(最高优先级)channel → 按该渠道匹配member 自动匹配前端要做的:一般情况下什么都不用做;只有 OTA 来源的单需要带 channel=ota。
客人在店消费后,商户可能发起一笔「待付收款单」,客人在小程序付。
GET /hotel/orders/{order_id}/charges
{ "ok": true, "data": { "charges": [
{ "id": 5, "out_trade_no": "FC00000380558", "amount": 600.8, "status": "pending" }
] } }
在订单详情里:order_type==='room' 且有 status==='pending' 的收款单 → 显示「去支付」按钮。
POST /hotel/charges/{id}/prepay → 返回 jsapi_params,直接喂给 wx.requestPayment:
const { jsapi_params } = res.data
wx.requestPayment({ ...jsapi_params,
success: () => { /* 轮询确认 */ },
fail: (e) => { /* 提示 */ } })
GET /hotel/charges/{id} 确认 status==='paid' 再提示成功| 场景 | 返回 | 建议提示 |
|---|---|---|
| 满房/维护日 | 409 该房型维护中,暂不可订 | 「所选日期不可订,请调整日期」 |
| 余量不足 | 409 余量不足(仅剩 N 间) | 「仅剩 N 间」 |
| 日期非法 | 422 离店日须晚于入住日 | 「请选择正确的日期」 |
| 非本人收款单 | 403 | 「无权查看」 |
| 未绑 openid | 409 | 「当前账号暂不支持线上支付,请到前台结算」 |
| 微信未配置 | 503 | 「线上支付暂未开通」 |
/100(和历史套餐下单不同)。bookingId 返回是字符串,参与运算前 Number() 一下。nights 是逐晚数组,总价是所有晚 × 间数的累加;不要自己用 base_price × 天数 算(会漏掉周末价、节假日价、渠道折扣)。left 限制可选间数,否则用户会撞 409。list_price/total_price 划线展示)→ 下单channel=ota(如暂不涉及可不做)hotel-c-end-contract.md —— 早期预订契约(已被本文整合,保留作参考)hotel-c-end-integration.md —— 从旧套餐下单改造到独立酒店域的补丁说明hotel-c-end-charge-contract.md —— 收款单支付专项