Appearance
充值
充值无需调用接口发起:用户向钱包的充值地址转账,平台监听链上交易,达到最终性后自动入账,并通过回调通知你。你方只需要 获取充值地址 和 处理回调。
流程
text
链上转账到充值地址
│
▼
发现交易 ──▶ 交易记录 kind=DEPOSIT, status=CONFIRMING 回调 TRANSACTION_CREATED
│
▼ 等待确认 / 最终性(按网络配置)
│
├─ 金额 < 最小充值额 ──────────▶ COMPLETED + subStatus=BELOW_MIN_DEPOSIT (未入账)
├─ 金额 ≤ 充值手续费 ──────────▶ COMPLETED + subStatus=BELOW_MIN_DEPOSIT (未入账)
├─ 资产暂停充值 / 钱包冻结等 ──▶ PENDING_REVIEW(人工处理,未入账)
├─ 反洗钱筛查未通过 ──────────▶ PENDING_REVIEW + subStatus=AML(未入账)
├─ 交易未进入主链 ────────────▶ FAILED(未入账)
└─ 正常 ─────────────────────▶ COMPLETED(已入账 netAmountRaw) 回调 TRANSACTION_STATUS_UPDATED
│
▼ 极少数情况:入账后链重组,原区块被替换
REVERSED + subStatus=REORG(入账被冲正) 回调 DEPOSIT_REVERSED状态的完整定义见 交易状态。
确认与最终性
若 EVM 充值地址启用了 EIP-7702 长期委托,发送原生币时请通过 eth_estimateGas 估算 Gas,不要固定使用 21,000;委托代码执行需要额外 Gas。链上执行失败不会形成有效充值。此限制不影响普通 ERC-20 转入的 Gas 估算方式。
每个网络有自己的入账条件,可从 GET /v1/wallets/{id}/addresses 的 confirmations 字段读取:
mode | 含义 |
|---|---|
confirmations | 交易所在区块之上有 n 个确认后入账 |
finalized | 交易所在区块被链最终确定后入账(如 Solana) |
solidified | 交易所在区块被固化后入账(如 TRON) |
等待期间状态一直是 CONFIRMING,平台不推送确认数变化。
充值手续费
充值手续费用于覆盖平台把充值归集到热钱包的链上成本,在入账时从充值金额中扣除:
text
到账金额(amountRaw) = 链上实际转入金额
手续费 (feeRaw) = 入账时生效的充值手续费
入账金额(netAmountRaw)= amountRaw - feeRaw- 手续费在入账那一刻确定(取当时的
depositFeeRaw,见 手续费如何计算),可能与用户转账时看到的值略有差异。 - 交易对象在入账后才有
feeRaw和netAmountRaw;入账前feeRaw为null,且不包含netAmountRaw字段。 - 请按
netAmountRaw给用户记账,而不是amountRaw。
不会自动入账的充值
| 情况 | 状态 | 处理 |
|---|---|---|
金额低于资产的最小充值额(minDeposit / minDepositRaw) | COMPLETED + subStatus = BELOW_MIN_DEPOSIT | 不入账、不扣费。请在前端提示最小充值额 |
金额不高于充值手续费(amountRaw ≤ depositFeeRaw) | COMPLETED + subStatus = BELOW_MIN_DEPOSIT(与上一行相同;BELOW_DEPOSIT_FEE 为预留值,当前不会出现) | 不入账、不扣费 |
资产暂停充值(DEPOSIT_PAUSED) | PENDING_REVIEW + subStatus = ASSET_DEPOSIT_PAUSED | 平台/租户后台人工处理 |
| 钱包已冻结或关闭、网络关闭了自动入账 | PENDING_REVIEW + subStatus = WALLET_OR_NETWORK_HOLD | 人工处理 |
| 反洗钱(AML)筛查未通过或需复核 | PENDING_REVIEW + subStatus = AML | 人工处理 |
| 交易失败或未进入主链(被丢弃、2 小时内未确认) | FAILED + subStatus = "not on canonical chain" | 无需处理 |
注意 COMPLETED 不一定等于已入账
status = COMPLETED 且 subStatus 不为 null(BELOW_MIN_DEPOSIT,以及预留的 BELOW_DEPOSIT_FEE)时,资金没有进入用户余额。判断是否入账请同时检查 subStatus 为 null(或检查存在 netAmountRaw 字段)。
用户冻结(PATCH /v1/users/{customerRefId} 设为 FROZEN)不影响充值入账;只有钱包被冻结时才转人工。
人工补入账
不支持的代币、用户申诉找回等情况由平台人工处理。人工补入账成功后推送 MANUAL_DEPOSIT_CREDITED 回调:
json
{
"eventId": "0192a4d0-1111-7aaa-8bbb-0c0d0e0f1011",
"type": "MANUAL_DEPOSIT_CREDITED",
"tenantId": "0191f0aa-1b2c-7d3e-8f40-5a6b7c8d9e0f",
"createdAt": "2026-10-03T09:12:00.000000Z",
"data": {
"caseId": "0192a4cf-9a00-7b00-8c00-0d0e0f101112",
"walletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a",
"assetId": "USDT_ERC20",
"amountRaw": "50000000"
}
}该事件不对应交易记录(GET /v1/transactions 查不到),data 中只有 walletId。请在你方保存 walletId → customerRefId 的映射(deposit_address 响应里同时有这两个字段),以 caseId 为唯一键给用户加 amountRaw。
链重组冲正
入账后若平台证实原区块被替换(链重组),该笔入账会被冲正:交易状态变为 REVERSED、subStatus = REORG,并推送 DEPOSIT_REVERSED 回调:
json
{
"eventId": "0192a4d2-0000-7000-8000-000000000abc",
"type": "DEPOSIT_REVERSED",
"tenantId": "0191f0aa-1b2c-7d3e-8f40-5a6b7c8d9e0f",
"createdAt": "2026-10-03T09:30:00.000000Z",
"data": { "depositId": "0192a4c9-2222-7333-8444-555566667777" }
}depositId 是平台内部充值 ID,不是交易 id。收到该事件时,请用 GET /v1/transactions?kind=DEPOSIT&status=REVERSED&createdFrom=… 找出对应交易,并从用户余额中扣回 netAmountRaw。若用户已把资金转走、余额不足,平台会冻结该钱包并人工处理。
回调示例
1)发现充值(TRANSACTION_CREATED):
json
{
"eventId": "0192a4c9-3000-7000-8000-000000000001",
"type": "TRANSACTION_CREATED",
"tenantId": "0191f0aa-1b2c-7d3e-8f40-5a6b7c8d9e0f",
"createdAt": "2026-10-03T06:00:01.120000Z",
"data": {
"id": "0192a4c9-2f00-7aaa-8bbb-ccccdddd0001",
"kind": "DEPOSIT",
"settlement": "ON_CHAIN",
"status": "CONFIRMING",
"subStatus": null,
"assetId": "USDT_ERC20",
"networkKey": "ethereum",
"decimals": 6,
"amountRaw": "77000000",
"feeRaw": null,
"networkFeeRaw": null,
"networkFeeAssetId": "ETH",
"source": { "walletId": null, "address": "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc", "customerRefId": null, "uid": null },
"destination": { "walletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a", "address": "0x8ba1f109551bd432803012645ac136ddd64dba72", "customerRefId": "u-10001", "uid": "48213907" },
"txHash": "0x5f1c2a0e9b7d4c3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a",
"externalTxId": null,
"note": null,
"createdAt": "2026-10-03T06:00:01.050000Z",
"updatedAt": "2026-10-03T06:00:01.050000Z"
}
}2)入账完成(TRANSACTION_STATUS_UPDATED):
json
{
"eventId": "0192a4ca-1000-7000-8000-000000000002",
"type": "TRANSACTION_STATUS_UPDATED",
"tenantId": "0191f0aa-1b2c-7d3e-8f40-5a6b7c8d9e0f",
"createdAt": "2026-10-03T06:03:15.400000Z",
"data": {
"id": "0192a4c9-2f00-7aaa-8bbb-ccccdddd0001",
"kind": "DEPOSIT",
"settlement": "ON_CHAIN",
"status": "COMPLETED",
"subStatus": null,
"assetId": "USDT_ERC20",
"networkKey": "ethereum",
"decimals": 6,
"amountRaw": "77000000",
"feeRaw": "500000",
"netAmountRaw": "76500000",
"networkFeeRaw": null,
"networkFeeAssetId": "ETH",
"source": { "walletId": null, "address": "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc", "customerRefId": null, "uid": null },
"destination": { "walletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a", "address": "0x8ba1f109551bd432803012645ac136ddd64dba72", "customerRefId": "u-10001", "uid": "48213907" },
"txHash": "0x5f1c2a0e9b7d4c3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a",
"externalTxId": null,
"note": null,
"createdAt": "2026-10-03T06:00:01.050000Z",
"updatedAt": "2026-10-03T06:03:15.390000Z"
}
}回调中的 data 是“当前快照”
TRANSACTION_* 事件的 data 是投递时刻的交易对象,而不是事件发生时刻的。如果投递发生了延迟或重试,TRANSACTION_CREATED 里看到的可能已经是 COMPLETED。请始终以 data.status 为准做幂等的状态推进,而不要依赖事件类型。
入账处理建议
js
function onTransactionEvent(tx) {
if (tx.kind !== "DEPOSIT") return;
if (tx.status === "COMPLETED" && tx.subStatus === null && tx.netAmountRaw !== undefined) {
// 以 tx.id 为唯一键(数据库唯一约束),仅首次给 tx.destination.customerRefId 增加 tx.netAmountRaw
} else if (tx.status === "REVERSED") {
// 若之前已入账,则扣回 netAmountRaw
} else {
// CONFIRMING / PENDING_REVIEW / FAILED / COMPLETED+BELOW_*:仅更新展示状态,不加钱
}
}- 唯一键用交易
id,不要用txHash:一笔链上交易可能包含多笔转入(例如 BTC 的多个输出、同一交易多次代币转账),会生成多条充值记录。 - 定期用
GET /v1/transactions?kind=DEPOSIT&createdFrom=…&createdTo=…对账,补齐可能漏处理的回调。