需要 Silver 或更高等级的会员 — 申请时需要,之后每一次已认证的调用同样需要。若密钥所有者的会员到期,项目会被冻结,直到其重新订阅。
/v1 下进行版本管理。
获取访问权限
访问权限按项目授予。以下四项缺一不可:1
有效的 Silver 或更高等级会员
每次调用都会检查,而不只是在审批时检查。
2
已获批准的开发者申请
在控制面板的 Vito API 页面提交,由 Vetox 团队人工审核。
3
已接受的 API 开发者条款
在提交申请时确认。
4
项目所需的 scope
由 Vetox 团队根据你的描述授予。
Scope
身份验证
将密钥作为 Bearer 令牌发送:- IP 白名单 — 将调用限制在特定的服务器 IP
- 速率限制 — 按项目设定的上限,随所有者的会员等级提升
密钥、轮换与保管
- 只将其保存在服务端 — 任何持有它的人都能向你的用户扣款
- 在 API 密钥标签页中轮换。旧密钥会继续生效 24 小时作为宽限期,让你不停机完成部署
- webhook 签名密钥单独轮换,拥有各自的 24 小时重叠期
- 一旦泄露,请立即轮换
官方 Node.js SDK
官方软件包@vetox-bot/vito 封装了全部九个端点以及 webhook 校验。它替你处理 Idempotency-Key 请求头、带指数退避的重试、超时以及错误分类。
安装
fetch 与 node:crypto — 同时提供 ESM 和 CommonJS 两种格式,并附带完整的 TypeScript 类型定义。
初始化
apiKey,SDK 会从环境变量读取 VITO_API_KEY。密钥格式在构造时即被校验,因此格式错误的密钥会立刻失败,而不会白白花掉一次网络往返和一个 401。
客户端选项
可用方法
每个方法都直接返回已解包的
data 字段 — 你永远不需要自己去取 success 或 data。所有方法还接受按次调用的选项:{ timeoutMs, maxRetries, signal, headers },写入类方法另外接受 { idempotencyKey }。使用示例
启动时校验密钥
读取余额
向用户扣款(售出商品)
为用户充值
遍历交易
幂等性与重试
SDK 会在每一次写入(deduct、credit、transfer)时发送 Idempotency-Key 请求头。如果你没有提供,它会每次调用只生成一次,并在每次重试时重发完全相同的键,因此重试绝不可能把同一笔操作结算两次。
当同一个逻辑操作可能从新的进程重新发起时 — 任务执行器、队列重投递或定时扫描 — 请自行提供键:
auth.rotateKey() 是刻意排除的 — 在那里重试会签发第二把密钥,并使第一次调用返回的那把作废。用 SDK 校验 webhook
constructEvent 会检查 5 分钟的重放窗口,以常数时间与请求头中的每一个 h1 签名比对 — 因此在 24 小时的密钥轮换重叠期内自动可用 — 随后解析载荷并返回带类型的事件。
在 Next.js(App Router)的路由处理函数中,请使用会自行读取原始请求体的变体:
投递是至少一次的。在执行任何副作用之前,请先按
event.eventId 去重。错误处理
SDK 抛出的一切都继承自VitoError,并携带 code、status、type、requestId 与 retryable。
取消一次调用
VITO_SDK_ABORTED 的 VitoConnectionError。
向用户扣款
1
你的应用调用 POST /v1/deduct
附带用户、金额、发起的
guildId 以及商品详情。2
Vito 返回 confirmUrl
一条待确认记录,有效期 10 分钟。用户同时会收到私信。
3
用户用 PIN 批准
在
vetox.io 上完成。4
Vito 结算并通知
余额被扣除,交易被记录;若你配置了 webhook,会发送一条带签名的通知。
5
你的应用验证并完成
校验签名,然后解锁内容或发放商品。
请求参数 — /v1/deduct
为用户充值
POST /v1/add 从你自己的余额为用户充值 Vito,用于奖励或退款。除 guildId 和 product 外,字段与 /deduct 相同。
与扣款不同,充值没有确认步骤 — 会立即结算。需要
credit:create scope 和足够余额,否则调用返回 402 VITO_INSUFFICIENT_OWNER_FUNDS。费用
每笔扣款在扣除平台手续费后结算给你 — 采用与应用内 Vito 转账相同的费率,依据你的会员等级:5 Vito 及以下的金额免手续费,通过
/v1/add 的充值则始终免手续费。Webhook
在设置标签页中添加一个或多个https 回调地址。每当一条确认记录进入终态,Vito 就会发送一条带签名的 POST。
校验签名
每次投递都带有X-Vito-Signature 请求头:
X-Vito-Event-Id 作为去重键,因为重试会发送相同的 id:
用你的签名密钥对
<ts>:<rawBody> 重新计算 HMAC,并以常数时间比较。
事件
共五种事件类型,全部共用同一种载荷结构。结果由data.status 承载。
webhook 会以退避策略重试 5 次。请尽快返回 2xx,并异步执行你的发货逻辑。
错误码
每个响应都包在一层信封里。成功携带data,失败携带 error,两者绝不会同时出现:
速率限制
此外还有按 IP 的限制,为你每分钟配额的一半,最低不少于 30。
发送
Idempotency-Key 请求头,即可安全地对重试去重。端点
限制
- 确认记录会在 10 分钟后过期 — 请把未确认的请求当作已放弃
amount必须是正整数metadata最多 10 个键- 单笔与每日上限由 Vetox 团队设定,在设置标签页中以只读方式展示
安全检查清单
把密钥留在服务端
把密钥留在服务端
API 密钥与签名密钥绝不属于客户端代码。任何一个泄露都要立即轮换。
校验每一个 webhook
校验每一个 webhook
对照原始请求体校验签名,并拒绝早于约 5 分钟的投递。
只在 completed 时结算
只在 completed 时结算
切勿依据
/deduct 的响应发货 — 扣款要到 confirmation.completed 才算最终确定。最小权限
最小权限
只申请你真正使用的 scope,并启用 IP 白名单。
疑难排查
每次调用都返回未授权
每次调用都返回未授权
所有者的会员已到期。它在每次调用时都会重新检查。
我把密钥弄丢了
我把密钥弄丢了
无法找回 — 系统只保存哈希。请轮换以获取新的密钥。
轮换后 webhook 签名校验失败
轮换后 webhook 签名校验失败
在 24 小时重叠期内请同时接受新旧两个密钥。
有一笔扣款始终没有完成
有一笔扣款始终没有完成
用户没有批准。确认记录会在 10 分钟后过期。
收不到任何 webhook
收不到任何 webhook
项目需要同时具备回调地址和签名密钥。只有其中之一时,什么都不会发送。
到账的 Vito 比我扣的少
到账的 Vito 比我扣的少
这是结算手续费。使用 5 Vito 及以下的金额可以避免,或把它计入你的定价。
402 VITO_INSUFFICIENT_OWNER_FUNDS
402 VITO_INSUFFICIENT_OWNER_FUNDS
/v1/add 由你自己的余额出资,并非凭空产生。请先充值。Vito
余额、PIN 与费用。
付款请求
你向用户扣款时,他们看到的界面。
npm 上的 @vetox-bot/vito
官方 Node.js 软件包 — 一次安装,完整集成。