
简介这是一份 OneAPI 计费系统开源版 1.2.0 的完整源码包面向需要自建 API 网关并集成计费能力的开发者或中小团队。系统支持免费、资源包、混合计费等多种模式兼顾卡密兑换、余额充值、实名与手机号绑定校验同时提供邮件/短信验证码防刷机制和注册赠送余额更新中还修复了特定值扣费逻辑等已知问题。源码包共 2000 个文件、压缩后约 8.34MB其中 PHP 文件 643 个构成核心业务逻辑MD 文档 725 个便于阅读部署与二次开发说明JSON 数据 531 个覆盖配置与接口定义另含前端样式、JavaScript、SQL 初始化脚本与 License 文件目录结构清晰。已有 95 人学习下载。通过该源码包可快速部署一套可运营的 API 计费管理后台也可基于在线 API 文档与代码编辑能力灵活改造计费规则适合具备一定 PHP 开发经验、希望搭建或二次开发计费系统的技术人群。1. 这不是 Intel 的 OneAPI一个自托管的 API 接口计费网关先泼盆冷水如果你搜索“OneAPI”是为了找 Intel 那个 2024.2.1 的编译器工具包这篇不是给你看的。我拆的是另一个东西——OneAPI 计费系统开源版 1.2.0一套跑在自有服务器上的接口管理系统解决的是「API 接口怎么收费、用户怎么充值、卡密怎么发、文档怎么维护」这一串脏活。这套系统支持免费、资源包、混合计费三种模式内置卡密兑换、余额充值、实名认证、短信/邮箱验证码防刷还能在线编辑 API 文档和接口代码。适合手里有 API 想开放出来赚钱的独立开发者或者内部要做接口网关计费的小团队。我亲手搭了一套踩了几个不大不小的坑下面把部署、计费配置、扣费逻辑和排错过程完整写出来。2. 计费模型先行免费、资源包、混合计费怎么选很多人装完系统第一件事就冲去配接口结果卡在计费模型上。我先花一节把这个系统的计费骨架讲透你后面配参数才不会懵。2.1 三种计费模式的功能边界系统的计费核心是「接口」维度每个接口独立设置计费方式。管理员在后台创建接口时需要明确这个接口走哪条计费路径计费类型适用场景用户侧体验系统侧处理逻辑免费公开测试接口、引流入口无需余额直接调用不记录扣费流水只累计调用次数资源包预购次数的封装 API、按量计费的模型接口先买资源包调用时扣减次数每次请求实时扣减资源包剩余额度余量为 0 时拒绝请求混合计费部分免费额度 超出后扣费免费额度用完后自动切换扣费先查免费额度再走资源包或余额扣费这里最容易被忽略的是混合计费的优先级顺序。系统按「免费额度 → 资源包 → 余额」的顺序依次消耗而不是管理员可以随便调整的。如果你希望某个接口只走资源包、不走余额那需要在接口配置里关闭「余额兜底扣费」开关否则用户会在资源包耗尽后悄悄扣成余额月底对账时你根本想不起来这笔账是从哪来的。我自己的经验是对外收费接口一律只开资源包内部调试接口才开混合计费。2.2 卡密兑换与余额充值的流转设计卡密和充值构成了系统的资金入口。管理员在后台生成一批卡密可自定义面额、有效期、批量生成数量用户在个人中心输入卡密兑换成余额。余额充值则走站内配置的支付通道支付回调成功后自动入账。这里注意一个流转细节卡密兑换生成的余额和直接充值的余额在系统里是同一种资产不存在「充值余额」和「赠送余额」的隔离。这意味着如果你用了「注册赠送余额」功能赠送的余额和充值余额混在一起。如果你后续要搞活动、限制赠送余额不可提现或不可用于某些接口需要自己在业务层加标记这个版本的原生逻辑不区分资产来源。2.3 实名与手机号校验在什么环节生效系统支持实名认证和绑定手机号校验但很多管理员不知道这两个校验在什么环节强制、什么环节可选。我实测后的结论是手机号绑定注册时可选绑定也可以在用户中心后补。绑定后涉及敏感操作如修改支付密码、提现会强制要求短信验证码。实名认证仅在管理员开启「接口需要实名认证」时才强制校验。未实名的用户调用该接口会被拦截返回固定的错误码。这个设计对 API 开放场景是够用的。但如果你想做「未实名用户不能充值」这种强约束原生系统做不到得自己改注册逻辑。这也是我后来放弃在实名上做太多文章的原因——这个项目的重心在计费和接口管理用户认证只是基础设施别指望它达到金融级 KYC 的水平。3. 部署与初始化从源码包到跑通首笔扣费部署环境我推荐 LNMPLinux Nginx MySQL PHP这套系统的前端资源layui、bootstrap、summernote 等和后台管理让它跑在 PHP 环境里最顺。下面按源码部署方式写这也是 DIY 属性最强的路径。3.1 环境清单与目录结构我用的环境版本Ubuntu 22.04、Nginx 1.24、MySQL 8.0、PHP 8.1需要安装 pdo_mysql、fileinfo、opcache 扩展。把源码包解压到/var/www/oneapi-billing后有三个关键目录需要先认出来/var/www/oneapi-billing ├── public/ # Web 根目录Nginx 要指向这里 ├── app/ # 业务代码含计费逻辑 ├── config/ # 数据库、缓存、邮件配置 ├── storage/ # 日志、缓存、上传的 API 文件 └── database/ # SQL 初始化脚本3.2 初始化数据库与配置文件第一步修改.env.example为.env填入数据库连接信息cp .env.example .env # 编辑 .env核心参数如下 DB_HOST127.0.0.1 DB_PORT3306 DB_DATABASEoneapi_billing DB_USERNAMEyouruser DB_PASSWORDyourpassword APP_URLhttps://api.yourdomain.com保存后导入初始 SQLmysql -uyouruser -p oneapi_billing database/oneapi_billing.sql注意如果你用的是 MySQL 8.0导入 SQL 时如果报错Row size too large通常是因为表默认用 utf8mb4 且字段过多。解决办法是在导入前把 SQL 文件里的utf8mb4替换为utf8mb4_general_ci或把默认字符集改成utf8mb4的ROW_FORMATDYNAMIC。这个坑只在 8.0 版本出现5.7 没这个问题。3.3 Nginx 配置与伪静态规则管理后台的 URL 走的是重写路由务必配置伪静态否则页面全部 404server { listen 80; server_name api.yourdomain.com; root /var/www/oneapi-billing/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }配好之后systemctl reload nginx浏览器打开后台地址用 SQL 文件里的初始管理员账号登进去第一步会强制让你改管理员密码。到这一步系统就能访问了但先别急着创建接口——先去「站点设置」里把站点名称、备案号、客服联系方式填上这些信息会直接显示在用户端页面上不然后面用户注册了看到一堆占位符体验很差。4. 扣费逻辑与防刷机制1.2.0 版本的关键改动这一章是 1.2.0 版本更新的重点也是这个资源最值钱的部分。上一个大版本被人诟病的「特定值扣费逻辑」和「验证码可刷」两件事在这个版本都动了刀。4.1 特定值扣费逻辑修复了什么先解释「特定值」是什么。计费系统的扣费公式通常是「扣费金额 单价 × 本次调用消耗的计费单位」。如果接口按 token 数或字数计费调用方传入一个use_count参数系统通过这个值计算扣费。1.2.0 之前的问题出在边界值判断上——当传入值为负数、0、超大整数或带小数时系统直接按默认单价扣费导致很多「调用返回值异常」的请求也扣了全款场面一度很混乱。这次修复后的扣费判断逻辑我拆出来是这个思路// 计费核心校验传入的计费数值 public function calcDeduction($unitPrice, $useCount, $resourceQuota) { // 1. 异常值直接拒绝不算扣费 if (!is_numeric($useCount) || $useCount 0) { return [ status rejected, reason invalid_use_count, deduct 0 ]; } // 2. 转为整数防止小数精度问题导致多扣 $useCountInt (int) floor($useCount); if ($useCountInt ! (int) $useCount) { // 非整数时按整数部分计费余数丢弃 // 这是因为 API 场景里按次消费应是离散值 } // 3. 判断资源包余量是否足够 if ($resourceQuota $useCountInt) { return [ status insufficient, reason quota_exceeded, deduct 0 ]; } // 4. 正常扣费 $deductAmount $unitPrice * $useCountInt; return [ status success, deduct $deductAmount, remaining $resourceQuota - $useCountInt ]; }这段代码揭示了三个关键行为异常数值不扣费直接拒绝、小数一律取整再乘单价、资源包余量不足时整单拒绝而不是扣成负数。这三个边界修复了上一版本「扣费金额跟实际用量对不上」的主要来源。如果你要自己改费率策略这层逻辑是唯一需要动刀的地方别去碰更底层的流量统计那部分和扣费无关。4.2 邮箱/短信验证码防刷的限流参数上一版本最头痛的问题攻击者用脚本批量请求发送验证码接口导致短信通道被打爆、邮箱被塞满垃圾邮件。1.2.0 引入了防刷机制配置入口在「系统设置 → 验证码设置」核心参数有四个参数我的推荐值说明同一 IP 发送间隔60 秒低于 60 秒直接拒绝第二次发送同一账号每日发送上限10 条防止通过频繁触发找回密码刷爆通道同一手机号/邮箱每日上限5 条防止针对单一用户轰炸图形验证码开关开启发送前必须完成图形验证码这里最值得说的是图形验证码开关一定要开。单纯依赖频率限制有绕过的空间——攻击者用代理池换 IP就能绕开 IP 限制。加上图形验证码之后每个发送请求都被前置拦截脚本根本走不到发送验证码那一步。我自己的部署里把 IP 间隔从默认的 30 秒改到了 60 秒因为发现凌晨有规律性的试探请求60 秒能把单 IP 的探测频率压到一个很低的水平。4.3 注册赠送余额的规则配置「注册赠送余额」是这次新增的功能配置在「用户设置」里支持两个参数赠送金额和启用开关。# 配置示例 REGISTER_BONUS_ENABLEDtrue REGISTER_BONUS_AMOUNT1.00注意赠送的余额在数据库里和充值余额同属一个余额字段所以如果你开启了这个功能需要考虑羊毛党的成本。我后来补了一个限制——新注册用户当日消费上限设为 5 元防止有人批量注册然后清空赠送余额调用高价接口。这个限制在原生后台没有是我自己在外层拦截层加的。如果你的赠送金额大于 1 元强烈建议你评估一下接口的单价水平别让赠送金额超过单次调用成本。5. 常见问题排查部署与异常计费的五条记录我把搭建和试运行期间踩的坑整理成故障记录按「现象 → 原因 → 解决」写后面的人照着对照能省很多时间。5.1 后台登录后页面空白现象管理员账号能登录但跳转后全白页浏览器控制台报 500。原因PHP 的storage/logs和storage/cache目录没有写权限框架在写入日志时异常退出。解决chown -R www-data:www-data /var/www/oneapi-billing/storage然后chmod -R 755。这是 PHP 项目最常见的环境类问题优先检查目录权限不要先怀疑代码。5.2 接口请求后返回 401 但在后台看到调用成功了现象用户侧调用返回未授权但后台统计里看到次数增加了。原因接口配置了「需要实名认证」用户未实名时请求被拦截但仍然被计入总调用量。也就是说这个 401 的请求被统计为「发起」而不是「成功」。解决在统计报表里区分「请求数」和「成功数」。后台列表默认显示请求数要看成功付费的请求需要切换到明细模式。这个坑属于产品定义问题不是 bug但对账时容易产生误解。5.3 卡密批量生成后有一个面额错了现象批量生成了 100 张 10 元卡密发现其中一张应该是 50 元。原因生成卡密时不支持单张改面额修改只能删除后重新生成。解决在数据库里查cards表找到那张卡密直接改amount字段。注意这个操作不会留下操作日志自己改完要在备注里记录。5.4 注册赠送余额到账延迟超过一分钟现象新用户注册后看不到赠送余额最迟延迟了 90 秒。原因系统走队列异步发放队列进程没跑或者 crontab 没配置。解决配置定时任务* * * * * php /path/to/artisan schedule:run。这是个定时调度命令不是发送验证码的队列命令。如果还不生效检查.env里的QUEUE_CONNECTIONdatabase是否为这个值如果是sync则队列不会独立执行。5.5 扣费记录金额比单价多了一倍现象单价 1 元的接口一次调用扣了 2 元。原因接口配置里同时开了「资源包扣费」和「余额扣费」请求被两次扣费。具体说资源包扣费成功后系统又执行了一次余额扣费因为逻辑上把「资源包不可用」判断放在了「资源包扣费成功」之后导致重复扣。解决直接升级到 1.2.0这个版本修了特定值扣费逻辑后这类重复扣费基本绝迹。如果还出现检查接口配置里是否把「资源包扣费」和「余额扣费」两个开关同时开启通常只开一个。6. 进阶API 文档在线编辑与扣费规则的验证方法系统自带 API 文档在线编辑和代码在线编辑功能。文档编辑器基于 summernote直接嵌在后台可以加说明、示例请求、响应参数表。代码编辑器则允许直接修改接口的接入示例代码PHP、Python、JS 三种语言改完即时生效。这个功能的实际价值是省掉「文档维护→部署→同步」的环节对一个人维护多个 API 的场景非常省事。但要注意权限控制给编辑权限的角色只有超级管理员普通管理员只能查看。如果你要给某个同事开放编辑权需要在「角色管理」里重新分配默认角色不含这个权限。我个人建议保持默认设置因为在线编辑直接改的是对外展示的代码和文档一旦有人误操作改了计费示例代码调用方会照着错的示例接排查成本极高。最后给一套我自己验证计费规则是否生效的完整动作每次都走一遍# 1. 在后台创建测试用户充值 10 元 # 2. 创建测试接口单价 2 元/次计费类型设为余额扣费 # 3. 用测试用户的 key 调用接口 5 次 # 4. 查看扣费流水确认扣费金额 2 × 5 10 元且余额为 0 # 5. 再调用第 6 次确认返回余额不足错误 # 6. 把第 1 步改为充值 9.9 元重复 2-5验证小数金额不会四舍五入成整数扣费 # 7. 到用户中心查看资源包剩余额度确认数值与流水记录一致这套验证看起来简单但几乎每次改完扣费逻辑都能查出点东西来——要么是余额判断边界差一分钱要么是资源包余量显示和实际不符。从那以后我每次改完计费规则都强制自己走一遍测试接口 → 查扣费流水 → 看资源包快照的流程这套流程救了我至少三次对账事故。希望帮到你。本文还有配套的精品资源点击获取