TECHNICAL BLOG
BLOCKCHAIN · NODE.JSMay 2026·12 min read

Building a crypto payment gateway with Node.js and ethers.js v6

How to design a cryptocurrency payment architecture supporting BTC, USDT TRC-20, ERC-20 and BEP-20 with per-transaction dedicated wallets and automated sweeping.

TECHNICAL BLOG

At SoftDev.Mx we've built cryptocurrency payment infrastructure for platforms with thousands of active users across multiple countries. This article documents the architecture we designed for a payment gateway supporting Bitcoin, USDT (TRC-20, ERC-20, BEP-20) and more networks soon.

The goal was clear: users needed to deposit cryptocurrencies and see their balance reflected instantly. Behind the scenes, this meant monitoring multiple blockchains, detecting incoming transactions, assigning dedicated wallets per payment, and automatically sweeping funds to a master wallet.

We needed a library that would let us interact with Ethereum and its derivatives (BSC, Tron) in a unified way. ethers.js v6 was the natural choice: it supports multiple networks, has a clean API, and is actively maintained. For Bitcoin, we used bitcoinjs-lib combined with Electrum for transaction monitoring.

Each time a user initiates a deposit, the backend generates a unique wallet dedicated exclusively to that transaction. This is achieved by deriving a new address from a master seed using BIP32/BIP44. Benefits: if a user deposits to the wrong address, the impact is limited to a single transaction; traceability is complete.

Incoming transactions are detected by polling RPC nodes or block explorer APIs. For Ethereum and BSC, we use JSON-RPC calls to our own nodes. For Tron, we use the TronGrid API. For Bitcoin, Electrum. Each network has its own confirmation logic and reorg handling, adding complexity to state management.

The sweeping architecture is key to security. Funds accumulated in temporary wallets are periodically swept to a cold master wallet. We implemented a cron job that checks the balances of all active wallets every hour and executes sweep transactions. To minimize gas costs, transactions are batched when possible.

Every incoming and outgoing transaction is recorded in PostgreSQL with its status (pending, confirming, confirmed, failed). A worker listens for TransactionConfirmer events that update states as on-chain confirmations increase. The real-time dashboard consumes this data to show users their transaction status.

With this architecture we've processed thousands of transactions without any loss of funds. Key lessons: use dedicated addresses per transaction, have RPC node redundancy, implement dynamic gas limits, and most importantly — test exhaustively on testnet before touching mainnet.

Read article

Want to receive technical articles?

We publish about the real technical challenges we solve: blockchain, biometrics, infrastructure and enterprise software architectures.

Notify me on WhatsApp when published