mcpField
B
book-hotel

book-hotel

github.com/justintravala其他0260 次安装23 周前更新
代码仓库

关于 book-hotel

通过 x402 支付流程使用 USDC 完成已选酒店预订的技能。它要求明确确认,并提供支付上限和状态恢复步骤,以避免重复扣款。

主要功能

  1. 01通过 x402 支付并预订
  2. 02要求提供住客和搜索会话信息
  3. 03设置最高支付金额
  4. 04支付错误后查询预订状态
  5. 05返回支付及预订确认信息

适用场景

  1. 01确认已选酒店套餐
  2. 02使用 USDC 支付预订
  3. 03超时后恢复查询预订状态
  4. 04重试付款前确认预订结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/justintravala/travel-skills --skill book-hotel

安装后在 Claude Code 中输入/book-hotel确认已加载。

详细介绍

预订酒店

预订酒店并使用 USDC 付款。付款通过 x402 协议自动处理:旅行 API 返回 HTTP 402 Payment Required,Agent 的钱包使用 USDC 付款,然后预订确认。

**这是一笔真实的链上金融交易。**请谨慎操作。

适用场景

用户已选定具体套餐,并明确要求预订:

  • “帮我预订柏悦酒店”
  • “预订选项 2”
  • “确认并支付这家酒店”
  • “就订这家吧”

请勿推测性地使用此技能。仅在用户明确批准付款时使用。

前提条件

调用前需要满足以下全部条件:

  1. 从 search-hotel 或 search-room 获取有效的 packageId
  2. 获取同一搜索会话中的 sessionId
  3. 客人信息:名字、姓氏、电子邮件(必须由用户提供,切勿编造)
  4. 已通过身份验证的 Coinbase 钱包——如果尚未验证,请先运行 coinbase/agentic-wallet-skills 包中的 authenticate-wallet 技能
  5. 钱包中有足够的 USDC——如果余额不足,请先运行 fund 技能
  6. 用户明确确认套餐、总价和日期

如果缺少任何一项,请询问用户或调用相关技能,不要跳过步骤。

钱包设置检查

预订前,请确认钱包状态。快速检查:

npx awal@latest balance

如果用户尚未通过身份验证,此操作会返回身份验证错误 → 触发 authenticate-wallet 技能。 如果 USDC 余额低于预订总价,请触发 fund 技能。

预订前确认

付款前务必先总结信息并确认。例如:

即将预订并付款:

  • 东京柏悦酒店,柏悦豪华特大床房,含早餐
  • 5 月 1 日至 5 日(4 晚),2 位成人
  • 总计:1,800 USDC(从你的 Coinbase 钱包支付)
  • 4 月 29 日前可免费取消
  • 客人:Nguyen Van A,[email protected]

确认吗?(是/否)

只有在用户回答“是”(或表达同等意思)后,才运行付款命令。如果用户在同一轮对话中已明确授权预订,并提供了以上全部信息,则无需再次询问,可以直接继续。

调用方法

使用 awal x402 pay 调用预订端点。CLI 会自动处理 402 → 签名 → 重试。

预订端点将输入拆分为两部分:

  • 查询字符串(-q 标志):package_id、session_id——用户选择的套餐及其对应的搜索会话。
  • 请求正文(-d 标志):contact 对象,以及硬编码的 reward_wallet 和 agent_id(见下文)。
npx awal@latest x402 pay https://qpgdy2kn7v.ap-southeast-1.awsapprunner.com/m2m-payment/book \
  -X POST \
  -q '{"package_id":"<packageId>","session_id":"<sessionId>"}' \
  -d '{
    "contact": {
      "given_name": "<first>",
      "sur_name": "<last>",
      "email": "<email>",
      "phone": "<phone>"
    },
    "reward_wallet": "0x8D91B9c9920BD2E056989C2E80F14a20557B4773",
    "agent_id": "1996"
  }'

请注意 snake_case 字段名(package_id、session_id、given_name、sur_name、reward_wallet、agent_id)——预订端点要求使用这一确切格式。contact 对象为必填项,其中包含 phone。请勿将 package_id / session_id 放入正文中——它们必须作为查询参数传递。

reward_wallet 和 agent_id(硬编码值——请勿更改)

这两个字段用于标识技能作者,以便预订系统归属奖励。每次预订调用都必须发送以下确切值:

  • reward_wallet:0x8D91B9c9920BD2E056989C2E80F14a20557B4773
  • agent_id:"1996"

这两个字段都是请求正文顶层的必填项(与 contact 同级)。请勿向用户询问,也请勿替换为用户的钱包地址。

有关更改这些值以分叉该技能的完整理由和说明,请参阅 README 中的配置部分。

安全:限制最高付款金额

为避免意外超额扣款(例如 API 返回错误金额),请使用微量 USDC 传入 --max-amount(1 USDC = 1,000,000 微单位):

  --max-amount 1850000000   # caps payment at 1,850 USDC for an 1,800 USDC booking

请始终将 --max-amount 设为预期总额加上一个小幅缓冲(5% 左右)。

完整示例
npx awal@latest x402 pay https://qpgdy2kn7v.ap-southeast-1.awsapprunner.com/m2m-payment/book \
  -X POST \
  -q '{"package_id":"e47otEJtYeZYblF9","session_id":"6kVmPYwZhQJewNTp"}' \
  -d '{"contact":{"given_name":"Justin","sur_name":"Ta","email":"[email protected]","phone":"+84336657091"},"reward_wallet":"0x8D91B9c9920BD2E056989C2E80F14a20557B4773","agent_id":"1996"}' \
  --max-amount 1850000000

输出

成功后,CLI 会同时打印付款收据和预订确认信息。预订响应位于正文中:

{
  "bookingId": "BK_2026_05_001",
  "status": "CONFIRMED",
  "hotelName": "Park Hyatt Tokyo",
  "checkIn": "2026-05-01",
  "checkOut": "2026-05-05",
  "totalPriceUSD": 1800,
  "cancellationDeadline": "2026-04-29T23:59:00Z",
  "paymentTxHash": "0xabc...",
  "confirmationEmail": "[email protected]"
}

交易哈希(paymentTxHash)显示在 X-PAYMENT-RESPONSE 标头中,awal 会在输出中显示该哈希。

确认预订

✅ 已预订!确认编号 BK_2026_05_001。 Park Hyatt Tokyo · 5 月 1–5 日 · 已支付 1,800 USDC 交易:0xabc...def(在 basescan 上查看) 可在 2026 年 4 月 29 日之前免费取消。 确认邮件已发送至 [email protected]。

请保存预订 ID——管理或取消预订时需要用到。

错误处理

  • 402 with amount > --max-amount — 预订总额超出安全上限。停止操作,告知用户实际金额,并询问是否要提高上限后继续。
  • Insufficient USDC balance — 触发 fund 技能充值,然后重试。
  • Wallet not authenticated — 触发 authenticate-wallet 技能,然后重试。
  • Payment was authorized but rejected by server / X402 submission failed / 任何授权后的超时 — 切勿盲目重试 pay 命令。链上结算和预订可能已经成功——只是 Agent 未收到响应。请运行下方的恢复流程。
  • Package no longer available(付款前)— 重新运行 search-hotel 或 search-room 以刷新;sessionId 也可能已过期。
  • Session expired — 重新运行搜索以获取新的 sessionId。
  • 付款期间发生网络错误 — 与上述授权后超时的情况相同:先运行恢复流程,再进行其他操作。

恢复:付款已授权,但 Agent 报告失败

最常见的虚假失败情况:awal x402 pay 签署付款授权后,服务器在链上完成结算并完成预订,但响应未能及时到达 Agent → CLI 抛出 Payment was authorized but rejected by server。钱已扣除,预订已成功,但 Agent 认为失败。盲目重试会导致重复扣款。

遇到上面列出的任何错误时,在告知用户失败之前,请执行以下操作:

第 1 步 — 等待约 5 秒,然后运行 travel-cli book-status

重要提示: 首次调用 book-status 前请等待约 5 秒。服务器可能仍在结算付款并写入预订记录——立即调用很可能会返回 404 not_found,尽管预订最终会成功。这会让你误以为确实失败,从而诱使你重试并造成重复扣款。

使用刚才预订时使用的相同 package_id 和 session_id。无需 x402、付款或身份验证:

sleep 5 && npx @tvl-justin/travel-cli@latest book-status \
  --package-id "<packageId>" \
  --session-id "<sessionId>"

CLI 始终会输出形如 { httpStatus, body, interpretation } 的 JSON。

第 2 步 — 解读响应

根据 httpStatus 分支处理:

httpStatusbody含义操作
200{ "status": "completed", "transaction": "0x…", "bookingId": "BK_…", … }预订已成功。Agent 虽然超时,但款项已扣除,房间也已预留。按成功处理。使用此响应正文向用户提供确认信息(结构与正常成功响应相同)。不要重试付款。
202{ "status": "in_progress", "retry_after_ms": <N> }服务器仍在结算或处理预订。等待 body.retry_after_ms(每次轮询最多约 10 秒),然后重新运行 book-status。最多轮询约 6 次。如果仍为 in_progress,告知用户确认邮件稍后会发送,并请其查看 awal wallet history。
404{ "status": "not_found" }服务器端未发生任何操作——确实失败了。可以安全地重试原来的 awal x402 pay(或向用户说明原始错误)。
5xxerror恢复端点本身不可用。告知用户:“我无法确认预订是否成功。请检查您的邮件——Travala 成功预订后总会发送确认邮件——并查看 awal wallet history 中的转账记录。请暂时不要重试。”

JSON 输出中的 interpretation 字段是对上述映射的易读说明,可用于向用户展示,但控制流始终应根据 httpStatus 分支处理。

步骤 3 — 返回 200(已恢复)

像正常成功一样展示结果,但要说明恢复情况,让用户了解发生了什么:

✅ 已预订!确认编号 BK_2026_05_001。 (CLI 最初报告失败,但预订实际上已成功——已从服务器恢复。不会重复扣款。) 东京柏悦酒店 · 5 月 1 日至 5 日 · 已支付 1,800 USDC 交易:0xabc...def(在 basescan 上查看) 确认邮件已发送至 [email protected]。

不要这样做
  • ❌ 发生授权后错误时,未先运行 travel-cli book-status 就重新运行 awal x402 pay。
  • ❌ 未运行 travel-cli book-status 就告诉用户“预订失败”。预订成功的可能性远高于失败。
  • ❌ 手动编写退款请求——服务器不支持为已完成的预订退款(预订成功不代表需要退款)。

重要规则

  • 绝不编造住客信息。如果用户尚未提供,请询问。
  • 未在本轮或近期对话中获得明确批准时,绝不调用 awal x402 pay。
  • 始终设置 --max-amount,以防止费用失控。
  • 如果用户改变主意(“等等,给我看看选项 3”),不要付款——返回 search-room。
  • 绝不泄露私钥或钱包助记词。Agent 只通过 awal 签名;密钥保留在 Coinbase 的安全基础设施中。

评论

支持 Markdown