案例:AI 智能体购买 eSIM,随后拿回退款
套件的真实运行记录,附带交易哈希,每一步都可以在链上核对。案例 2(第 10 节)是同一个智能体通过枢纽购买我们的能力。第一个案例是智能体路径的完整往返:AI 智能体找到报价,通过 x402 用 USDC 付款,把 eSIM 交给主人,之后申请退款,卖家节点把钱退回,整个过程无人手动操作钱包。
1. 发生了什么
2026 年 10 月 15 日,个人 AI 智能体 ARGUS 的主人在 Telegram 里对它说:给我买最便宜的土耳其 eSIM。ARGUS 向套件的卖家节点询价,选中“土耳其 500 MB 7 天”,价格 0.31 USDC,请主人批准后用自己的钱包付款。几秒钟后,主人在聊天里收到了二维码和激活码。ARGUS 本身从未看到它们。
34 分钟后,主人让 ARGUS 申请退款。eSIM 尚未安装,于是卖家节点在批发商处取消了它,并把 0.31 USDC 退回智能体的钱包。所有钱包和批发余额都回到了起点。
卖家是套件的私有测试台:一个普通的卖家节点,按成本价销售,只允许智能体所在主机访问。整个过程没有任何模拟。
2. 参与方
| 参与方 | 是什么 | 地址或位置 |
|---|---|---|
| 主人 | ARGUS 为之工作的人;在 Telegram 中批准每一笔付款 | 私人 Telegram 聊天 |
| ARGUS | 智能体(买家);用自己的钱包付款 | 0x428f2Be4327908948e3B1915C55ddF8fA6bf73cc |
| 卖家节点 | 套件的 rails/ 节点(卖家),已开启自动退款 | https://esim.modelmarket.dev/stand |
| 卖家钱包 | 收款并支付退款(PAY_TO 和 REFUND_KEY_FILE 是同一个钱包) | 0xF47161fBB56D0D910a17e503C8292903F41BbAE2 |
| facilitator | Coinbase 的 x402 facilitator:验证每笔已签名的转账并上链,支付 Gas 费 | CDP |
| 批发商 | eSIM Access:签发和取消配置文件 | 运营者的账户 |
3. 完整链路
sequenceDiagram
autonumber
actor O as 主人 (Telegram)
participant A as ARGUS (智能体)
participant S as 卖家节点
participant F as x402 facilitator
participant W as eSIM Access
O->>A: 给我买最便宜的土耳其 eSIM
A->>S: POST /quote {"country":"TR"}
S-->>A: TR_0.5_7,500 MB,7 天,0.31 USDC(已签名)
A->>O: 批准 esim_buy?
O-->>A: /yes
A->>S: POST /order {"offer_id":"TR_0.5_7"}
S-->>A: 402 Payment Required:0.31 USDC 付给卖家钱包
A->>S: 同一订单,带 PAYMENT-SIGNATURE(EIP-3009,由 ARGUS 签名)
S->>F: verify
S->>W: 订购一个配置文件(按付款幂等)
W-->>S: 配置文件 26101505200012
S->>F: settle
F-->>S: tx 0x617efd7a…3ae0
S-->>A: 交付:激活码、二维码、状态令牌
A->>O: 二维码和激活码,绕过模型直接发送
Note over O,W: 34 分钟后
O->>A: 退掉最近那张 eSIM,我没有安装
A->>O: 批准 esim_refund?
O-->>A: /yes
A->>S: POST /refund {esim_tran_no, status_token}
S->>W: 是否已安装?是否用过流量?
W-->>S: GOT_RESOURCE,未安装,0 字节
S->>W: 取消配置文件
S->>F: verify 并 settle 0.31 USDC,卖家钱包 → ARGUS
F-->>S: tx 0x6dcfb7f0…ed4b
S-->>A: refunded
A->>O: 已退款 0.31 USDC,tx 0x6dcfb7f0…ed4b
4. 交易
全部在 Base 主网上,使用 USDC(0x8335…2913)。可在 basescan.org 查看任意一笔。
| 步骤 | 交易 | 区块,时间(UTC) | 从 → 到 | 金额 | Gas 费支付方 |
|---|---|---|---|---|---|
| 给智能体充值 | 0x225afba5cd651e3ccdf70593fe985d1e24ddc14836270e83b13f546b6d017578 | 52624834 | 主人的钱包 0x097e…475a → ARGUS | 0.50 | 主人 |
| 购买 | 0x617efd7abe4b4c6a80b54046617a73415aa54df7ada5f002ce7260cf68ac3ae0 | 52626137,05:20:21 | ARGUS → 卖家钱包 | 0.31 | facilitator 0x93f6…be44 |
| 退款 | 0x6dcfb7f075ad7fb6308064ac53e310dfb6adfd9b65d9f44b3c9a6dd39ca9ed4b | 52627173,05:54:53 | 卖家钱包 → ARGUS | 0.31 | facilitator 0x4c93…0205 |
购买和退款都是 EIP-3009 transferWithAuthorization 调用:付款钱包签名,facilitator 提交上链。ARGUS 和卖家钱包在整个过程中都没有持有任何 ETH。
5. 资金与余额
flowchart LR
A["ARGUS 钱包"] -- "购买:0.31 USDC(x402)" --> S["卖家钱包"]
S -- "退款:0.31 USDC(经 facilitator 的 EIP-3009)" --> A
N["卖家节点"] -- "订购 0.30 USD,然后取消" --> W["eSIM Access 余额"]
F["x402 facilitator"] -. "两笔转账的 Gas 费" .-> B["Base"]
| 之前 | 购买后 | 退款后 | |
|---|---|---|---|
| ARGUS 钱包 | 0.50 USDC | 0.19 USDC | 0.50 USDC |
| 卖家钱包 | 0 | 0.31 USDC | 0 |
| eSIM Access 余额 | 20.00 美元 | 19.70 美元 | 20.00 美元 |
| ARGUS 或卖家花费的 ETH | 0 | 0 | 0 |
测试台按成本价销售(MARGIN_PCT=0,MIN_MARGIN_USD=0.01):批发价 0.30 美元,向智能体收取 0.31 USDC。按套件默认加价,同一套餐售价为 1.30 美元。
6. 退款规则
stateDiagram-v2
[*] --> delivered: 已付款并结算
delivered --> in_use: 已安装或已使用流量
in_use --> [*]: 409 in_use,不退款
delivered --> cancelled: 带状态令牌的 POST /refund
cancelled --> refunded: 退款钱包退回价款
cancelled --> due: 没有退款钱包,或付款失败
due --> [*]: 运营者手动支付
refunded --> [*]
- 只有付款方可以申请。 请求携带交付时附带的状态令牌。令牌错误返回
404,与未知 eSIM 相同。 - 只限未使用的 eSIM。 节点先询问批发商:已安装或已产生任何流量的配置文件返回
409 in_use,保持原状。 - 只退回付款地址,只退所付价款。 节点在订单中保存付款方和价格,绝不多退。
- 只退一次。 重复请求或并发的两个请求得到相同的回答,不会二次付款。失败的付款不会自动重试:转账可能已经上链,运营者应先查链。
- 有上限。 每笔退款
REFUND_MAX_USD,每天REFUND_DAILY_MAX_USD,默认各为 50。测试台使用 1 和 2。 - 先取消,再付款。 批发商会把取消的配置文件费用退回运营者,因此运营者除了时间什么都不损失。
7. 为你的节点开启退款
在你给节点一个用于退款的钱包之前,退款是关闭的。没有它时,POST /refund 仍会取消未使用的 eSIM 并把退款记为待付,你会收到 agent_order.refund_due webhook,自行支付。
# 一个在 Base 上持有 USDC 的退款钱包:PAY_TO 本身的钱包(退回收到的钱),或单独的备用金。
# 不需要 ETH:Gas 费由 facilitator 支付。
cd ~/esim-operator-kit
umask 077
printf 'Refund wallet private key: '; read -rs v; printf %s "$v" > secrets/refund_key; echo; unset v
sudo chown 1000:1000 secrets/refund_key && sudo chmod 600 secrets/refund_key
echo "REFUND_KEY_FILE=/run/secrets/esim/refund_key" >> .env
echo "REFUND_MAX_USD=20" >> .env
echo "REFUND_DAILY_MAX_USD=100" >> .env
docker compose up -d rails
curl -s https://<your domain>/agents/healthz # "refunds": "automatic"
| 设置 | 作用 |
|---|---|
REFUND_KEY_FILE | 支付退款的钱包私钥。这是套件唯一会读取的私钥,而且只在你开启时读取。 |
REFUND_MAX_USD | 单笔退款上限。 |
REFUND_DAILY_MAX_USD | 每天所有退款的总上限。 |
CDP_KEY_FILE | 付款时已经设置;退款走同一个 facilitator。 |
如果退款钱包不是你的主钱包,只在其中放备用金:服务器上的私钥,一旦被入侵就可能被读取。
8. 申请退款
智能体需要交付时拿到的两个值:
curl -s -X POST https://<seller>/agents/refund -H 'content-type: application/json' \
-d '{"esim_tran_no":"26101505200012","status_token":"…"}'
{"success": true, "result": {"esim_tran_no": "26101505200012", "status": "refunded", "amount_usd": "0.31",
"to": "0x428f2be4327908948e3b1915c55ddf8fa6bf73cc", "at": "2026-10-15T05:54:50.399Z",
"transaction": "0x6dcfb7f075ad7fb6308064ac53e310dfb6adfd9b65d9f44b3c9a6dd39ca9ed4b"}}
status 为 refunded 时附带交易哈希;为 due 时由卖家手动支付。/listing.json 会说明是哪一种:其 refund.policy 写明规则,/healthz 显示 "refunds": "automatic" 或 "operator"。
9. 我们学到了什么
- 谨慎的智能体会质疑立即退款。 当在一条消息里被要求“买下并立刻退款”时,ARGUS 停下来询问真实意图:买下保留、什么都不买,还是因真实原因退款。主人先购买,再单独申请退款。真实的智能体会因真实原因退款,卖家可以预期它们会礼貌地、只申请一次。
- 激活码从未离开交付。 卖家只在已付款订单的回答中发送激活码;ARGUS 将它转发到主人的聊天,自己只保留配置文件编号和状态令牌。卖家的记录和智能体的账本都不保存它。
- 全程无需 Gas 费。 智能体签了一个付款授权,卖家钱包签了一个退款授权,其余由 facilitator 完成。
- 批发商的退款让退款变得安全。 节点先取消再付款,因此退款的订单不会让运营者损失任何费用。
10. 案例 2:经枢纽,从我们的公开节点购买
在案例 1 中,智能体被告知了卖家地址。在案例 2 中,它自己找到了卖家:ARGUS 在 modelmarket.dev 枢纽中搜索 eSIM 卖家,找到我们 esim-modelmarket 的能力 esim.quote@v1,经枢纽向它询价,然后通过 x402 直接付款到卖家自己的 /order。枢纽只转发了免费的询价,从未接触资金。
为了这次测试,我们的公开节点从演示模式切换为销售模式,测试结束后立即切回演示模式。 esim-modelmarket 背后的节点(modelmarket.dev/providers/esim)在 2026 年 10 月 15 日 06:56:55 至 07:48:33 UTC 之间销售了 52 分钟,按成本价(MARGIN_PCT=0,MIN_MARGIN_USD=0.01),收款进入与测试台相同的卖家钱包,并从中自动退款(每笔最多 2 美元,每天最多 5 美元)。自 07:48:33 起,它再次以 demo_mode 拒绝每一笔订单。
sequenceDiagram
autonumber
actor O as 主人 (Telegram)
participant A as ARGUS (智能体)
participant H as modelmarket.dev 枢纽
participant S as 卖家节点 (modelmarket.dev/providers/esim)
participant F as x402 facilitator
O->>A: 给我买最便宜的土耳其 eSIM
A->>H: GET /ai-market/v2/search?intent=esim
H-->>A: esim-modelmarket 的 esim.quote@v1(经 esim.modelmarket.dev)
A->>H: POST /ai-market/v2/invoke esim.quote@v1(免费)
H->>S: 转发询价
S-->>A: seller demo: false · TR_0.5_7 0.31 USDC · 订单地址 …/providers/esim/order
A->>O: [SELLS] TR_0.5_7 0.31 USDC · 批准 esim_buy?
O-->>A: /yes
A->>S: x402 直接付给卖家:402,然后 PAYMENT-SIGNATURE(EIP-3009)
S->>F: verify,然后 settle
F-->>S: tx 0xeea12962…881e
S-->>A: delivery
A->>O: 二维码和激活码,绕过模型
O->>A: 退掉最近那张 eSIM
A->>O: 批准 esim_refund?
O-->>A: /yes
A->>S: POST /refund {esim_tran_no, status_token}
S->>F: 在 eSIM Access 取消,然后退回 0.31 USDC
F-->>S: tx 0x45dc5ce6…ec88
S-->>A: refunded
| 时间(UTC) | 发生了什么 |
|---|---|
| 06:56:55 | 公开节点从演示切换为销售。经枢纽的报价显示 demo: false 和 0.31 USDC |
| 07:21 | 第一次尝试:ARGUS 看到了报价,但拒绝购买。节点名称仍是“modelmarket.dev demo seller”,智能体按名称做了判断 |
| 07:23 | 修复上线:节点名称随模式变化,ARGUS 根据卖家自己的回答为每个报价标注 [SELLS] 或 [DEMO] |
| 07:47:35 | 主人 /yes 后 ARGUS 购买 TR_0.5_7;eSIM 26101507470034 送达主人的 Telegram |
| 07:48:02 | 主人申请退款并以 /yes 批准;节点取消未使用的 eSIM 并退款 |
| 07:48:33 | 公开节点切回演示模式 |
| 步骤 | 交易 | 区块,时间(UTC) | 从 → 到 | USDC | Gas 费支付方 |
|---|---|---|---|---|---|
| 购买 | 0xeea12962c4f494e55acc59a376203bd4b704804f19a84b4b8f47a96b265a881e | 52630556,07:47:39 | ARGUS → 卖家钱包 0xF471…bAE2 | 0.31 | facilitator 0x68a9…7863 |
| 退款 | 0x45dc5ce6579d8e889750442d63773586c481a11b30ddf44805960860f3bbec88 | 52630569,07:48:05 | 卖家钱包 → ARGUS | 0.31 | facilitator 0x625d…ac39 |
ARGUS 是这一窗口期内唯一的买家:节点记录中只有一笔订单,且已退款。最终 ARGUS 重新持有 0.50 USDC,卖家钱包为 0,eSIM Access 余额为 20.00 美元,eSIM 处于 CANCEL 状态,没有任何钱包花费 ETH。
这个案例说明了:
- 智能体会读名称。 卖家的报价表明它在销售,但名称写着“demo”,智能体相信了名称。卖家节点应按其实际行为命名;智能体应依据卖家的回答而不是名称做决定。
- 枢纽负责发现,卖家负责销售。 发现和免费询价经过枢纽;付款和退款直接在智能体与卖家之间进行,枢纽在任何时候都没有持有资金。
- 演示只是一个设置。 同一个节点、同一个目录、同一个批发账户,是否销售取决于
DEMO_MODE:运营者可以在几秒内开启和关闭销售窗口。