系统概览
USDT Gateway 是一个多商户 USDT-TRC20 收款网关。它使用“商户自有收款地址 + 唯一应付金额”的方式匹配链上充值,例如用户购买 100 USDT 的订单时,系统可能要求支付 100.001。
自动充值
系统监听链上 USDT 转账,按地址、金额和订单窗口自动匹配。
商户入账
达到确认数后,商户余额按原始订单金额入账,不包含后缀。
通知与对账
支付成功后发送签名 Webhook,后台保留订单、链事件、账本和审计记录。
用户角色
| 角色 | 主要使用入口 | 可以做什么 |
|---|---|---|
| 商户 | /merchant | 提交注册申请,审核通过后维护多个收款地址,查看余额、订单、Webhook、API Key,提交提现申请。 |
| 开发者 | /manual、/demos | 使用 API Key 创建订单、查询订单、校验 Webhook 签名。 |
| 平台运营 | 内部后台 | 维护商户、服务费规则、地址池、异常充值、Webhook 重试和链监听状态。 |
| 财务 | 内部后台 | 审核提现、维护白名单、记录出款 Tx Hash、查看审计日志。 |
商户快速开始
- 在
/merchant提交商户注册申请,等待管理员审核通过。 - 审核通过后登录商户后台,先在“收款设置”里配置自己的 USDT-TRC20 收款地址池。
- 如果有多个地址,可以选择轮询策略,或为不同地址设置权重后按权重分配。
- 确认商户状态、服务费额度、余额和 Webhook 配置。
- 在 API Key 页面创建一个服务端 API Key。API Key 只展示一次,需要保存到你的服务端环境变量。
- 调用创建订单接口,拿到
pay_amount、deposit_address和checkout_url。 - 把收银台链接或支付信息展示给用户,要求用户精确转账,不要多付或少付。
- 监听 Webhook,收到
payment.paid后给你自己的业务订单发货或开通服务。
建议商户系统用
merchant_order_id 做幂等键。同一个商户重复提交同一个 merchant_order_id 时,应当视为同一笔业务订单。支付流程
- 商户服务端创建支付订单,例如金额
100。 - 网关返回唯一应付金额,例如
100.001。同金额活跃订单会递增到100.002、100.003。 - 用户向订单指定的商户 TRON 地址转入精确金额。
- 链上监听 Worker 发现 USDT Transfer 事件,系统按地址和金额匹配订单。
- 达到确认数后订单变成
paid,商户余额增加原始订单金额,平台按商户计费规则扣减服务费预存款。 - 系统投递
payment.paidWebhook。
| 订单状态 | 含义 | 商户动作 |
|---|---|---|
awaiting_payment | 等待用户转账 | 展示地址和精确金额。 |
seen | 链上已看到交易,但确认数为 0 | 等待确认。 |
confirming | 确认数不足 | 等待达到 required confirmations。 |
paid | 已确认并入账 | 发货、开通服务或完成业务订单。 |
expired | 用户未在有效期内支付 | 提示用户重新下单。 |
API 对接
鉴权
商户服务端 API 使用 Bearer Token。不要把 API Key 放到浏览器、App 客户端或公开仓库。
Authorization: Bearer <merchant_api_key>
创建订单
POST /v1/payment-orders
Content-Type: application/json
Authorization: Bearer <merchant_api_key>
{
"amount": "100",
"merchant_order_id": "order-1001",
"customer_reference": "user-123",
"notify_url": "https://merchant.example/webhooks/usdt"
}
创建订单返回
{
"object": "payment_order",
"data": {
"id": "po_xxx",
"requested_amount": "100",
"pay_amount": "100.001",
"asset_code": "USDT",
"network": "TRON",
"deposit_address": "T...",
"status": "awaiting_payment",
"checkout_url": "https://pay.example.com/checkout/po_xxx",
"required_confirmations": 12,
"expires_at": "2026-05-17T12:30:00.000Z"
}
}
查询订单
GET /v1/payment-orders/:id
Authorization: Bearer <merchant_api_key>
完整的多语言代码在 /demos。
Webhook 通知
订单支付完成后,系统会向订单的 notify_url 或商户默认 Webhook URL 投递 payment.paid 事件。提现标记已打款后会投递 withdrawal.paid。
| Header | 说明 |
|---|---|
USDT-Event-Id | 事件投递 ID,可用于幂等。 |
USDT-Signature | 格式为 t=timestamp,v1=signature。 |
签名规则
signed_payload = timestamp + "." + raw_json_body
signature = HMAC_SHA256(webhook_secret, signed_payload)
验签必须使用原始请求 body,不能使用格式化或重新序列化后的 JSON。
提现流程
- 商户在后台提交提现申请,系统冻结可用余额。
- 平台财务审核,必要时要求第二人复核。
- 人工或外部钱包完成链上出款。
- 财务在后台填入真实 Tx Hash 并标记已打款。
- 系统扣减冻结余额,写入提现账本并通知商户。
MVP 阶段建议使用人工出款,不要把钱包私钥放进应用服务器。
异常处理
| 情况 | 系统表现 | 处理建议 |
|---|---|---|
| 用户少付或多付 | 不会自动匹配订单,进入未匹配充值 | 联系平台人工处理。 |
| 订单过期后才支付 | 在宽限窗口内可能仍可匹配,否则进入异常 | 建议用户重新下单并联系客服。 |
| Webhook 失败 | 系统记录失败并按重试策略投递 | 商户检查 HTTPS、响应状态和验签逻辑。 |
| 重复回调 | 可能因网络或重试产生 | 商户用事件 ID 和订单 ID 做幂等。 |
上线检查
- 确认域名、HTTPS 和服务器防火墙配置完成。
- 生产环境使用 PostgreSQL,不要使用默认密码和默认 Admin Key。
- 配置真实 TronGrid API Key,并让每个商户配置真实 USDT-TRC20 收款地址。
- 在管理员后台为商户配置按比例、按笔数或包月服务费规则,并确认预存服务费余额。
- 用 1-10 USDT 做一次真实小额转账,验证监听、匹配、确认、入账、Webhook。
- 开启数据库备份和恢复演练。
- 商户上线前必须完成 Webhook 验签和幂等测试。