Automated recurring crypto payments system

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Automated recurring crypto payments system
Medium
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1238
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    867
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1080
  • image_logo-advance_0.png
    B2B Advance company logo design
    563
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    829

Automated Recurring Crypto Payments System

Blockchain is inherently a push system. Nobody can withdraw funds from your wallet without your transaction signature. Recurring payments in crypto aren't "a subscription that pulls money monthly" — it's an architectural problem: how to organize automatic payouts without constant user presence while maintaining security.

Implementation Models

Three fundamentally different approaches, each solving different tasks.

Pull model with approval. Recipient (or protocol) can withdraw themselves, but only within approved allowance. Standard ERC-20 scheme: user once does approve(spender, amount), then spender calls transferFrom on schedule.

Problem — unlimited approve. User approves type(uint256).max, and if the contract is compromised, all funds are at risk. Correct: approve specific amount + allowance resets after each payout.

Escrow with schedule. User deposits funds into storage contract, contract pays on schedule. User retains control via pause/cancel function. More secure architecture — funds are locked, but user knows exactly what and when will be spent.

Streaming payment (streaming). Superfluid and Sablier protocols implement continuous token flow: funds flow per second, recipient can withdraw accumulated any time. Especially good for salaries, vesting, rent payments.

Contract Architecture

For a custom recurring payment system, build around several key elements:

struct PaymentSchedule {
    address payer;
    address payee;
    address token;          // address(0) for ETH
    uint256 amount;         // amount per period
    uint256 period;         // in seconds
    uint256 nextPaymentAt;  // timestamp of next payment
    uint256 maxPayments;    // 0 = infinite
    uint256 completedPayments;
    bool active;
}

mapping(bytes32 => PaymentSchedule) public schedules;

Key functions:

  • createSchedule() — user creates subscription, first payment optionally immediately
  • processPayment(bytes32 scheduleId) — executes next payout (called by keeper)
  • cancelSchedule() — user cancels subscription
  • pauseSchedule() / resumeSchedule() — temporary pause

Protection from double-spending. nextPaymentAt updates before fund transfer (Check-Effects-Interactions). Add paymentNonce — unique counter per payment, protection from replay in multisig scenarios.

Payment Automation: Who Calls the Contract

The contract won't call itself. Need an external trigger.

Chainlink Automation (formerly Keepers). Decentralized network of nodes monitoring condition and calling contract:

import "@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";

contract RecurringPayments is AutomationCompatibleInterface {
    
    function checkUpkeep(bytes calldata)
        external view override
        returns (bool upkeepNeeded, bytes memory performData)
    {
        bytes32[] memory dueSchedules = getDueSchedules(); // schedules with nextPaymentAt <= block.timestamp
        upkeepNeeded = dueSchedules.length > 0;
        performData = abi.encode(dueSchedules);
    }
    
    function performUpkeep(bytes calldata performData) external override {
        bytes32[] memory scheduleIds = abi.decode(performData, (bytes32[]));
        for (uint i = 0; i < scheduleIds.length; i++) {
            _processPayment(scheduleIds[i]);
        }
    }
}

Chainlink Automation — reliable choice for mainnet. Cost — pay LINK per upkeep call plus gas. Registration takes minutes via web interface or programmatically.

Gelato Network. Chainlink Automation alternative with more flexible triggers. Supports time-based and event-based triggers. Can pay in ETH instead of native token.

Custom backend keeper. For B2B solutions or when full customization needed: backend monitors contract, calls processPayment. Centralized but simpler to debug. Often preferred for enterprise clients.

Limit Management and Security

Per-period amount limit. User sets maximum single payout size when creating subscription. Keeper calling payout with higher amount — revert.

Time window. Payment is overdue if not executed within graceWindow after nextPaymentAt. If keeper doesn't call within window — payment skipped (or accumulates, depends on business logic).

Pause on insufficient funds. If escrow account lacks tokens — instead of revert, contract emits InsufficientFunds event and deactivates schedule. Keeper reads event and notifies user (via backend + email/push).

Native Currency vs Tokens

ETH payments simpler to implement but harder to manage: user must keep ETH in contract. Tokens (ERC-20) more convenient for stablecoin payments (USDC, DAI) — user approves contract to spend tokens from their wallet, keeps them themselves.

For B2C recurring payments (subscriptions) — recommend USDC on Polygon or Arbitrum. Low gas, stable cost, wide support.

Criteria ETH/MATIC native ERC-20 (USDC)
Complexity Simpler Slightly harder
Fund storage In contract (escrow) With user (approve)
Amount predictability Depends on rate Stable (stablecoin)
User UX Worse (must top up contract) Better

Development Process

Design (1-2 days). Determine model (pull/escrow/streaming), choose keeper, draw state machine for schedule (active → paused → cancelled → completed).

Contract development (4-6 days). Write in Solidity 0.8+, OpenZeppelin ReentrancyGuard, Pausable. Tests via Foundry — fuzzing time boundary conditions especially important.

Keeper integration (1-2 days). Chainlink Automation registration or Gelato task deployment.

Backend and notifications (2-3 days). Monitor contract events via ethers.js or viem, send user notifications.

Total timeline — 1-2 weeks depending on complexity and number of integrations.