You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram订阅机器人集成USDT TRC20支付的技术难题求助

实现Telegram机器人集成USDT TRC20支付方案(无第三方支付网关)

1. 生成用户专属USDT TRC20地址

直接用Tron官方SDK(比如tronweb)生成独立地址对,每个用户发起支付请求时生成唯一地址,关联用户ID、应付金额、过期时间存入数据库(如MySQL/Redis)即可。

  • 代码示例(Node.js):
const TronWeb = require('tronweb');
const tronWeb = new TronWeb({
    fullHost: 'https://api.trongrid.io',
    headers: { "TRON-PRO-API-KEY": "你的TronGrid API密钥" }
});

// 生成用户专属地址并关联订单
async function generateUserPaymentAddress(userId, amountDue) {
    const account = await tronWeb.createAccount();
    // 存入数据库:userId, address=account.address.base58, privateKey=account.privateKey, amountDue, expiresAt=Date.now()+900000(15分钟过期), status='pending'
    return account.address.base58;
}
  • 核心:用户地址的私钥必须加密存储,后续归集转账要用到。

2. 支付状态校验

两种方案可选,按需选择:

方案A:定时轮询

用定时器定期扫描未完成订单,调用TronGrid API查询用户地址的USDT余额:

async function verifyPayment(userId) {
    const order = await db.query('SELECT * FROM payment_orders WHERE userId = ? AND status = "pending"', [userId]);
    if (!order) return;

    // USDT TRC20合约地址固定为TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
    const usdtBalance = await tronWeb.trx.getTokenBalance(order.address, 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
    const actualAmount = usdtBalance / 1e6; // 转换为USDT单位(6位小数)

    if (actualAmount >= order.amountDue) {
        // 标记支付完成,授予频道权限
        await db.query('UPDATE payment_orders SET status = "completed" WHERE id = ?', [order.id]);
        await telegramBot.addChatMember('你的私密频道ID', userId);
    } else if (Date.now() > order.expiresAt) {
        // 订单过期,标记失效
        await db.query('UPDATE payment_orders SET status = "expired" WHERE id = ?', [order.id]);
    }
}

// 每30秒轮询一次
setInterval(() => {
    db.query('SELECT userId FROM payment_orders WHERE status = "pending"').then(users => {
        users.forEach(user => verifyPayment(user.userId));
    });
}, 30000);

方案B:实时事件监听

通过TronGrid的WebSocket订阅用户地址的USDT转账事件,比轮询更高效:

const socket = tronWeb.eventServer.subscribe('transfer', {
    contract: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
    recipient: '用户地址'
});

socket.on('message', async (data) => {
    const userId = await db.query('SELECT userId FROM payment_orders WHERE address = ? AND status = "pending"', [data.result.to]);
    if (userId) {
        const amount = parseInt(data.result.value) / 1e6;
        const order = await db.query('SELECT amountDue FROM payment_orders WHERE userId = ?', [userId]);
        if (amount >= order.amountDue) {
            // 执行支付完成逻辑
        }
    }
});
  • 注意:校验时最好等待1-2个区块确认,避免链上交易回滚导致误判。

3. USDT归集到主地址

用户支付完成后,用用户地址的私钥签名转账交易,将USDT转到你的主地址:

async function collectUSDT(userAddress, userPrivateKey, mainAddress) {
    const usdtBalance = await tronWeb.trx.getTokenBalance(userAddress, 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
    if (usdtBalance <= 0) return;

    try {
        const tx = await tronWeb.transactionBuilder.sendToken(
            mainAddress,
            usdtBalance, // 全额归集,已为最小单位
            'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
            userAddress
        );
        const signedTx = await tronWeb.trx.sign(tx, userPrivateKey);
        await tronWeb.trx.sendRawTransaction(signedTx);
        // 标记订单为已归集
        await db.query('UPDATE payment_orders SET collected = 1 WHERE address = ?', [userAddress]);
    } catch (err) {
        console.error('归集失败:', err);
    }
}
  • 关键:用户地址必须有足够TRX作为燃料费才能转账,所以要么生成地址时预存少量TRX(比如0.01 TRX),要么在支付提示里告知用户自行存入。

4. 核心注意事项

  • 安全性:用户私钥必须加密存储,主地址私钥用环境变量或密钥管理服务托管,绝对不能硬编码。
  • 过期机制:设置合理的订单过期时间(比如15-30分钟),清理无效订单。
  • 异常处理:处理链上交易失败、API请求超时等情况,避免机器人逻辑卡死。

内容的提问来源于stack exchange,提问作者CrazyChicken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:22:50