TokenPay settles crypto orders by polling explorers and matching the amount
✅一款同时支持动态和静态收款地址收取TRX、USDT-TRC20、ETH系列区块链所有代币的支付解决方案!✅A payment solution that supports both dynamic and static payee addresses to receive TRX, USDT-TRC20, all tokens of ETH series blockchain!
At a glance
- What is it?
- TokenPay is a GPL-3.0 licensed, self-hosted .NET 8 payment gateway for TRX, USDT-TRC20 and ETH-series tokens, with a design point that matters for anyone integrating it: the order amount is compared against the incoming transaction value, which is why it supports both a shared static address and a unique dynamic address per order. The mechanism depends on third-party explorer APIs, and the admin page is read only.
- Who is it for?
- TokenPay fits a self-hosted seller who wants to accept TRX, USDT-TRC20 or ETH-series tokens and already runs a stack that speaks one of the supported plugin protocols, such as dujiao-next, the epay plugins, v2board or card-system. It does not fit a merchant who needs a settlement guarantee, because confirmation depends on third-party explorer APIs polling and on a single amount comparison, and the manual fulfilment path exists precisely for the cases that do not resolve.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 27 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One address per order, or one per user, is the design decision
The project description opens with the claim that makes this a gateway rather than a wallet: a payment solution that supports both dynamic and static payee addresses to receive TRX, USDT-TRC20, all tokens of the ETH series.
The problem that solves is stated plainly in the feature list. Supporting one receiving address per order, or one per user, addresses the pain point of a single shared address, which makes it easy to complete the wrong order. In a shared-address model, several customers pay to the same wallet at the same time and the gateway has to guess which payment belongs to which order. With a unique address per order, each payment is unambiguous at the address level, and the only remaining question is the amount.
The scope of the chains is broader than the headline suggests. The README says the project supports TRX, USDT-TRC20, the ETH-series native coins and ETH-series ERC20 tokens, and in principle all ETH-series blockchains, with the common ones named as Ethereum, Binance Smart Chain and Polygon. That in principle covers a long tail of EVM chains, with the practical caveat that each chain needs its own explorer API and its own address handling.
The deployment model is deliberately narrow. TokenPay is a privately deployed, self-hosted payment solution written in C#, cross-platform for Windows, Linux and macOS on x86 and arm, requiring no extra environment configuration and running as a single compiled binary. It depends on no external resources, needs no separate database because it uses a lightweight SQLite, and needs no Redis.
That last constraint is what makes it attractive for small operators. The cost of a dedicated database server and a Redis instance is the part of a payment stack that usually stops a self-hosted deployment, and here it is replaced by one file.
Settlement is an amount comparison against polled explorer data
The design section explains how the implementation works, and the README is open about the fact that it is the same principle as other projects: it goes through APIs provided by TronGrid, Etherscan and similar services.
The mechanism is described as a short numbered sequence.
简单的原理:
0.服务器定时同步交易所最新汇率
1.客户支付,交易上链
2.服务器定时通过API轮询,获取监听地址下的最新入账交易数据,并与数据库订单对比
3.若金额一致,将订单标记为完成
4.订单完成后,异步通知任务将订单完成事件回调给平台In English: the server periodically syncs the latest exchange rates, the customer pays and the transaction is written on chain, the server periodically polls the API for the newest incoming transactions on the watched addresses and compares them with the orders in the database, and if the amount matches, the order is marked complete. After that an asynchronous task notifies the platform that the order is done, through a callback.
Three design consequences follow from that description, and they are worth holding on to.
First, the gateway does not run a node or validate a transaction itself. It reads a third-party API. That means the settlement path depends on an external service's availability, its rate limits and its indexing lag.
Second, the comparison that completes an order is on amount. The description says the incoming amount is compared with the order amount in the database and that a match is treated as order completion. An order that is paid twice, or two concurrent orders of the same value on a shared static address, are the cases where an amount-only match is ambiguous, and the dynamic per-order address is the mitigation for the second of them.
Third, the notification to the platform is asynchronous and happens after the order is marked complete, so the integration contract has to treat the callback as the signal and not poll for order state.
The admin page is read only, and manual fulfilment is a feature
The feature list describes the management side of the system as a built-in, configurable, read-only backend management page, which can safely be used to view orders, wallets and exchange rate records, and which supports manually completing expired orders whose on-chain arrival has already been confirmed.
That last clause is a small sentence doing a lot of work. It says the system knows the difference between an order that was never paid and an order that was paid but not matched, and it gives the operator a way to complete the second kind by hand. Given that settlement depends on polling third-party explorer APIs and comparing amounts, that manual path is not a convenience, it is the safety valve for the cases the automated path cannot resolve.
The read-only part is also meaningful. An admin page that can view orders, wallets and rate records but cannot move funds or change state is a much smaller security surface than a full back office, and for a self-hosted deployment that is the sensible default. The manual completion action is the one exception, and it is scoped to expired orders whose on-chain arrival has been confirmed.
The pages themselves are also part of the product. The project supports display in Simplified Chinese and English, adapting to the visitor's device language, with other languages defaulting to English, and the ExtraLanguages configuration can add more if you supply the corresponding language pages. There is a separate document, the view customisation guide, on overriding the built-in pages at runtime.
For an integrator, that combination means the customer-facing payment page, the order record and the settlement callback are three separate concerns, and the documentation treats them as such with separate pages for the API, the admin panel, the runtime customisation and the deployment guides.
Plugins are the integration surface, not the core
The project structure is three directories, and one of them is where the interoperability lives.
TokenPay
├── Plugs ---> (插件)
├── Wiki ---> (知识库)
└── src ---> (项目核心目录)The Plugs directory holds the integrations, and the README lists the ones that exist. A newer dujiao-next plugin is built into the project by the developer. The epay-pro and epay plugins, which are the 彩虹易支付 family, are in the tree. There is a dujiaoka plugin, which the README marks as no longer maintained and not recommended. There is a v2board plugin, and a card-system plugin.
That list is the answer to the question a buyer actually has, which is what my storefront runs on. The epay protocol in particular is the common integration contract for a large class of Chinese storefront scripts, and the presence of several independent plugins for the same protocol is a good sign, because it means the protocol is implemented in the plugins rather than baked into the core.
The Wiki directory is the documentation, and the README points at specific files inside it. There is the TokenPay interface documentation at Wiki/docs.md, the backend management notes at Wiki/admin.md, the manual running guide at Wiki/manual_RUN.md, the 宝塔 panel guide at Wiki/BT_RUN.md, the Docker guide at Wiki/Docker-RUN.md, and the view customisation guide at Wiki/ViewCustomization.md. The existing plugins in the repository are also suggested as a reference for integrators, and there are also user-contributed setup videos.
The repository itself keeps the project core in src/, with a global.json pinning the.NET SDK version, plus.github/ for the workflows and a.gitattributes file.
Release packages come in self-contained and framework-dependent flavours
The deployment documentation is unusually practical, and the one detail worth pulling out is the packaging choice.
The tutorial section states that a release provides both a self-contained package and a lightweight package whose name contains framework-dependent, and that the latter requires the.NET 8 ASP.NET Core Runtime to be installed in advance, with the choice explained in the manual running guide.
That is a decision with real operational consequences. The self-contained package carries the runtime with it, so a fresh machine needs nothing but the binary, which matches the feature claim of no extra environment configuration. The framework-dependent package is smaller, at the cost of requiring a runtime that has to be installed and kept in step, and it is the sensible choice on a server where the runtime is already managed.
The other deployment routes are equally concrete: a guide for running TokenPay under the 宝塔 panel, a manual running guide, and a Docker guide. That is three documented ways to run the same binary, which is a sign the author expects a mixed user base rather than one standardised environment.
The release history is short and regular. The recent tags are v1.2.0 on 2026-09-25 and two pre-release builds, pre-v1.2.0-20260916 and pre-v1.2.0-20260907, one per week in September 2026. The version badge in the README still reads 1.0.0 and points at a dujiaoka release, which is a stale reference rather than the current version.
The last push to the repository was on 2026-09-26, the day after the v1.2.0 tag, and the repository is not archived with master as the default branch.
GPL-3.0, and a disclaimer that puts the operating risk on the user
The licence is GPL-3.0, stated in the README with a badge and referenced in the project description, with LICENSE.txt at the repository root. You may use, modify and redistribute it, including in a commercial deployment, provided the copyright notice, the licence text and the source obligations of the copyleft are met. That is a licensing fact rather than legal advice, and for a self-hosted piece of server software that most merchants deploy unchanged, the practical obligation is to keep the notice and to be willing to publish source for a modified version.
The disclaimer section is the other thing to read carefully, because it is unusually explicit. The project is open source and intended for learning and exchange, and it states that it must not be used for any purpose that violates the laws of the People's Republic of China, including Taiwan province, or the laws of the user's own region. It says the author completed only the development and open sourcing of the code, has never taken part in any user's operations or profit-making activities, does not know what users will do with the source afterwards, and that any legal responsibility arising from use is the user's own. There is then a warning block saying the blockchain tokens involved in the project are for learning purposes, that the author does not endorse the financial nature of the tokens that blockchain has spawned, and does not encourage or support mining, coin speculation or virtual currency ICOs.
That is a real constraint for an evaluator, and not only a legal formality. A merchant who wants to accept crypto in production is taking on regulatory questions that this software does not address and that the author explicitly disclaims.
The acknowledgements credit the projects the code stands on: Serilog for logging, FreeSql for the data access layer, Flurl for the HTTP client, Nethereum for the Ethereum side and HDWallet for key handling. The first two of those are visible in the design too, since the SQLite store and the pluggable chain support are exactly the kind of thing a lightweight ORM and a logging framework make straightforward.
Editorial conclusion
TokenPay fits a self-hosted seller who wants to accept TRX, USDT-TRC20 or ETH-series tokens and already runs a stack that speaks one of the supported plugin protocols, such as dujiao-next, the epay plugins, v2board or card-system. It does not fit a merchant who needs a settlement guarantee, because confirmation depends on third-party explorer APIs polling and on a single amount comparison, and the manual fulfilment path exists precisely for the cases that do not resolve. Before deploying it, read Wiki/docs.md for the integration contract, test a real small payment end to end on your target chain, and read the author's legal disclaimer, which places responsibility for the use of the software on the operator.
Frequently asked questions
What chains and tokens does TokenPay support?
The project supports TRX, USDT-TRC20, the ETH-series native coins and ETH-series ERC20 tokens, and in principle all ETH-series blockchains, with Ethereum, Binance Smart Chain and Polygon named as the common examples. The chain list is a repository topic, and each chain needs its own explorer API for settlement polling.
How does TokenPay decide that an order is paid?
The server periodically polls APIs such as TronGrid and Etherscan for the newest incoming transactions on the watched addresses, compares the incoming amount with the order amount in the database, and marks the order complete when the amounts match. An asynchronous task then calls back the platform that the order is finished.
What is the difference between dynamic and static payee addresses in TokenPay?
The project supports one receiving address per order or one per user, and the feature list says this solves the pain point of a single shared address, where it is easy to complete the wrong order. The static mode relies on the amount comparison to disambiguate, while a per-order address removes that ambiguity.
What does TokenPay need to run?
The project is a self-hosted .NET 8 application in C# that needs no external resources, no separate database because it uses a lightweight SQLite, and no Redis. It runs as a single compiled binary on Windows, Linux and macOS on x86 and arm, and releases ship as both self-contained and framework-dependent packages.
Which storefronts can integrate with TokenPay?
The Plugs directory holds the integrations, and the README lists dujiao-next, which is built into the project, the epay-pro and epay plugins, a dujiaoka plugin marked as no longer maintained, a v2board plugin and a card-system plugin. The API contract is documented in Wiki/docs.md and the admin panel in Wiki/admin.md.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lightcountry-tokenpay)Was this useful?