从0到1:x-ui面板集成支付系统实现节点自动化售卖
从0到1:x-ui面板集成支付系统实现节点自动化售卖
【免费下载链接】x-ui 支持多协议多用户的 xray 面板 项目地址: https://gitcode.com/gh_mirrors/xu/x-ui
引言:节点运营的痛点与解决方案
你是否还在为x-ui面板的节点手动开通、流量超限提醒、到期续费等问题烦恼?作为节点服务提供商,当用户量增长到一定规模后,纯人工管理不仅效率低下,还容易出错。本文将详细介绍如何通过第三方支付系统与x-ui面板的深度集成,实现节点服务的自动化售卖与管理,彻底解放你的双手。
读完本文后,你将能够:
- 理解x-ui面板的数据模型与扩展点
- 设计支付系统与x-ui的对接方案
- 实现节点自动开通、流量控制与到期管理
- 构建完整的用户支付-开通-使用闭环流程
一、x-ui面板数据模型解析
1.1 核心数据结构
x-ui面板的核心数据模型主要定义在database/model/model.go文件中,其中与节点管理相关的主要有User和Inbound两个结构体:
// 用户模型
type User struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Username string `json:"username"`
Password string `json:"password"`
}
// 节点模型
type Inbound struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
UserId int `json:"-"` // 关联用户ID
Up int64 `json:"up" form:"up"` // 上传流量
Down int64 `json:"down" form:"down"` // 下载流量
Total int64 `json:"total" form:"total"` // 总流量限制
Remark string `json:"remark" form:"remark"` // 备注信息
Enable bool `json:"enable" form:"enable"` // 是否启用
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` // 到期时间戳
// 配置部分
Listen string `json:"listen" form:"listen"`
Port int `json:"port" form:"port" gorm:"unique"`
Protocol Protocol `json:"protocol" form:"protocol"`
Settings string `json:"settings" form:"settings"`
StreamSettings string `json:"streamSettings" form:"streamSettings"`
Tag string `json:"tag" form:"tag" gorm:"unique"`
Sniffing string `json:"sniffing" form:"sniffing"`
}
1.2 关键字段分析
对于支付系统集成而言,以下字段尤为重要:
| 字段名 | 作用 | 支付集成关联性 |
|---|---|---|
| UserId | 关联用户ID | 用于绑定购买用户 |
| Total | 总流量限制 | 控制不同套餐的流量额度 |
| ExpiryTime | 到期时间戳 | 实现节点有效期管理 |
| Enable | 是否启用 | 控制节点开关状态 |
| Up/Down | 流量统计 | 用于超限检测 |
1.3 节点服务接口
x-ui提供了InboundService服务类(位于web/service/inbound.go),封装了节点管理的核心操作:
type InboundService struct {}
// 关键方法摘要
func (s *InboundService) GetInbounds(userId int) ([]*model.Inbound, error) {}
func (s *InboundService) AddInbound(inbound *model.Inbound) error {}
func (s *InboundService) UpdateInbound(inbound *model.Inbound) error {}
func (s *InboundService) DisableInvalidInbounds() (int64, error) {}
其中DisableInvalidInbounds方法会自动禁用流量超限或已过期的节点,这为支付系统的到期管理提供了天然支持。
二、支付系统集成方案设计
2.1 系统架构设计
支付系统与x-ui的集成可采用以下架构:
2.2 数据流程设计
完整的数据流程包含以下步骤:
- 用户下单:用户在销售页面选择套餐并完成支付
- 支付回调:支付系统向我们的API服务发送支付成功通知
- 订单处理:API服务验证回调合法性,解析订单信息
- 节点创建:根据套餐信息创建或更新对应的Inbound记录
- 配置生效:触发x-ui配置更新,使新节点生效
- 通知用户:通过邮件或其他方式将节点信息发送给用户
2.3 数据表扩展设计
为支持支付功能,我们需要扩展以下数据表:
-- 产品套餐表
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL COMMENT '套餐名称',
description TEXT COMMENT '套餐描述',
price DECIMAL(10,2) NOT NULL COMMENT '价格',
traffic_limit BIGINT NOT NULL COMMENT '流量限制(MB)',
duration_days INT NOT NULL COMMENT '有效期(天)',
protocol VARCHAR(20) NOT NULL COMMENT '支持协议',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 订单表
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(50) UNIQUE NOT NULL COMMENT '订单编号',
user_id INT NOT NULL COMMENT '用户ID',
product_id INT NOT NULL COMMENT '产品ID',
amount DECIMAL(10,2) NOT NULL COMMENT '订单金额',
status TINYINT NOT NULL COMMENT '状态:0-待支付,1-已支付,2-已取消',
payment_time DATETIME COMMENT '支付时间',
inbound_id INT COMMENT '关联节点ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
三、核心功能实现
3.1 支付回调API开发
首先,我们需要在x-ui的web服务中添加支付回调处理接口。创建web/controller/payment.go文件:
package controller
import (
"net/http"
"x-ui/database"
"x-ui/database/model"
"x-ui/web/service"
"github.com/gin-gonic/gin"
)
type PaymentController struct {
inboundService service.InboundService
// 其他依赖...
}
// 支付回调处理
func (c *PaymentController) HandlePaymentCallback(ctx *gin.Context) {
// 1. 解析回调参数
var callbackData PaymentCallbackData
if err := ctx.ShouldBindJSON(&callbackData); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
return
}
// 2. 验证签名
if !verifyPaymentSignature(callbackData) {
ctx.JSON(http.StatusForbidden, gin.H{"error": "签名验证失败"})
return
}
// 3. 查询订单信息
order := getOrderByNo(callbackData.OrderNo)
if order == nil || order.Status != 0 {
ctx.JSON(http.StatusOK, gin.H{"status": "success"}) // 防止重复处理
return
}
// 4. 创建/更新节点
inbound := c.createInboundForOrder(order)
// 5. 更新订单状态
updateOrderStatus(order.Id, inbound.Id)
ctx.JSON(http.StatusOK, gin.H{"status": "success"})
}
// 根据订单创建节点
func (c *PaymentController) createInboundForOrder(order *Order) *model.Inbound {
// 获取产品信息
product := getProductById(order.ProductId)
// 创建节点
inbound := &model.Inbound{
UserId: order.UserId,
Total: product.TrafficLimit * 1024 * 1024, // 转换为字节
Remark: "Auto-created by payment: " + order.OrderNo,
Enable: true,
ExpiryTime: calculateExpiryTime(product.DurationDays),
Port: getAvailablePort(),
Protocol: model.Protocol(product.Protocol),
// 其他必要配置...
}
// 保存节点
c.inboundService.AddInbound(inbound)
return inbound
}
3.2 节点自动开通实现
节点开通的核心在于正确设置Inbound结构体并调用x-ui的服务方法:
// 获取可用端口
func getAvailablePort() int {
// 实现逻辑:查找一个未被占用的端口
// 可通过查询Inbound表的port字段,找到一个未使用的端口
}
// 计算到期时间戳
func calculateExpiryTime(days int) int64 {
return time.Now().AddDate(0, 0, days).Unix() * 1000
}
// 更新x-ui配置
func updateXrayConfig() error {
// 调用x-ui的配置更新逻辑
xrayService := service.XrayService{}
return xrayService.Restart()
}
3.3 流量与到期管理
x-ui已内置节点有效性检查机制,我们只需确保正确设置相关字段即可:
// 在InboundService中已存在的方法
func (s *InboundService) DisableInvalidInbounds() (int64, error) {
db := database.GetDB()
now := time.Now().Unix() * 1000
// 禁用流量超限或已过期的节点
result := db.Model(model.Inbound{}).
Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true).
Update("enable", false)
return result.RowsAffected, result.Error
}
我们可以通过定时任务定期执行此方法,确保及时禁用无效节点:
// 添加到定时任务
func init() {
// 每小时检查一次
cron.AddFunc("0 * * * *", func() {
service.InboundService{}.DisableInvalidInbounds()
})
}
四、前端界面扩展
4.1 用户中心页面
在x-ui的web界面中添加用户中心页面,展示用户的节点信息和订单历史:
<!-- web/html/xui/user_center.html -->
<div class="user-center">
<div class="node-list">
<h2>我的节点</h2>
<table class="table">
<thead>
<tr>
<th>节点名称</th>
<th>协议</th>
<th>端口</th>
<th>已用流量</th>
<th>剩余流量</th>
<th>到期时间</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 动态生成节点列表 -->
<tr v-for="node in nodes" :key="node.id">
<td>{{ node.remark }}</td>
<td>{{ node.protocol }}</td>
<td>{{ node.port }}</td>
<td>{{ formatTraffic(node.up + node.down) }}</td>
<td>{{ formatTraffic(node.total - (node.up + node.down)) }}</td>
<td>{{ formatTime(node.expiryTime) }}</td>
<td :class="node.enable ? 'text-success' : 'text-danger'">
{{ node.enable ? '运行中' : '已停用' }}
</td>
<td>
<button @click="showConfig(node)" class="btn btn-sm btn-primary">查看配置</button>
<button @click="renewNode(node)" class="btn btn-sm btn-success" v-if="!node.enable">续费</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="order-history">
<h2>订单历史</h2>
<!-- 订单列表 -->
</div>
</div>
4.2 流量统计与可视化
使用Chart.js添加流量统计图表(需引入国内CDN):
<!-- 在页面中添加图表容器 -->
<div class="traffic-chart">
<canvas id="trafficChart"></canvas>
</div>
<!-- 引入Chart.js (国内CDN) -->
<script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script>
// 初始化流量图表
function initTrafficChart(trafficData) {
const ctx = document.getElementById('trafficChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: trafficData.dates,
datasets: [
{
label: '上传流量 (MB)',
data: trafficData.upData,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
},
{
label: '下载流量 (MB)',
data: trafficData.downData,
borderColor: 'rgb(255, 99, 132)',
tension: 0.1
}
]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
</script>
五、安全与异常处理
5.1 支付回调安全验证
支付回调必须进行严格的安全验证,防止伪造请求:
// 验证支付签名
func verifyPaymentSignature(data PaymentCallbackData) bool {
// 1. 按支付平台要求的顺序拼接参数
params := []string{
data.MerchantNo,
data.OrderNo,
data.Amount,
// 其他必要参数...
}
joined := strings.Join(params, "|")
// 2. 使用商户密钥计算签名
h := hmac.New(sha256.New, []byte(merchantSecret))
h.Write([]byte(joined))
calculatedSign := hex.EncodeToString(h.Sum(nil))
// 3. 与回调数据中的签名比较
return calculatedSign == data.Signature
}
5.2 并发控制与幂等性处理
为防止重复处理支付回调,需要实现幂等性控制:
// 使用Redis实现分布式锁
func acquireCallbackLock(orderNo string) bool {
// 尝试获取锁,设置10秒过期
result, _ := redisClient.SetNX(
"payment:lock:"+orderNo,
"1",
10*time.Second,
).Result()
return result
}
// 释放锁
func releaseCallbackLock(orderNo string) {
redisClient.Del("payment:lock:" + orderNo)
}
// 在回调处理中使用锁
func (c *PaymentController) HandlePaymentCallback(ctx *gin.Context) {
// ...解析参数
// 获取锁
if !acquireCallbackLock(callbackData.OrderNo) {
ctx.JSON(http.StatusOK, gin.H{"status": "success"}) // 已处理,直接返回成功
return
}
defer releaseCallbackLock(callbackData.OrderNo) // 确保释放锁
// ...处理订单
}
5.3 异常情况处理
针对可能出现的异常情况,需要有相应的处理机制:
// 订单处理中的异常捕获
func (c *PaymentController) processOrder(order *Order) {
defer func() {
if r := recover(); r != nil {
// 记录错误日志
log.Printf("处理订单异常: %v, 订单号: %s", r, order.OrderNo)
// 发送告警通知
sendAlertEmail("订单处理失败", fmt.Sprintf("订单号: %s, 错误: %v", order.OrderNo, r))
// 可能需要人工干预的订单标记为异常
markOrderAsException(order.Id)
}
}()
// 订单处理逻辑...
}
六、部署与测试
6.1 部署架构
推荐的部署架构如下:
6.2 部署步骤
-
编译x-ui:
go build -o x-ui -
配置数据库:
# 导入初始SQL mysql -u root -p xui < sql/init.sql -
配置支付服务:
# 修改配置文件 vi config/payment.json # 启动服务 ./payment-service -
配置Nginx:
server { listen 443 ssl; server_name your.domain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; # 代理x-ui location / { proxy_pass http://127.0.0.1:54321; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 代理支付回调 location /api/payment/callback { proxy_pass http://127.0.0.1:8080; proxy_set_header Content-Type application/json; } }
6.3 测试流程
完整的测试流程应包括:
-
模拟支付测试:
# 使用curl模拟支付回调 curl -X POST https://your.domain.com/api/payment/callback \ -H "Content-Type: application/json" \ -d '{"order_no":"TEST123456","amount":"9.90","sign":"xxx..."}' -
节点创建验证:
- 检查数据库中是否创建了对应的Inbound记录
- 登录x-ui面板查看节点是否正常显示
- 测试节点是否可以正常连接
-
到期禁用测试:
- 修改测试节点的expiryTime为当前时间之前
- 执行DisableInvalidInbounds方法
- 验证节点是否被禁用
-
流量超限测试:
- 修改测试节点的total为较小值
- 通过工具产生流量使其超限
- 验证节点是否被禁用
七、总结与扩展
7.1 实现成果总结
通过本文介绍的方案,我们成功实现了x-ui面板与支付系统的集成,主要成果包括:
- 设计了完整的支付-开通闭环流程
- 实现了节点的自动创建与配置
- 开发了基于流量和时间的节点管理机制
- 添加了安全的支付回调处理
7.2 后续扩展方向
该集成方案还可以从以下几个方面进行扩展:
- 多支付渠道支持:集成更多支付方式,如支付宝、微信支付等
- 优惠券系统:添加折扣码、促销活动支持
- 多级分销系统:实现推广返佣功能
- 用户流量包:支持购买额外流量包
- 自动续费功能:实现节点服务的自动续费
7.3 最佳实践建议
在实际运营中,建议:
- 定期备份:定期备份x-ui的数据库,防止数据丢失
- 监控告警:对支付服务和x-ui服务进行监控,及时发现问题
- 流量统计:实现更详细的流量统计和分析,为运营决策提供数据支持
- 用户反馈:建立用户反馈渠道,持续优化服务
通过这套方案,你可以将x-ui从一个单纯的节点管理工具,转变为一个功能完善的节点销售平台,实现真正的自动化运营。
如果你觉得本文对你有帮助,请点赞、收藏并关注,下期我们将介绍如何实现x-ui的多语言支持和自定义主题开发。
【免费下载链接】x-ui 支持多协议多用户的 xray 面板 项目地址: https://gitcode.com/gh_mirrors/xu/x-ui
更多推荐
所有评论(0)