Open-source project
GMWalletApp/epusdt avatar
GMWalletApp/epusdt

Epusdt (GM Pay): a self-hosted multi-chain crypto payment gateway in Go

开源优雅的跨平台收款网关 GM Pay(formerly known as EPUSDT)

3,854 stars1,045 forksGoGPL-3.0

At a glance

What is it?
Epusdt, now branded GM Pay, is a GPLv3 Go gateway that turns plain HTTP API calls into USDT, USDC, TRX, ETH and BNB collections across Tron, Ethereum, BSC, Polygon, Solana and Aptos. It is for operators who want funds to land in their own wallets, and it asks you to accept a matching scheme based on amount differences rather than unique addresses.
Who is it for?
Adopt Epusdt if you run a digital-goods shop, an AI API reseller panel or a subscription site on Dujiaoka, V2Board, XBoard, NewAPI, Sub2API, WordPress or WHMCS and you want settlement straight into your own wallets with no custodian in the middle. Do not adopt it if you need fiat cards, chargebacks, refunds or a regulated money-services relationship, and do not adopt it if you cannot run a long-lived process with reliable outbound access to chain APIs and RPC nodes.
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 63 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Epusdt solves, and the shape of the shop it fits

Accepting crypto on a small storefront usually means one of two bad options. You hand the money flow to a hosted processor that holds the balance and takes a cut, or you write your own chain watcher, address allocator and callback retry loop from scratch. Epusdt takes the second path and packages it. The README describes it as a multi-chain, multi-token crypto payment gateway built in Go, deployable privately, with no third-party custody and no platform commission, so funds arrive directly in wallets you control.

The audience is narrower than "anyone who wants crypto payments". The compatibility table names the systems it plugs into: Sub2API and NewAPI for AI distribution, Dujiaoka and 异次元发卡 for card-key shops, V2Board, XBoard, xiaoV2board and SSPanel for proxy panels, plus WordPress and WHMCS, and anything speaking the Epay 易支付 interface. Those are all systems that already have a payment-plugin slot and a callback URL, which is why the pitch is "no business logic rewrite". If your checkout is a bespoke mobile app with its own order state machine, you are integrating against the HTTP API yourself, and the value proposition is thinner.

The honest framing: Epusdt is infrastructure for merchants who are comfortable operating a server and a wallet. It is not a merchant-of-record product, and the disclaimer in the README is explicit that the project is non-custodial, non-profit and provided for study, research and technical exchange.

How the amount-matching mechanism actually works

Epusdt does not give each order a fresh deposit address. It reuses a pool of wallet addresses and distinguishes orders by the exact amount received. The README's implementation section walks through the flow: a customer owes 20.05 USDT; the system looks up an available address-plus-amount combination in a hash table; if address_1:20.05 is unclaimed it locks that pair for 10 minutes and returns it; if the pair is taken, the system adds 0.0001 and tries the next combination, up to 100 attempts; a background thread watches incoming transfers on all wallets and confirms the order when the amount matches.

That design is the whole architecture in miniature. It means the gateway needs a small number of funded addresses rather than one per order, and it means order attribution is a matching problem rather than a lookup problem. The 10-minute lock and the 100-attempt ceiling are the two parameters that bound it: under heavy concurrent load, a merchant can exhaust distinct amounts within 0.01 USDT of the base price. The README does not document what happens when all 100 attempts fail, which is the first thing to test if you expect bursty traffic.

The README also lists multi-wallet rotation, an asynchronous queue for callbacks aimed at high-concurrency scenarios, and a Telegram bot for notifications. The rotation feature is what makes the address pool manageable; the queue is what keeps a slow merchant endpoint from blocking confirmation. Neither is described in enough detail in the README to predict throughput, and no benchmark numbers are published, so sizing is something you measure on your own deployment.

Installing Epusdt and taking a first payment

The repository ships two deployment paths and points at a third. The README's quick-start table links the in-repo epctl script for Linux binary install, upgrade, status and password initialisation, a Docker guide described as the recommended route, a 宝塔面板 (aaPanel) guide, and a manual guide. The repository also carries epctl-docker-test.sh, which the README says runs a real Ubuntu plus systemd install acceptance test inside local Docker.

The Docker path is the one with a file in the repository. The docker-compose.yaml defines a single service named epusdt using the image gmwallet/epusdt:latest, restarting always, mounting ./env onto /app/.env, and publishing port 8000.

yaml
services:
  epusdt:
    image: gmwallet/epusdt:latest
    restart: always
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./env:/app/.env
    ports:
      - "8000:8000"

Start it with the usual compose command from the repository root. Because the volume maps a host file onto /app/.env, create that file first; the Dockerfile copies src/.env.example into the image at build time, so the container has a template to follow even if you have not written your own yet.

bash
docker compose up -d
docker compose logs -f epusdt

The Dockerfile is worth reading before you deploy, because it reveals the runtime contract. It builds with Go in an alpine builder stage, runs the binary with ./epusdt http start, sets TZ=Asia/Shanghai, declares a VOLUME at /app/conf, and accepts a build argument API_RATE_URL that rewrites the api_rate_url key in .env during the image build.

dockerfile
ENV TZ=Asia/Shanghai
ARG API_RATE_URL=""
COPY --from=builder /app/src/.env.example /app/.env
ENTRYPOINT ["./epusdt", "http", "start"]

On the binary path, the README says ./epctl handles Linux installation, upgrades, configuration display, status and initial password retrieval. It does not reproduce the subcommands in the README itself; they live in wiki/EPCTL.md in the repository. Read that file rather than guessing at flags. Once the service is up, the integration surface is the HTTP API documented at epusdt.com, and the management panel and cashier pages shown in the README screenshots are served from the same process on port 8000.

Where the design bites: matching, callbacks and custody

The amount-matching scheme has a failure mode that is easy to underestimate. Two customers paying the same base price in the same ten-minute window are distinguished only by fractions of a cent. If a customer pays the wrong amount, or pays from an exchange that rounds the transfer, the background matcher has nothing to bind the deposit to. The README does not describe a manual reconciliation workflow for unmatched deposits, so plan for one operationally: someone has to look at the wallet and decide what the stray transfer was.

Callbacks are the second sharp edge. The README advertises an asynchronous queue for high-concurrency callback delivery, but it does not document retry policy, backoff, signature verification or a replay endpoint. The related search phrase "epusdt 不 回调" (callback not firing) exists for a reason. Treat your callback handler as at-least-once and idempotent, keyed on your own order ID, and do not assume the gateway will retry forever.

Custody is the third. Non-custodial means you hold the keys and you hold the consequences. There is no chargeback, no dispute process, and no way to reverse a confirmed on-chain transfer. The README's disclaimer states that whether crypto activity constitutes money transmission or an MSB under US regulation depends on the business model, including whether the operator receives, holds, controls or transmits funds. Running Epusdt yourself does not settle that question, and the project explicitly disclaims providing legal, tax or compliance advice. If your business needs a regulated counterparty, this is the wrong tool.

How Epusdt differs from hosted crypto payment processors

The obvious alternative is a hosted processor that gives you a checkout page and settles to your bank or wallet. The difference is not cosmetic. A hosted processor allocates a per-invoice address or an internal ledger entry, handles confirmation depth, and absorbs the matching problem for you. You pay a percentage and you accept that the processor controls the funds until settlement, and that it can freeze or refuse a transaction.

Epusdt inverts every one of those. You run the process, you own the addresses, you receive directly, and you pay nothing per transaction beyond network fees and your own hosting. In exchange you inherit the amount-matching logic, the callback reliability, the chain API dependencies and the operational burden of keeping the service running. A second alternative is the sibling project the README lists under its Edge series: GMPay Edge, a multi-chain payment gateway built on Cloudflare Workers, with merchant API, aggregated cashier, payment management and webhook delivery, alongside GMShop Edge for digital-goods storefronts. That is the same problem solved without a server to operate, at the cost of depending on a Workers runtime and whatever limits it imposes. Choosing between them is mostly a question of whether you want a long-lived process you control or an edge deployment you do not maintain.

Maintenance, releases and what GPLv3 means for your integration

The repository is not archived and the last push was on 2026-07-29, which is recent enough that the project is being worked on. Releases are frequent: v1.0.9 on 2026-06-29, v1.0.10 on 2026-07-10, and v2.0.0 on 2026-07-23, a major bump that arrived about a week before the last push. The README itself warns that the exact set of supported chains and tokens is governed by the latest release and the official documentation, not by the table in the README, so pin a version and check its release notes before you promise a token to a customer.

Upgrade cost depends on your path. The Docker route means pulling a new tag and recreating the container; the binary route goes through ./epctl, which the README says handles upgrades. Neither path is documented in the README with rollback steps, so keep your .env and any database or Redis state under your own version control before you move tags.

The licence is GPLv3. If you deploy Epusdt as a separate service and talk to it over HTTP, you are using it, not distributing a derivative of it. If you modify the source and ship the modified binary to customers, or embed it in a product you distribute, GPLv3's copyleft obligations attach to that distribution. The README does not discuss this, and this is not legal advice; if your business model involves redistributing a modified Epusdt, get a lawyer to read the licence rather than a blog post.

Editorial conclusion

Adopt Epusdt if you run a digital-goods shop, an AI API reseller panel or a subscription site on Dujiaoka, V2Board, XBoard, NewAPI, Sub2API, WordPress or WHMCS and you want settlement straight into your own wallets with no custodian in the middle. Do not adopt it if you need fiat cards, chargebacks, refunds or a regulated money-services relationship, and do not adopt it if you cannot run a long-lived process with reliable outbound access to chain APIs and RPC nodes. Verify three things before you point real customers at it: that the chain and token you intend to accept appears in the release notes for the version you install, that your callback endpoint is reachable from the gateway and idempotent, and that your chosen deployment path (the ./epctl script or the docker-compose.yaml image gmwallet/epusdt:latest) starts cleanly with your own .env rather than the .env.example copied into the image.

Frequently asked questions

What is USDT payment, and does Epusdt handle it?

Epusdt is a multi-chain crypto payment gateway that accepts USDT on TRC20, ERC20, Solana, BEP20 and Polygon, according to the README's network and token table. It watches those chains for incoming transfers and confirms the matching order, with funds going directly to wallets you control.

Which payment gateway can accept USDT payments?

Epusdt is one option: a GPLv3, self-hosted Go gateway that exposes an HTTP API and plugs into Dujiaoka, V2Board, XBoard, NewAPI, Sub2API, WordPress, WHMCS and Epay-compatible platforms without rewriting business logic. The README also lists GMPay Edge, a Cloudflare Workers based gateway, as a sibling project.

How can I pay someone with USDT through Epusdt?

The customer does not interact with Epusdt directly. The README's flow has the merchant system request a payment, the gateway lock an address and exact amount pair for 10 minutes, and the customer send that amount to that address, after which a background thread matches the incoming transfer and confirms the order.

Official sources

  1. GMWalletApp/epusdt on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gmwalletapp-epusdt.svg)](https://hysenlabs.com/projects/gmwalletapp-epusdt)