关于 prava-shopping
Prava Shopping 是一个驱动 Prava CLI 的购物 Agent 技能,适用于希望 Agent 搜索并购买实物商品的用户。它按商品、卖家、报价和结账逐步推进,并在确认商品及最终价格后才继续支付。
主要功能
- 01跨商家搜索商品
- 02查看卖家报价与商品选项
- 03获取含运费和税费的最终报价
- 04分步等待用户确认
- 05创建支付会话并完成结账
适用场景
- 01按关键词和购物意图寻找商品
- 02确认卖家、规格及配送选项
- 03核对总价后发起购买
- 04通过 Prava CLI 查看订单结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ prava-payments/ prava-skills --skill prava-shopping安装后在 Claude Code 中输入/prava-shopping确认已加载。
附带文件references/cli-shop.md
详细介绍
Prava Shopping — 为 AI Agent 发现并购买商品
使用 Prava CLI 完成端到端购物:跨商家搜索商品 → 打开商品选择变体 → 获取准确价格报价 → 创建银行卡会话 → 结账。 用户只需批准一次银行卡;之后由 Agent 完成其余操作。
按意图选择路径(请先阅读)
| 用户想要…… | 操作 |
|---|---|
| 让 Prava 查找并购买商品(“帮我买 / 找一个 / 买一个 <product>”“结账我的购物车”) | 使用此技能:按下方流程操作 |
| 为已在特定商店选好的商品付款、支付账单,或支付当前正在结账的订单 | 转交给 prava-pay |
| 预先授权之后或重复购买,或“设置预算”(当前没有要购买的商品) | 转交给 prava-pay 的设置授权流程——不要在此重复设置授权 |
| 与购买无关的研究或浏览(餐厅、旅行、信息、“帮我找一个图书馆/API”) | 两个技能都不使用——不要介入 |
| 关于 Prava 本身的问题、设置或关联 | prava-pay |
何时启用
当用户想让 Prava 为他们查找并购买实体商品时启用——“帮我买 / 找一个 / 买一个 <product>”“订购这个”“结账我的购物车”。
意图不明确时确认使用哪种方式——不要擅自替用户决定,也不要反复追问:
- 如果 Prava 是用户已设置的购买方式,且请求明确表示要购买,就继续操作——但要先说明:“我会用 Prava(你关联的银行卡)为你查找并购买。” 后续的确认步骤(确认商品 → 确认总价 →
--yes)都可作为退出点。 - 出现以下信号时先询问:用户可能想通过其他方式浏览或购买,例如提到其他商店或工具、表示“我正在浏览 X”、粘贴商品链接,或请求仅仅是探索性的:“要我用 Prava 为你查找并购买吗?还是你准备在其他地方购买?”
以下情况不要运行商品发现流程/不要使用此技能:
- 请求与购买商品无关——例如一般性研究或浏览(餐厅、旅行、信息)。不要介入;此技能用于购买,不是搜索引擎。
- 用户正在自行查找商品,或已经在其他地方从特定商店选好了具体商品 → 用户只需要付款 → 应使用 prava-pay(在该商家付款;不搜索 Prava 商品目录)。
- 用户表示**“我自己找”/“只付款”/“不要搜索”** → 尊重用户意愿:跳过
shop search(见下文)或转交给 prava-pay。 - 点对点付款、带有现成链接的账单,或关于 Prava 本身的问题 → 使用 prava-pay。
可以跳过商品发现。 此技能不必从 search 开始。如果用户已明确商品(你有 product_id 和商家信息,或用户指定了商品目录中的具体商品),可以从 product/quote 开始——仍可获取 Prava 报价并安全结账,无需替用户进行商品发现。只有在用户确实想让 Prava 查找可选商品时,才使用 search。
此技能使用与 prava-pay 相同的 CLI,并将付款步骤交由该技能文档中说明的同一 prava sessions 流程处理。
前置条件
Agent 必须已关联到用户的 Prava 账户,并且已安装 prava CLI。
如果 prava status 不是 active,请先完成关联流程——参阅 prava-pay 技能
(前置条件及“验证 CLI 已安装且 Agent 已关联”)。不要在此重复说明。
无需设置环境变量前缀。 CLI 会根据命令推断技能(shop * → prava-shopping),并读取已安装技能的版本,因此直接运行 prava shop … 即可。(只有在非标准 Agent 主机上,才需要设置 PRAVA_SKILL_VERSION=<ver> 进行覆盖。)
流程(id 链:product_id → variant_id → checkout_session_id)
节奏——每轮只做一个决定。先呈现,然后停止并等待用户回复。 以下步骤是检查点,不是要端到端运行的脚本。**绝不要在同一轮中连续执行其中两条 命令。**具体来说:执行
search后 → 等待用户选择商品; 执行product后 → 等待用户确认卖家/变体;执行quote后 → 等待用户批准支出。每条prava shop命令都只能在用户回复上一步之后 执行。“帮我买 X”授权你启动流程,而不是让你默默地将流程直接执行到底。
1. 搜索
搜索时要提供两项内容:精简的关键词 --query,以及包含用户完整自然语言需求的 --intent(场合、收件人、风格、预算表述)。UCP 会利用意图对结果进行排序,使其更符合用户的实际需求——仅使用 --query 会丢失这些上下文。
prava shop search --query "dark roast coffee" \
--intent "a smooth, not-too-bitter dark roast as a gift for my dad" \
[--merchant bonescoffee.com] [--ships-to US] [--limit 10]
--query= 仅包含商品关键词(要匹配的内容)。--intent= 用用户自己的话表达需求(原因/对象/预算)。只要用户提供的不只是一个简单关键词,就传入此参数——例如:“给女朋友买一顶不超过 30 美元的帽子” →--query "hat" --intent "a hat as a gift for my girlfriend, under $30"。
每条结果都会显示标题、价格、商家和商品 ID。用通俗语言向用户展示列表(标题 + 价格 + 商家)——绝不要粘贴原始 JSON 或图片 URL。如果用户想查看更多选项,请使用游标翻页(参见分页)。如果选择不明确,请询问用户想要哪一款(或哪家商家)。
2. 商品 → 选择卖家(报价)
prava shop product --product-id "<product_id>" --merchant <merchant>
同一商品通常由多家商家销售。CLI 会将每家商家列为一项报价——
标签 — $价格 [选项] · 商家 + 变体 ID — 可订购的报价优先,然后按价格从低到高排列。
价格仅包含商品本身;运费会在报价时加上。因此:
- 执行
product后,停止并等待——不要在同一轮中运行quote。简要转述——商品的标题 + 一句话描述以及报价(卖家 · 价格 · 变体)——并询问用户确认想要哪一项。即使只有一项报价也一样:展示给用户(“只有一个选项:,,$ + 运费——要我帮你计算价格吗?”),然后等待用户回复再报价。绝不要刚介绍完商品就接着继续操作。 (如果需要描述来转述,可运行product --json。) - 让用户明确选择——可以按价格选择(默认选择最便宜的可订购报价),也可以在报价确实有所不同时按选项(尺码/研磨程度/颜色)选择。不要悄悄替用户换成其他商家。
- 标记为
(out of stock)的报价可能只是仅显示价格的商品信息,实际无法订购——不要仅仅因为它们看起来更便宜就选择它们。列表已将它们排到末尾。 - 使用所选报价自身对应的商家(显示在该行)来执行
quote——不一定是你搜索时使用的商家。
2.5 配送地址(报价前必需)
quote 会将商品寄送到用户保存的地址;钱包会在服务端注入该地址,因此你(Agent)永远不会接触原始地址或电话号码。查看已保存的信息:
prava shop address list # MASKED: label · "•••• St, City RG •••NN, US" · address-id · [default]
- 已有默认地址(或用户指定了地址)→ 继续报价(非默认地址可选用
--address-id <id>)。 - 没有保存地址 → 用户必须先添加。优先使用 Prava 仪表板(最安全——个人身份信息不会经过你):向用户提供仪表板 URL,请他们添加地址和电话号码,然后重新运行
address list。备用方案:让用户口述地址,并通过prava shop address add保存。当你询问时,收集以下所有信息:- 名和姓(收件人)
- 街道——第 1 行(如有第 2 行,也要收集)
- 城市、州/地区、邮政编码
- 国家/地区(ISO-2,例如 US、IN、GB)
- 电话号码——含国家/地区拨号代码(例如
+91 98765 43210、+1 415 555 0100)。务必要求提供开头带+<code>的号码;如果用户只提供了普通号码,询问其国家/地区代码(+91、+1,……)。 然后:prava shop address add --first-name … --last-name … --line1 … [--line2 …] --city … --region … --postal … --country US --phone "+1 415 555 0100" --default。
- 个人身份信息规则——绝不要复述、重复或记录完整地址或电话号码。你只会收到经过脱敏的摘要;请通过标签/address-id指代地址。
- 缺少地址时,
quote/checkout会返回SHOP_ADDRESS_REQUIRED/SHOP_CONTACT_REQUIRED——转达该消息,并引导用户前往仪表板。
3. 报价 → 确切价格
仅在用户确认商品(步骤 2)且已保存地址(步骤 2.5)后运行此命令。
CLI 会强制执行商品确认步骤:没有 --yes 时,quote 会拒绝执行——仅在用户选定卖家/款式后才传入 --yes。
prava shop quote --variant-id "<variant_id>" --merchant <merchant> [--quantity 1] --yes
它会返回最终价格(含运费/税费)、checkout-session-id 和过期时间(报价有效期约 5 分钟)。向用户显示总价,然后停在确认关口(步骤 4)。
执行环境可能较慢——如果超时/服务器错误,报价会自动重试一次(通过 --retries <n> 调整,例如 --retries 2)。如果仍然超时,只需再次运行 quote;重试是安全的(它只会创建会话)。checkout 不会自动重试——超时的扣款可能已经成功,因此只有在确认结果后才重新运行;重放会返回已存储的结果。
4. 向用户确认——然后创建银行卡会话
必须严格停止——绝不可跳过,即使商品只有一个选项,或者用户已经说“帮我买 X”也不例外。“帮我买 X”表达的是购买意图,并不代表用户已批准价格:直到报价后,卖家、款式、运费和总价才会确定。执行任何消费操作前,必须向用户展示以下信息并获得明确的**“同意”**:
- 商品——标题和一句话描述,
- 卖家(商家)及你准备购买的款式,
- 数量,
- 配送地址——仅显示标签/脱敏摘要(绝不可显示完整地址),以及
- 含运费的最终总价(来自报价)。
只有在用户明确确认后,才创建银行卡会话或结账。如果用户尚未回复,请等待——不要继续。
创建会话前:此报价中的商家和总价正是检查适用授权所需的信息——在此处也运行 prava-pay 的购买流程步骤 0(prava mandate list --json)。如果匹配到授权 → 按该流程向用户提供授权选项/自主扣款,而不要创建新的会话;如果没有匹配项 → 继续以下步骤。
然后为该确切总额创建银行卡会话(与 prava-pay 流程相同——金额必须等于报价总额):
prava sessions create \
--total-amount "<quote total, e.g. 27.98>" --currency <CUR> \
--merchant-name "<merchant>" --merchant-url "https://<merchant>" --merchant-country US \
--product '{"description":"<product title>","unit_price":"<quote total>","quantity":1}'
这会打印一个付款 URL——将其显示给用户,并等待用户批准并输入银行卡信息。然后轮询已令牌化的凭证:
prava sessions poll --session-id <session_id>
→ 返回 Token、Cryptogram、Expiry(一次性使用;约 30 分钟后过期)。
5. 结账
checkout 在未指定 --yes 时会拒绝执行——只有用户在第 4 步批准总金额后,才能传入此参数。
prava shop checkout --checkout-session-id "<checkout_session_id>" \
--token <token> --cryptogram <cryptogram> --expiry-month <MM> --expiry-year <YYYY> --yes
成功后会显示:✓ Paid 以及订单 ID。CLI 会输出清晰的结果——将其转告用户。
分页(“显示更多”)
搜索会返回一个精选页面(默认 10 条)。当 CLI 输出 “More results — next page”
这一行时,会附上包含 --cursor <value> 的准确命令。要查看更多结果,请使用该
--cursor 重新运行搜索。如果没有“更多”这一行,就表示已到末尾。游标是不透明的——请
原样传入;切勿自行编造或解码。(如果需要获取原始 next_cursor,请使用 --json。)
展示规则(保持简洁)
- 向用户展示有助于其做出决定的信息:标题、一句话描述、价格、商家、变体、 最终总价和订单结果。(描述与决策相关——用户选定商品时,请转述描述。)切勿倾倒原始 JSON、图片 URL、内部厘金额或价格明细对象。
- CLI 精选输出已包含这些信息。只有需要获取 ID/游标以串联下一条命令时才使用
--json——不要向用户展示该 JSON。
何时询问用户
search之后 → 停下;让用户选择商品(不要自动打开商品)。product之后 → 停下;转述摘要(标题 + 一句话描述 + 商品信息: 卖家 · 价格 · 变体),并让用户在执行quote之前确认卖家/变体—— 即使只有一个商品也一样。切勿在同一轮中串联product→quote。- 搜索结果含糊不清(有多个可能的商品/商家)→ 询问用户要选哪个。
- 存在多个变体(尺码/研磨度/颜色)→ 询问用户要选哪个。
- 任何消费之前(创建 mint 卡会话/结账) → 必须确认商品、卖家、变体、 数量和最终总价(含运费),并取得明确的“是”。这是第 4 步的硬性停止点。
- 用户要求“查看更多/其他选项” → 使用游标翻页。
操作示例——“帮我买一袋咖啡”
prava shop search --query "coffee"→ 展示前几条结果(标题 · 价格 · 商家)。停下—— 用户选择 #1。prava shop product --product-id <id> --merchant bonescoffee.com→ 转述给用户:“Costa Rica Single-Origin 12oz——中度烘焙,带有巧克力/坚果风味——整豆 $19.99,来自 bonescoffee.com。 只有这个选项——要我帮你查最终价格吗?”停下——等待用户回答“是”。prava shop quote --variant-id <vid> --merchant bonescoffee.com→ $27.98(含 $7.99 运费)。 确认环节:“含运费共 $27.98,来自 bonescoffee.com——要我帮你购买吗?”停下——等待明确的“是”。用户回答“是”后 →prava sessions create --total-amount "27.98" --currency USD --merchant-name "bonescoffee.com" --merchant-url "https://bonescoffee.com" --merchant-country US --product '{"description":"Costa Rica Single-Origin Coffee | 12oz","unit_price":"27.98","quantity":1}'→ 显示 URL,用户批准后 →prava sessions poll --session-id <id>→ token+cryptogram。prava shop checkout --checkout-session-id <cs> --token <t> --cryptogram <c> --expiry-month 12 --expiry-year 2028→✓ Paid,转告订单 ID。
错误(转述安全提示并据此处理)
- 报价已过期(
SHOP_SESSION_EXPIRED/ “expired”)——价格已失效。重新运行quote,获取新的checkout-session-id,然后结账。 - 付款被拒/“captcha required”/失败——告知用户交易未成功,并询问要不要重试或换一家商家。失败的会话无法重试——请重新执行
quote。 - “already being processed”(
SHOP_CHECKOUT_IN_PROGRESS)——结账正在处理中;请等待,不要重新提交。 - 结账次数限制/未完成的结账过多(配额)——告知用户该提示;用户已达到上限。
反模式
- 从
product/quote直接进入消费流程,却没有明确确认商品、卖家和总价——即使用户说了“帮我买 X”也不行。这是绝对不能做的第一件事。 - 在同一轮中连续执行两条
prava shop命令(例如product→quote),中间没有等待用户回复。先展示,再等待。 - 默默选定商品,却不把商品描述/报价转告用户。
- 把原始 JSON、图片 URL 或美分金额直接丢给用户。
- 有多个款式可选时,不询问而是自行猜测。
- 用户尚未批准银行卡会话(还没有 token)就调用
checkout。 - 会话过期或失败后重新结账,而不是重新询价。
- 创建的会话金额与报价总额不符。
- 将此技能用于 Prava 自有业务问题或 P2P 支付(这些属于 prava-pay / 不在范围内)。
快速参考
完整的标志、输出和退出代码,请参阅 cli-shop 参考。
# No env prefix needed — the CLI detects the skill + version automatically.
prava shop search --query "<keywords>" [--intent "<user's full ask>"] [--merchant <d>] [--ships-to US] [--limit N] [--cursor <c>] [--json]
prava shop product --product-id "<id>" --merchant <d> [--json]
prava shop quote --variant-id "<id>" --merchant <d> [--quantity N] --yes [--json]
prava shop checkout --checkout-session-id "<cs>" --token <t> --cryptogram <c> --expiry-month <MM> --expiry-year <YYYY> --yes
退出代码:0 成功 · 1 错误/被拒绝 · 2 Agent 未关联。
由 Prava Payments 构建——面向 AI Agent 的支付技术栈。