演示模式:面向 eSIM 运营商的参考店铺。价格为实时价格,支付已关闭。 运行你自己的运营商 →
Travel eSIM · demo
中文

运营者指南

目录

本指南带你从一台空服务器走到第一笔销售,然后介绍日常工作:订单、退款、余额、备份、更新。安装请预留一小时, 其中大部分时间是在等待批发账户开通和 DNS 记录生效。

其他文档:概览 · 智能体指南 · 接入指南 · 集成 · SDK

1. 你要搭建什么

            https://esim.example.com
                      │
                   Caddy (80, 443, Let's Encrypt)
      ┌───────────────┼──────────────────────────────┐
      │               │                              │
   store          rails (/agents/*)              node (/.well-known/ai-market.json, /ai-market/*)
  用户购买        智能体通过 x402 购买            枢纽发现你的套餐
      │               │
      └──── 你的 eSIM Access 余额 ────┘        付款进入你自己的钱包

store 和 rails 从同一个批发账户购买。两者都不持有资金:买家付款到你的地址,套件只读取链上数据来确认款项到账。

2. 开始之前

你需要说明
一个 eSIM Access 账户在 esimaccess.com 注册。见第 3 步。
至少 50 美元余额首次充值至少 50 美元(银行卡、PayPal 或支付宝;3,000 美元起可银行转账)。
一台 Linux 服务器装有 Docker Engine 和 compose 插件,有公网 IPv4,开放 80 和 443 端口。1 个 vCPU 和 1 GB 内存就够了。
一个域名或子域名例如 esim.example.com,A 记录指向服务器。
钱包地址EVM(一个地址用于全部七条 EVM 链)、Tron、Solana、TON。任意组合都可以。
销售条款和隐私政策两个公开页面。eSIM Access 要求每个经销商的网站都链接它们。
可选:Coinbase Developer Platform 密钥为用户开启 Base 上免 gas 的 USDC 付款,并开启智能体的 x402 订单。见第 8 步。
可选:Stripe开启银行卡付款。见第 8 步。

3. 批发账户

  1. 在 esimaccess.com 注册并验证邮箱。
  2. 充值余额(在控制台中:余额,然后充值)。最低 50 美元。你卖出的每张 eSIM 都按批发价从这笔余额中扣除,所以它是你的库存,不是手续费。
  3. 打开控制台的开发者(API)部分。那里有两个值:AccessCode 和 SecretKey。像对待密码一样对待 SecretKey。

没有沙盒:每一笔 API 订单都是真实的。两种低成本的测试方法:

4. 服务器和域名

  1. 为你的域名创建 A 记录,指向服务器的 IPv4 地址。在你的电脑上检查:
dig +short esim.example.com
  1. 在服务器上安装 Docker(docs.docker.com/engine/install),并确认 compose 可用:
docker compose version
  1. 在服务器防火墙和云服务商面板中开放 80 和 443 端口。Let's Encrypt 在签发证书前会检查 80 端口。

5. 获取套件并配置

git clone https://github.com/alexar76/esim-operator-kit.git
cd esim-operator-kit
cp .env.example .env
nano .env
设置填写什么
DOMAIN你的域名,不带 https://。
STORE_NAME买家在页头、标题和钱包弹窗中看到的店名。
PRODUCT_ID你的套餐在联邦中的简短标识,例如 esim-mytravel。字母、数字、短横线。
STORE_CONTACT买家联系你的邮箱,显示在页脚。
STORE_TERMS_URL、STORE_PRIVACY_URL你的销售条款和隐私政策,链接显示在页脚。
MARGIN_PCT在批发价基础上的加价百分比。100 表示翻倍。
MIN_MARGIN_USD每张 eSIM 的最低利润(美元)。便宜的套餐至少加这么多。
DEMO_MODE1 显示横幅且不收款。0 正式销售。在第 10 步之前保持 1。
PAY_TO_EVM、PAY_TO_TON、PAY_TO_TRON、PAY_TO_SOLANA你的收款地址。留空即关闭该网络。
EVM_CHAINS提供哪些 EVM 链,用 chain id 表示:8453 Base、1 Ethereum、42161 Arbitrum、10 OP、137 Polygon、56 BNB Chain、43114 Avalanche。
EVM_RPC_<chain id>、SOLANA_RPC可选:你自己的 RPC 端点。公共端点有频率限制。
SUPPLIEReSIM 的来源:esimaccess(默认)、airalo、esimgo,或用 http 接入你自己的系统。见集成。
WEBHOOK_URL、WEBHOOK_SECRET_FILE可选:把每个订单的状态签名后发送到你的 CRM、计费系统、Telegram 或表格。见集成。

价格怎么算。 价格 = 批发价 × (1 + MARGIN_PCT/100),但不低于批发价 + MIN_MARGIN_USD,向上取整到美分。按默认值(100% 和 1.00 美元),法国 1 GB 7 天的批发价是 0.70 美元,售价 1.70 美元。批发价 9.00 美元的 20 GB 套餐售价 18.00 美元。零售 eSIM 商店的小套餐通常要价 4 到 8 美元,所以你有空间。

只要地址。 每个 PAY_TO_* 都是你的收款地址。套件从不需要私钥或助记词。如果某份指南或某个人让你把它们放进 .env,那一定是错的。

6. 放置密钥

密钥存放在 secrets/,每个文件一个值。该目录不进 git,以只读方式挂载到容器中。用下面的方式输入,避免它们进入 shell 历史记录:

cd ~/esim-operator-kit
umask 077
printf 'AccessCode: '; read -rs v; printf %s "$v" > secrets/esimaccess_access_code; echo
printf 'SecretKey: '; read -rs v; printf %s "$v" > secrets/esimaccess_secret_key; echo
unset v

容器以用户 1000 运行,所以要把密钥文件和数据目录交给该用户:

mkdir -p data/store data/rails data/node data/caddy
sudo chown 1000:1000 secrets/*
sudo chown -R 1000:1000 data/store data/rails data/node
ls -l secrets

目录本身仍属于你,之后可以继续添加文件。每个新的密钥文件都需要同样的 sudo chown 1000:1000 和 chmod 600。

secrets/README.md 列出了所有可选文件:CDP 密钥、tonapi 和 TronGrid 密钥、Stripe 密钥。

7. 以演示模式启动

docker compose up -d --build
docker compose ps
docker compose logs --tail 30 store rails

首次构建需要几分钟。然后检查三件事:

curl -s https://esim.example.com/agents/healthz
curl -s -X POST https://esim.example.com/agents/quote -H 'content-type: application/json' \
  -d '{"country":"FR","min_gb":3,"min_days":7,"limit":3}'

如果健康检查返回 "ok":false,说明批发密钥错误或无法读取。见第 14 节。

检查你的价格。 下面的命令打印余额,以及任意国家按你的加价计算的最佳套餐,旁边附批发价:

docker compose exec -T rails node scripts/catalog.mjs FR ES IT US JP TH

在 .env 中修改 MARGIN_PCT 或 MIN_MARGIN_USD,然后用 docker compose up -d 生效。

8. 付款

每种方式在设置好地址(以及所需的密钥)后开启。开启你的买家常用的方式。Tron 上的 USDT 是最常见的加密货币付款方式,其次是 EVM 链上的 USDT 和 USDC,以及 TON 上的 USDT。

方式需要设置买家如何付款店铺如何确认
Base 上免 gas 的 USDCPAY_TO_EVM + secrets/cdp_api_key.json在浏览器钱包中签名一条消息,不付 gas。由 CDP facilitator 结算签名。先交付 eSIM,再结算付款;如果结算失败,eSIM 会被取消。
7 条 EVM 链上的 USDC / USDTPAY_TO_EVM(+ EVM_CHAINS)从浏览器钱包发起转账,或从任意钱包或交易所转账后粘贴交易哈希。读取交易回执:该代币转给你、金额不低于价格、时间晚于订单。等待确认数:Ethereum 和 BNB Chain 3 个,Polygon 10 个,其他 1 个。一笔交易只支付一个订单。
Tron 上的 USDTPAY_TO_TRON(+ secrets/trongrid_key)用页面上的 TronLink 或任意钱包,发送页面显示的精确金额。每个订单要求的金额是价格加上几百万分之一美元(最多多出 0.0099 美元)。这个精确金额在你已确认的 USDT 转账中标识出该订单。
Solana 上的 USDCPAY_TO_SOLANA(+ SOLANA_RPC)打开 Solana Pay 链接或扫描其二维码(Phantom、Solflare、Backpack)。每个订单有自己的引用密钥,钱包会把它加入转账。店铺据此找到交易。
TON 上的 USDT 或 TONPAY_TO_TON(+ secrets/tonapi_key)通过 TON Connect 连接 Tonkeeper 或其他钱包,或手动转账并填写显示的备注。通过 tonapi.io 按订单备注找到转账。
银行卡secrets/stripe_secret_key + secrets/stripe_webhook_secretStripe Checkout。Stripe webhook。

主动转账类付款(除免 gas 的 Base 和银行卡外的所有方式)在订单创建后的 24 小时内都会被查找。

Coinbase Developer Platform 密钥。 它为用户开启 Base 上免 gas 的 USDC,也开启智能体的 x402 订单。没有它,店铺仍可以普通转账的方式接收 Base 上的 USDC,但面向智能体的节点不接受订单。

  1. 登录 portal.cdp.coinbase.com 并创建项目。
  2. API Keys:创建一个 secret API key,下载它的 JSON 文件。
  3. 把文件复制为 secrets/cdp_api_key.json(其中包含 id 和 privateKey),然后运行 sudo chown 1000:1000 secrets/cdp_api_key.json && sudo chmod 600 secrets/cdp_api_key.json 和 docker compose up -d。

Stripe。 在 Stripe 控制台添加 webhook 端点 https://<你的域名>/api/stripe/webhook,事件选 checkout.session.completed 和 checkout.session.async_payment_succeeded。把私钥(sk_live_…)放进 secrets/stripe_secret_key,把端点的签名密钥(whsec_…)放进 secrets/stripe_webhook_secret。

频率限制。 公共的 TronGrid、tonapi 和 RPC 端点足够小店使用。销售稳定后,添加免费的 TronGrid 密钥和 tonapi 密钥,并把 EVM_RPC_<id> 和 SOLANA_RPC 指向你自己的服务商。

9. 智能体与联邦

rails 节点已经在 https://<你的域名>/agents/ 为智能体提供服务。要让智能体在枢纽上搜索时找到你,需要向联邦描述你的节点并发布公告。

  1. 根据实时目录生成 node.toml。填入你自己的名称、域名和 PRODUCT_ID:
docker compose exec -T rails node scripts/node-toml.mjs \
  --name "My Travel eSIM" --url https://esim.example.com \
  --product esim-mytravel --upstream http://rails:9490 > node.toml
head -20 node.toml
  1. 启动节点:
docker compose --profile federation up -d --build node
curl -s https://esim.example.com/.well-known/ai-market.json | head -c 400; echo
  1. 用枢纽的方式检查它,然后发布公告:
docker compose exec node aimarket doctor --url https://esim.example.com
docker compose exec node aimarket node knock --config /node/node.toml --hub https://modelmarket.dev

在收录你之前,枢纽会用一个真实国家调用 esim.quote。收录后,在枢纽上搜索 “eSIM France” 的智能体就会得到你的套餐。付款从不经过枢纽:智能体通过 x402 直接付款到你节点对应的钱包。

data/node/ 存放节点的签名密钥,也就是它在联邦中的身份。请备份。目录新增国家后,重新执行第 1 步。

10. 测试订单,然后正式上线

  1. 在 .env 中设置 DEMO_MODE=0,并逐字符再次核对 PAY_TO_* 地址。
  2. 生效:
docker compose up -d
curl -s https://esim.example.com/agents/healthz

应显示 "demo":false。设置了 CDP 密钥和 PAY_TO_EVM 后会显示 "paid_orders":true。

  1. 在你自己的店铺,用你自己的钱包,在你预计买家最常用的网络上,购买某个国家最便宜的套餐。订单页面应在一分钟内显示二维码。
  2. 在钱包中核对付款,在 eSIM Access 控制台中核对订单。
  3. 如果你不想保留这张 eSIM,在 eSIM Access 控制台取消未使用的配置文件。批发价会退回余额。你付的钱本来就进了你自己的钱包。

对每个已开启的网络都这样做一遍。然后你就正式上线了。

11. 日常工作

订单。 店铺把订单保存在 data/store/orders.json。列出需要你处理的订单:

sudo jq -r '.[] | select(.status=="refund_due" or .status=="underpaid")
  | [.created_at, .id, .status, .method, (.price_cents/100), .payment.ref, (.payment.payer // "-"), (.error // "")] | @tsv' \
  data/store/orders.json
状态含义怎么做
awaiting_payment订单已创建,尚未收到付款。无需操作。
delivered已付款,eSIM 已交给买家。无需操作。
refund_due已付款,但批发商未能交付:余额用完,或套餐下架。在同一网络上退款到 payment.payer,或充值后手动为买家补发该套餐。
underpaid收到的金额低于价格。退款,或请买家补齐差额后手动交付。
expired24 小时内未收到付款。无需操作。之后到账的付款不会被匹配,你会在钱包里看到一笔没有订单的款项。

买家会写信到 STORE_CONTACT。向他们索要页面地址中的订单号(/o/<订单号>)。不要索要完整链接:里面有他们的令牌。

余额。 让批发余额保持在几天销量以上。余额不足以支付订单时,付款页会显示“该套餐暂时不可用”,而不会收款。用下面的命令查看余额:

docker compose exec -T rails node scripts/catalog.mjs | head -1

日志。

docker compose logs -f --tail 100 store rails

日志中从不包含激活码或密钥。

备份。 每天把 data/ 和 secrets/ 备份到服务器以外的地方:

更新。

git pull
docker compose up -d --build
docker compose --profile federation up -d --build node    # 如果你运行联邦节点

在更新正在销售的店铺之前,先阅读版本说明。

12. 智能体的订单

智能体通过 POST /agents/order 购买(见智能体指南)。节点验证 x402 付款、购买配置文件,并且只在配置文件创建后才结算。如果结算失败,节点会取消配置文件,批发价退回你的余额。智能体的订单记录在 data/rails/orders.json 中,不含激活码。USDC 会到达你在 Base 上的 PAY_TO_EVM。

13. 法律、税务和条款

以下不构成法律或税务建议。开始销售前,请咨询你所在国家的会计师。

14. 故障排查

现象原因解决
浏览器提示证书无效DNS 尚未指向这里,或 80 端口未开放dig +short <域名>,开放 80 端口,然后 docker compose restart caddy 并查看 docker compose logs caddy。
healthz 显示 "ok":false,或店铺没有任何国家批发密钥错误,或用户 1000 无法读取。日志显示 catalogue not loaded yet: <code>。sudo rm secrets/esimaccess_*,按第 6 步重新写入,然后 docker compose restart store rails。
日志中出现 EACCES 或 permission denied数据目录不属于用户 1000sudo chown -R 1000:1000 data/store data/rails data/node
付款页显示“该套餐暂时不可用”批发余额不足以支付该套餐给 eSIM Access 充值。
每个付款步骤都回答“演示模式:支付已关闭”DEMO_MODE=1第 10 步。
付款页缺少某个网络它的 PAY_TO_* 为空检查 .env,然后 docker compose up -d。
店铺反复重启某个 PAY_TO_* 不是有效地址:店铺遇到无效地址会拒绝启动docker compose logs store 会指出是哪个。修正 .env。
找不到 Tron 付款金额不精确,常见原因是交易所从金额中扣除了手续费在钱包中找到这笔转账并退款,或手动交付。提醒买家从钱包发送精确金额。
找不到 TON 付款备注缺失或被修改同上。使用 TON Connect 时钱包会自动填写备注。
aimarket doctor 报告私有地址node.toml 中的 url 不是你的公网域名用 --url https://<域名> 重新生成 node.toml(第 9 步)。
node 无法启动:node.toml 是个目录文件不存在时 compose 自动创建了目录rmdir node.toml,生成文件(第 9 步),再次启动。

GitHub 上的套件 →