你将构建什么
一个文档生成 SaaS——用户每次执行付费操作时,Profy 自动从其账户扣除相应积分:- 生成报告(
generate_report)→ 扣 10 积分 - 导出 PDF(
export_pdf)→ 扣 5 积分 - 生成摘要(
generate_summary)→ 扣 3 积分
ProfyApp SDK 调用完成,Profy 保证幂等与原子性。
前置条件
report_event 走 OAuth,只有用户 OAuth token 能调用(不是 API Key)。OAuth token 仅持有 events:write scope——它能上报计费事件,但不能调用 Expert/Chat(那是 sk-pro- API Key 的能力)。Step 1: 在 Studio 中配置计费事件
进入 Profy Studio → 你的 App → 计费事件,添加以下 Meter:事件名称一旦创建后不可修改,请使用
snake_case 命名。单价可随时调整,调整后立即生效。运行时可用 list_meters() 读取当前配置的事件与单价。Step 2: 安装和初始化 SDK
ProfyApp 只持有 App 身份(client_id / client_secret)。用户 token 每次调用时传入——因为一个 App 服务很多用户,各自持有不同的 token。
Step 3: 实现计费上报
用户触发付费操作时,调用report_event 上报。传入该用户的 OAuthToken,并用 on_refresh 回调持久化轮换后的 token(refresh 每次都会轮换,旧 refresh token 立即作废)。
扣费金额由服务端根据 Meter 的单价决定——请求体没有 amount/units 字段。想在客户端展示单价,用
list_meters() 读取。Step 4: 用 Meter 展示单价 + 从响应追踪余额
平台没有独立的余额查询端点。正确做法是:用list_meters()(公开,无需 token)拿到单价用于前端展示;用户余额则从每次 report_event 响应的 balance_remaining 追踪,并始终处理 InsufficientBalanceError(402)。
Step 5: 处理扣费失败
错误按 HTTP 状态码分类,都继承自ProfyApiError(带 .statusCode / .status_code 和 .body)。
report_event 内置了 token 轮换处理:access token 过期时(配了 on_refresh)会自动刷新一次并回调,401 时也会反应式刷新重试一次。你只需在 on_refresh 里持久化新 token。Step 6: 幂等性与安全重试
idempotencyKey 保证同一业务操作不会被重复扣费。请求超时或网络抖动时,用同一个 key 安全重试。
计费事件设计指南
命名规范
- 使用
snake_case,以动词开头:generate_、export_、analyze_ - 避免泛化命名(如
action、event),长度建议 ≤ 32 字符
粒度决策
常见问题
Q: 幂等键重复会怎样? API 返回idempotent_replay: true,不会重复扣费。charged 值为首次扣费金额。
Q: 怎么在扣费前知道余额?
平台没有余额查询端点。用每次 report_event 响应里的 balance_remaining 追踪,并处理 InsufficientBalanceError。
Q: metadata 会被存下来吗?
metadata 字段被接受但当前不会被持久化或返回,不要依赖它做业务判断——它仅供未来扩展。
Q: 单价修改后已发出的请求按哪个价格?
按请求到达时的最新单价计算。修改立即生效,无过渡期。
Q: refresh token 会过期吗?
90 天有效,且每次刷新都会轮换(旧的立即作废)。用 on_refresh 持久化新 token,否则 App 刷一次就把自己锁死。
下一步
SDK 快速开始
OAuth 授权与基础事件上报
Token 管理
OAuth 授权码流程与 token 轮换持久化
调用平台专家
在你的 App 中嵌入 AI 专家能力
API 参考
Events API 完整端点文档

