彩虹易支付接入USDT TRC20收款:PHP插件开发与链上回调实现

📅 发布时间:2026/9/15 11:39:22
彩虹易支付接入USDT TRC20收款:PHP插件开发与链上回调实现
简介原版彩虹易支付虽然扩展性强但默认不集成加密货币通道。面向使用该系统的站长与开发者这款USDT-TRC20收款插件可直接补足这一缺口接入后客户以TRC20网络支付USDT资金直接进入个人钱包不经过任何第三方通道适合个人或小微站点低成本启用加密支付。资源包采用RAR压缩共5个文件以3个PHP脚本为核心分别承担支付方式注册、订单支付处理和定时链上查询功能另含1份Markdown配置说明和1份License文件整体体积仅7KB部署简单目录结构清晰。当前已有758人学习浏览尤其适合具备一定PHP基础的易支付使用者作为参考内容包含可运行的插件源码、挂载说明与回调逻辑梳理既能帮助理解易支付插件扩展机制也能为二次开发或生产部署提供轻量模板。1. 彩虹易支付的 USDTTRC20收款绕不开的两个问题做资源站或出海业务的人大概率遇到过这种尴尬彩虹易支付接好了支付宝、微信但客户里总有那么一批人只愿意打 USDT。临时去接第三方 USDT 通道手续费高不说资金还要在别人那过一手结算周期拖三天都算快。这个插件的做法是把 USDTTRC20直接注册成易支付的一种新支付方式顾客扫码后链上转账钱秒到你自己的钱包你不需要打开交易所或钱包 App 去对账后台订单状态自己更新。它的技术要点是两件事一是搞懂易支付的插件接口怎么扩展二是把 TRC20 链上交易和传统回调逻辑对接起来。看完这篇你不仅能装上还能知道链上确认、通知回调这些环节在哪调、断在哪。2. 支付插件与 TRC20 链上监听的回调链路2.1 彩虹易支付的插件没有想象中复杂彩虹易支付原版PayJS 那套分支本身就预留了第三方支付方式的扩展点。所谓的「插件」就是往plugins目录丢一个文件夹文件夹里放一个继承某个支付类、实现统一接口的 PHP 文件。支付流程里易支付核心会把订单参数交给这个插件类的pay()方法由它生成跳转链接或二维码用户付款后再由插件类的notify()或callback()方法接收第三方支付平台的异步通知改订单状态。这个 USDT 插件走的也是同一套机制只是它把「第三方支付平台」换成了「TRC20 链上转账」。usdt_plugin.php这个类注册后核心代码在创建订单时会调它的getQrcode()或类似的生成方法返回一个收款的 TRC20 地址而订单是否支付成功则由cron.php定时去链上扫交易来确认。所以它不依赖外部支付网关这也是它能「直接到钱包」的根本原因整个资金链路里只有你自己的钱包地址。2.2 链上交易到订单回调的完整链路一张订单从创建到完成的完整时序大概是这样的用户在商城下单易支付核心生成订单。核心调用插件生成收款信息页面展示一个 TRC20 地址或二维码。用户用任意支持 TRC20 的钱包往这个地址转 USDT。链上广播后约 1 到 2 分钟TRON 网络打包出块交易进入「已确认」状态。cron.php在下一个执行周期请求 TRONSCAN 或 TRON Grid 接口查询该地址最近的 USDT 转账。匹配到对应订单、校验金额无误后调用易支付核心的订单完成方法。关键在最后一步。易支付核心标注订单完成通常通过POST参数把订单号和金额传给某个固定的回调 URL或者直接调用本地函数改库。写这类插件时你要在每个关键节点输出日志因为链上转账具备不可逆性——订单漏标意味着收到币但客户拿不到东西所以轮询和金额校验要格外保守。2.3 确认数与安全边界TRC20 的 USDT 转账在 TRON 网络上的确认时间和确认数有关。链上出现一笔交易后如果只等一个区块确认理论上存在极小的重组风险。虽然 TRON 的 DPoS 机制下单区块确认稳定性较高但插件设计里通常会做两个安全阀等待至少 2 到 19 个区块确认具体看插件配置通常可以自己调确认数。金额校验精确到小数位。TRC20 的 USDT 是 6 位精度而主流 PHP 的浮点数直接比较会出问题必须用整数比较或bccomp()对比。2.4 钱包地址的本地派生「直接到自己的钱包」意味着钱包地址是本地的——收款地址要么来自你自己的 TRON 私钥生成的地址要么是某个导入的助记词地址。多数插件在cron.php或配置页里让你填私钥或助记词然后用tron-php库生成地址。如果你不想把私钥写在服务器配置里也有另一种折衷方案在配置页填一个观察地址你交易所或收款钱包的地址插件只做链上监控不碰私钥。这样安全边界更清晰但也意味着插件无法做什么签名操作一般也不需要。3. 安装与配置把 USDT 插件挂到易支付3.1 目录结构与命名拿到epay_usdt-main解压后你会看到这些文件epay_usdt-main/ ├── pay.php ├── cron.php ├── usdt_plugin.php ├── LICENSE └── README.md安装的第一步不是直接传上去而是把epay_usdt-main重命名为usdt然后整体上传到易支付站点的plugins目录。命名决定了支付方式在系统内部的调用值所以plugins目录下这个文件夹名必须是usdt。# 在服务器站点根目录执行 mv epay_usdt-main usdt cp -r usdt /www/wwwroot/你的域名/plugins/ chown -R www:www /www/wwwroot/你的域名/plugins/usdt chmod -R 755 /www/wwwroot/你的域名/plugins/usdtchown和chmod是很多 PHP 项目最容易踩的坑如果cron.php对日志文件或数据缓存没有写权限后台配置保存后会出现「保存成功但定时任务一直跑不起来」的怪现象日志文件根本写不进去。另外上传时注意隐藏文件.git目录或README.md里的换行符可能导致部分环境下的路径解析异常。3.2 后台添加支付方式登录易支付后台找到「支付方式」或「支付接口配置」点击新增配置项填写内容说明支付方式名称USDT 或 稳定币收款前台展示用随意调用值usdt必须和插件目录名一致支持设备PC Mobile两种端都勾上商户号留空或填你的 TRON 地址取决于插件实现商户密钥留空链上收款不需要请求方式标准跳转或返回看插件README说明状态启用必须启用设置完保存后去网站前台测试下单确认支付方式列表里出现了 USDT 图标或名称。如果没出现优先检查调用值是否填了usdt——大小写和空格都会被当成另一个支付方式。3.3 定时任务与队列因为链上交易只能靠轮询发现cron.php必须被系统定时器周期性执行。常见做法是每 30 秒到 60 秒跑一次频率太低会导致订单支付后迟迟不回调太高会让服务器频繁请求 TRON 接口然后被限流。*/1 * * * * cd /www/wwwroot/你的域名/plugins/usdt php cron.php /www/wwwroot/你的域名/plugins/usdt/cron.log 21这里的运行用户要和站点运行用户一致绝大多数 PHP 站点是www。把输出重定向到日志文件有个好处链上接口偶发超时或 JSON 解析失败时你翻日志能看到是哪一个环节出问题而不是像很多站点那样傻等订单状态。3.4 收款地址的配置边界许多版本支持两种收款模式统一地址模式所有订单都显示同一个 USDT 地址靠「金额 自定义备注」来区分订单。独立地址模式每个订单生成一个新地址靠地址区分订单。如果你用的是独立地址模式usdt_plugin.php里大概率有生成钱包地址的代码每次下单都会调用一次tron-php的generateAddress()。这样安全性更高但需要每天备份地址库否则换服务器后旧地址的私钥就丢了历史订单无法对账。多数个人站长建议用统一地址模式省心且不容易出数据事故。4. 核心代码逻辑与参数调优4.1 usdt_plugin.php 的类实现这个文件是整个插件能否被易支付识别的核心。典型的类结构如下class epay_usdt { public function __construct($config) { $this-config $config; } public function pay($order) { $address $this-getUsdtAddress($order[pid]); $amount number_format($order[money], 6, ., ); $param [ address $address, amount $amount, orderid $order[trade_no], note USDT TRC20 收款 ]; return [type qrcode, data $param]; } public function notify($order) { // 查询链上交易是否到账 $confirmed $this-checkTrc20Confirmed($order[trade_no]); if ($confirmed) { return [status success, message ok]; } return [status fail, message pending]; } }pay()方法返回qrcode类型易支付前台核心会把这个data结构渲染为二维码。重点注意amount的处理number_format把金额格式化为 6 位小数这是为了和 TRC20 的 6 位精度对齐避免后面金额比对时出现浮点误差。notify()里并不直接改订单状态而是返回一个统一的成功标记因为真正改状态的动作在易支付核心内部完成。4.2 pay.php 的支付请求组装pay.php是插件暴露给易支付核心的接收入口。它会解析订单参数生成带收款地址和金额的二维码信息。这里有一个常见坑TRC20 地址是以T开头的 34 位 Base58 字符串很多插件在没有引入外部解码库时只用正则去校验if (!preg_match(/^T[1-9A-HJ-NP-Za-km-z]{33}$/, $address)) { throw new Exception(无效的 TRC20 地址); }这个正则可作为第一道防线但要注意它只保证了「看起来像一个地址」不能保证「这个地址在 TRON 网络上真实存在」。更稳妥的做法是调用 TRONSCAN 的验证接口$ch curl_init(); curl_setopt_array($ch, [ CURLOPT_URL https://apilist.tronscanapi.com/api/account?address . $address, CURLOPT_RETURNTRANSFER true, CURLOPT_TIMEOUT 5, ]); $response curl_exec($ch); curl_close($ch); $account json_decode($response, true); if (empty($account[address])) { throw new Exception(TRON 地址不存在); }这里的CURLOPT_TIMEOUT设为 5 秒比较合适。TRONSCAN 的公共 API 偶尔响应慢超时过短容易误报地址无效过长又会让下单页面卡住。如果插件支持填写多个钱包地址你还可以在这里做轮询切换——查每个地址的最近交易把流量分散到不同地址上。4.3 cron.php 的扫块与订单匹配cron.php的工作是找到「已付款但未标记完成」的订单。常见的实现是查数据库里交易状态为 pending 的订单然后逐个去链上校验。它的核心函数通常是这样的逻辑SELECT trade_no, money, addtime FROM epay_order WHERE status 0 AND type usdt AND addtime UNIX_TIMESTAMP(NOW() - INTERVAL 30 MINUTE);查出最近的未完成订单后调用apilist.tronscanapi.com/api/filter/trc20/transfers接口按收款地址过滤最近的 USDT 转账记录curl -G https://apilist.tronscanapi.com/api/filter/trc20/transfers \ --data limit20 \ --data start0 \ --data relatedAddress你的钱包地址 \ --data contract_addressTR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t \ --data token_nameUSDT \ --data direction0参数说明relatedAddress收款钱包地址必须和订单里的地址一致。contract_addressTRC20 USDT 的合约地址固定是TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t写错的话查不到任何数据。direction0只查转入转账方向的账户是收款地址。limit和start分页参数建议limit20就够用扫交易时不是扫全量只扫近 30 分钟的新增记录。拿到转账记录后用金额和订单号去匹配。匹配的核心逻辑建议这样写foreach ($transactions as $tx) { $amount $tx[quant]; // TRONSCAN 返回值是 6 位整数 $decimals 6; $realAmount $amount / pow(10, $decimals); foreach ($pendingOrders as $order) { if (bccomp((string)$realAmount, (string)$order[money], 6) 0) { // 标记订单为已支付 $order-update([status 1, trade_no $order[trade_no]]); } } }关键点在于bccomp。PHP 的浮点数0.1 0.2 0.3是false如果你直接用比较金额会出现「客户转了 10 USDT插件却说金额不匹配」的诡异问题。bccomp把两个金额当字符串比较就不会有二进制浮点误差。4.4 参数调优建议参数默认值建议调整方向扫描间隔60 秒带宽裕余缩短到 30 秒用户体验更接近实时到账确认区块数2 到 19小额单 2 个区块即可大额超过 500 USDT 建议 19 个区块再确认金额精度6不要改改了和链上对不上TRONSCAN 超时5 秒频繁出现超时时调到 10 秒但会拖慢下单页面订单过期时间30 分钟链上超时未付款的订单状态置为已取消确认区块数是个权衡设大了安全性高但用户等得急设小了秒到但极端情况下可能遇到网络重组。TRON 是 DPoS 共识出块速度约 3 秒一个2 个区块确认大约 6 秒日常小额收款完全够用。5. 上线前的验证清单与两个高频坑5.1 用一笔小额转账跑通全链路上线前不要直接拿大额测试。从插件后台看下有没有「测试模式」或「模拟回调」按钮没有的话就自己转一笔比如 1.5 USDT带小数能顺带验证精度处理是否正常。测试时要盯三个位置下单页面二维码能不能正常渲染地址是不是你的钱包地址。链上浏览器在 TRONSCAN 上搜该地址确认这笔交易已经出现且tokenName是 USDT。后台订单列表订单状态在 30 到 90 秒内取决于你的 cron 间隔变成「已支付」。如果订单状态一直不变优先看cron.php的日志输出。多数插件的cron.php会记录「最近一次执行时间」和「最近一次查询到的交易数」这两个值能快速定位问题日志里没有「最近一次执行时间」说明 cron 没跑起来检查系统定时器里的 PHP 路径和运行用户。有执行时间但查到的交易数一直是 0说明链上查询接口挂了或contract_address填错。查到交易但匹配不到订单多半是金额精度问题检查日志里的$realAmount和订单金额的对比结果。5.2 坑一ERC20 地址冒充 TRC20很多用户会把以太坊上0x开头的地址或交易所充值页面的「网络选择」看错直接往 TRC20 收款地址发了一笔 ERC20 的 USDT。这个插件本身解决不了这个问题但你有两个补救手段在支付页明显位置标注「仅支持 TRC20 网络请勿使用 ERC20 或其他网络转账否则无法到账」。在usdt_plugin.php的支付接口生成二维码时附带一个networktrc20的备注信息这样即使用户扫码后误选网络至少有个参照。5.3 坑二cron 重复标记订单轮询机制的天然风险是同一瞬间跑两个cron.php进程把同一笔订单标记两次。虽然不会造成实际财产损失但订单表里可能出现重复的状态更新记录影响对账。防御做法是给订单加一个「处理中」状态锁UPDATE epay_order SET status 1, paytime NOW() WHERE trade_no 订单号 AND status 0;用UPDATE后检查受影响行数如果行数为 0 说明订单已经被其他进程处理过了放弃本次操作。这比先SELECT再UPDATE安全得多因为它是原子操作。最后提一个运维细节如果你把确认区块数设得比较大比如 19用户看到「已支付」时的实际到账时间会延长到 1 分钟左右。此时不要在前台提示「支付失败」而是提示「支付确认中」否则用户会以为钱丢了转头去提工单。确认中状态的订单建议在后台单独一个列表展示方便你自己盯。本文还有配套的精品资源点击获取