简介:这是一套基于PHP开发的借贷公司整站源码,面向需要快速搭建网贷平台或二次开发借贷系统的开发者与运维人员。源码由得得系统改编而来,经实际测试可正常运行,覆盖用户注册、信用评估、借款申请、还款计划、逾期处理等核心借贷流程,并支持在线审批、合同签署与支付接口集成等网贷业务场景。压缩包为rar格式,内含借贷网整站源码,整体约11.34MB,包含前端HTML、CSS与JavaScript界面文件、后端PHP业务脚本、数据库SQL结构以及支付、短信等配置文件,前后端与数据层配套齐全,便于直接部署或按需定制。目前已有2534人学习下载,适合希望快速验证业务逻辑、研究借贷系统架构或进行功能扩展的开发者参考使用。
1. 从一套 PHP 借贷源码拆起:谁在用它、能跑通什么
手里这套 PHP 借贷源码,第一次打开目录时我数了下,大概两百多个文件,核心逻辑集中在application和extend两个目录里。它不是那种只放几张页面的演示壳子,而是把借款申请、授信审核、放款记账、还款计划、逾期计息这几条主链路都串起来了。适合谁?一是想研究消费信贷业务系统怎么分层的人,二是需要一套能本地跑通、能改业务流程的二次开发底座的人,三是接私活时要快速搭个可演示环境的人。我见过太多人拿到源码直接扔进宝塔,结果卡在伪静态和数据库导入上,这篇就把我从解压到跑通、再到改一个业务参数的完整路径写清楚,顺带把几个必踩的坑标出来。
2. 环境与依赖:PHP 版本、扩展和数据库怎么配才不翻车
2.1 先看框架底子,再决定 PHP 版本
这套源码用的是 ThinkPHP 5.1 那套结构,目录里有thinkphp文件夹,入口文件在public/index.php。ThinkPHP 5.1 对 PHP 版本比较挑,7.1 到 7.3 最稳,7.4 也能跑但个别地方会报implode参数顺序的 deprecated 警告,8.0 以上直接白屏。我一般先用php -v确认版本,不对就切。
# 查看当前 PHP 版本 php -v # 如果用的是宝塔,切换版本后记得重启 PHP-FPM /etc/init.d/php-fpm-73 restart逻辑说明:ThinkPHP 5.1 的容器和门面大量用了反射和call_user_func_array,PHP 8 对参数类型检查更严,老代码里没写类型的地方容易触发致命错误。参数上,php-fpm-73里的73就是版本号,换成你实际装的版本。
2.2 扩展清单:少一个都跑不起来
这套借贷源码依赖的扩展不算多,但有几个是硬性的。我列个表,装之前对着php -m过一遍。
| 扩展名 | 用途 | 缺失时的典型报错 |
|---|---|---|
| pdo_mysql | 数据库连接 | could not find driver |
| mbstring | 中文处理 | 验证码乱码、字符串截断 |
| curl | 短信/支付接口调用 | 接口请求超时无返回 |
| openssl | 加密与签名 | 支付回调验签失败 |
| bcmath | 金额高精度计算 | 利息算出来带一长串小数 |
| fileinfo | 上传文件类型检测 | 实名认证图片上传被拒 |
装扩展的命令按系统来,Debian 系一般是apt install php7.3-bcmath,CentOS 系用yum install php73-php-bcmath。装完php -m | grep bcmath确认一下。
2.3 数据库导入:别用 Navicat 直接拖
源码包里一般有个sql目录,里面是.sql文件。我习惯用命令行导入,因为 Navicat 有时候会把utf8mb4的排序规则改掉,导致后面中文乱码。
# 先建库,字符集必须指定 utf8mb4 mysql -uroot -p -e "CREATE DATABASE loan_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" # 再导入,注意路径换成你实际的 sql 文件位置 mysql -uroot -p loan_db < /www/wwwroot/loan/sql/loan_db.sql逻辑说明:utf8mb4_general_ci是兼容性最好的排序规则,utf8mb4_unicode_ci在某些 MySQL 5.6 上会有索引长度问题。参数上,loan_db是库名,你可以改,但改完要同步改config/database.php里的database值。
提示:导入前先看 sql 文件头部有没有
CREATE DATABASE语句,有的话把那一行删掉,否则会覆盖你刚建的库配置。
3. 核心链路拆解:借款申请到还款计划是怎么算出来的
3.1 借款申请的数据流与状态机
从用户点「立即借款」到生成一条loan_order记录,中间经过控制器、服务层、模型三层。我顺着代码走了一遍,核心状态流转是这样的:0 待审核 → 1 审核通过 → 2 已放款 → 3 还款中 → 4 已结清 → 5 逾期。状态值存在loan_order.status字段里,每次变更都会往loan_order_log插一条流水。
// application/api/controller/Loan.php 里的申请方法简化版 public function apply() { $data = input('post.'); // 参数校验:借款金额、期限、用途必填 $validate = validate('LoanApply'); if (!$validate->check($data)) { return json(['code' => 400, 'msg' => $validate->getError()]); } // 调用服务层,传入用户ID和申请数据 $result = LoanService::createOrder($this->uid, $data); return json($result); }逻辑说明:input('post.')拿全部 POST 参数,validate('LoanApply')对应application/api/validate/LoanApply.php里的规则。参数上,$this->uid是从 token 解析出来的用户 ID,别直接信前端传的user_id,否则就是越权漏洞。
3.2 还款计划生成:等额本息和先息后本两种算法
这套源码里还款方式支持两种,在extend/LoanCalculator.php里。等额本息用bcmath算,先息后本简单些。我贴一段等额本息的月供计算:
// 等额本息月供公式:M = P * r * (1+r)^n / ((1+r)^n - 1) public static function equalInstallment($principal, $annualRate, $months) { $monthRate = bcdiv($annualRate, 12, 6); // 月利率,保留6位小数 $pow = bcpow(bcadd(1, $monthRate, 6), $months, 6); // (1+r)^n $numerator = bcmul(bcmul($principal, $monthRate, 6), $pow, 6); $denominator = bcsub($pow, 1, 6); return bcdiv($numerator, $denominator, 2); // 月供保留2位 }逻辑说明:bcdiv、bcpow、bcmul都是 bcmath 的函数,第三个参数是小数位数。参数上,$annualRate传年化利率,比如 0.12 表示 12%,$months是期数。注意bcpow的指数参数必须是字符串或整数,传浮点会报错。
3.3 逾期计息与罚息:日利率怎么配
逾期后的罚息在config/loan.php里配,我一般会看这几个参数:
// config/loan.php 部分配置 return [ 'overdue_day_rate' => 0.0005, // 逾期日利率 0.05% 'overdue_penalty' => 0.05, // 罚息系数,在日利率基础上乘 'grace_days' => 3, // 宽限期天数,宽限期内不算逾期 'max_overdue_days' => 90, // 超过90天转坏账 ];逻辑说明:实际逾期费用 = 剩余本金 ×overdue_day_rate×overdue_penalty× 逾期天数。grace_days是给用户的缓冲,第 4 天才开始计罚息。参数上,overdue_day_rate别设太高,超过 0.001 在演示环境里容易让用户直接放弃还款。
注意:改完配置文件后,ThinkPHP 5.1 不会自动热加载,需要清一下缓存目录
runtime/cache,否则读的还是旧值。
4. 避坑排查:从白屏到支付回调失败的五个血泪记录
4.1 现象:首页白屏,日志里只有一行ERR
原因:runtime目录没有写权限,ThinkPHP 写不了日志和缓存,直接静默失败。解决:chmod -R 755 runtime,如果还不行就chown -R www:www runtime,www换成你实际的运行用户。
4.2 现象:登录后跳回首页,token 像没生效
原因:config/session.php里session的prefix和前端存的 key 对不上,或者domain配成了localhost但实际用 IP 访问。解决:把domain留空,prefix改成和前端localStorage里一致的字符串,比如loan_token。
4.3 现象:支付回调一直提示验签失败
原因:extend/pay/下的签名类里,signType默认是MD5,但实际支付渠道用的是HMAC-SHA256。解决:找到PayNotify.php,把signType改成HMAC-SHA256,同时确认key和商户后台配的一致。这个坑我调了两个小时,最后是抓包对比签名串才定位到。
4.4 现象:借款金额输入 1000,数据库里存成 999.99
原因:金额字段用了float类型,浮点精度丢失。解决:把loan_order.amount字段改成decimal(12,2),代码里所有金额运算走 bcmath,别用+-*/。
4.5 现象:后台审核通过后,用户端状态没变
原因:状态更新写在了事务里,但事务提交前发了消息队列,队列消费时读不到未提交的数据。解决:把发队列的操作挪到Db::commit()之后,或者用Db::afterCommit回调。
5. 二次开发技巧:改利率、加字段、接短信的稳妥做法
5.1 改利率别直接动数据库
利率配置在config/loan.php里,但有些版本会把它存到system_config表。我一般先grep -r "overdue_day_rate" application/ extend/ config/搜一遍,确认读的是哪个源。如果读表,改表后要清runtime/cache下的配置缓存文件。
5.2 加一个「紧急联系人」字段的完整路径
假设要在借款申请里加emergency_contact字段,需要动四个地方:一是loan_order表加字段ALTER TABLE loan_order ADD emergency_contact VARCHAR(50) DEFAULT '';;二是application/api/validate/LoanApply.php加验证规则;三是application/api/controller/Loan.php的apply方法里把字段塞进$data;四是前端表单加输入框。少一处都会导致数据存不进去或验证失败。
5.3 短信接口替换:别改核心类,用配置覆盖
源码里短信发送一般在extend/sms/Sms.php,我习惯不改这个文件,而是在config/sms.php里加一个driver配置,然后写个新的驱动类继承原类。这样升级源码时不会冲突。
// config/sms.php return [ 'driver' => 'aliyun', // 默认改成你用的渠道 'sign' => '你的签名', 'template' => [ 'verify' => 'SMS_123456', ], ];逻辑说明:driver决定加载哪个驱动类,template里存模板 ID。参数上,sign必须和短信后台审核通过的一致,否则会报SIGNATURE_NOT_MATCH。
5.4 验证改动是否生效的笨办法
改完任何配置或代码,我习惯先tail -f runtime/log/下的当日日志,再走一遍完整流程:注册 → 申请 → 审核 → 放款 → 还款。每一步看日志里有没有SQL报错或ERROR级别记录。这个习惯帮我省了无数次「以为改好了其实没生效」的后悔药。
提示:演示环境里把
app_debug设为true,能看到详细错误页;上线前记得改回false,否则会暴露路径和 SQL。
这套 PHP 借贷源码的骨架不算复杂,但细节都在配置和状态流转里。我每次搭新环境,都会先把runtime权限、数据库字符集、bcmath 扩展这三样过一遍,再走一遍完整借款流程。从那以后我每次拿到类似源码,都强制先跑通最小闭环再动业务代码,希望帮到你。
本文还有配套的精品资源,点击获取