Skip to content

提现与站内转账 ​

一个接口 POST /v1/transactions 同时支持链上提现和站内转账。平台根据收款方自动决定结算方式:

收款方结算方式交易 kind手续费
外部地址(含其他租户的充值地址)链上(ON_CHAIN)WITHDRAWAL提现手续费 withdrawFeeRaw;链上网络费由租户金库代付,用户成本通过手续费承担
本租户某个钱包的充值地址站内(OFF_CHAIN),自动识别INTERNAL_TRANSFER跨用户:租户设置的站内转账费;同一用户的钱包之间:0
本租户的钱包 ID(WALLET)或用户(END_USER)站内(OFF_CHAIN)INTERNAL_TRANSFER同上
平台运营地址(热钱包、归集、Gas 地址等)拒绝—422 INTERNAL_DESTINATION_NOT_ALLOWED

站内结算不上链、即时到账(除非触发审批),没有 txHash。

站内转账的收款方也要记账

如果你方维护用户余额,收到 kind = INTERNAL_TRANSFER、status = COMPLETED 的交易时,要同时给付款方(source.customerRefId)扣减 amountRaw + feeRaw,给收款方(destination.customerRefId)增加 amountRaw。向本租户充值地址的“提现”会变成站内转账,收款方不会收到 DEPOSIT 记录。

交易对象 ​

查询接口和 TRANSACTION_* 回调的 data 使用同一个交易对象(充值、提现、站内转账通用):

字段类型说明
idstring (UUID)交易 ID(查询、取消都用它)
kindstringDEPOSIT / WITHDRAWAL / INTERNAL_TRANSFER
settlementstringON_CHAIN / OFF_CHAIN
statusstring对外状态,见 交易状态
subStatusstring | null补充说明,见 交易状态
assetIdstring资产 ID
networkKeystring资产所在网络
decimalsinteger资产精度
amountRawstring金额(最小单位)。提现/转账为收款方收到的金额;充值为链上转入金额
feeRawstring | null向用户收取的手续费。提现/转账另外从付款方扣除;充值在入账时从 amountRaw 中扣除(入账前为 null)
netAmountRawstring仅充值且已确定手续费时出现:实际入账金额 = amountRaw - feeRaw
networkFeeRawstring | null链上提现实际支付的网络费(租户金库代付,用户成本通过手续费承担,仅供参考),在提现最终确认后写入;单位是该网络原生币的最小单位(例如 USDT_ERC20 提现时为 ETH 的 wei),不是本资产的单位。充值与站内转账为 null
networkFeeAssetIdstring | nullnetworkFeeRaw 所用的币种,即该网络原生币的资产 ID(例如 ETH、TRX),按其 decimals(见 GET /v1/supported_assets)换算
sourceobject付款方:walletId、address、customerRefId、uid(不适用时为 null;充值的 source.address 为链上转出地址)
destinationobject收款方:walletId、address、customerRefId、uid(链上提现只有 address)
txHashstring | null链上交易哈希;站内转账为 null;提现在广播后才有
externalTxIdstring | null你方提交时传入的 externalTxId
notestring | null提交时传入的备注
createdAt / updatedAtstringRFC 3339
json
{
  "id": "0192a4e0-5c00-7d00-8e00-0f1011121314",
  "kind": "WITHDRAWAL",
  "settlement": "ON_CHAIN",
  "status": "COMPLETED",
  "subStatus": null,
  "assetId": "USDT_ERC20",
  "networkKey": "ethereum",
  "decimals": 6,
  "amountRaw": "10000000",
  "feeRaw": "2500000",
  "networkFeeRaw": "1084522000000000",
  "networkFeeAssetId": "ETH",
  "source": { "walletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a", "address": "0x8ba1f109551bd432803012645ac136ddd64dba72", "customerRefId": "u-10001", "uid": "48213907" },
  "destination": { "walletId": null, "address": "0x90f79bf6eb2c4f870365e785982e1f101e93b906", "customerRefId": null, "uid": null },
  "txHash": "0x9a8b7c6d5e4f30211203f4e5d6c7b8a9f0e1d2c3b4a5968778695a4b3c2d1e0f",
  "externalTxId": "wd-20261003-000001",
  "note": null,
  "createdAt": "2026-10-03T07:00:00.100000Z",
  "updatedAt": "2026-10-03T07:02:41.870000Z"
}

发起提现 / 转账 ​

http
POST /v1/transactions

请求头

头必填说明
X-API-Key、Authorization是见 认证与签名
Content-Type是application/json
Idempotency-Key条件请求体没有 externalTxId 时必填;有 externalTxId 时忽略本头。见 幂等
X-User-2FA-Code条件租户开启“API 出金需终端用户两步验证”时必填,见 下文

请求体

字段类型必填说明
assetIdstring是资产 ID,必须与付款钱包同一链族
sourceobject是付款方
source.typestring是固定为 WALLET
source.idstring (UUID)是付款钱包 ID(本租户的钱包)
destinationobject是收款方,三选一,见下表
amountRawstring是收款金额(最小单位),必须大于 0。手续费另外从付款钱包扣除
externalTxIdstring否(强烈推荐)你方的唯一单号,1–128 字符,租户内唯一;同时作为幂等键
notestring否备注,原样出现在交易对象中

destination 的三种形式:

destination.type其他字段说明
WALLETid:钱包 ID本租户任意钱包(本人或他人),站内结算
END_USERuid 或 customerRefId(必须且只能给一个)本租户另一个用户,转入其与付款钱包同链族的默认钱包,站内结算。不能指定自己(用 WALLET 在本人钱包间划转)
ONE_TIME_ADDRESSoneTimeAddress.address:地址字符串任意地址。本租户充值地址 → 自动站内结算;其他 → 链上提现

链上提现示例:

json
{
  "assetId": "USDT_ERC20",
  "source": { "type": "WALLET", "id": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a" },
  "destination": { "type": "ONE_TIME_ADDRESS", "oneTimeAddress": { "address": "0x90f79bf6eb2c4f870365e785982e1f101e93b906" } },
  "amountRaw": "10000000",
  "externalTxId": "wd-20261003-000001"
}

按用户站内转账示例:

json
{
  "assetId": "USDT_ERC20",
  "source": { "type": "WALLET", "id": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a" },
  "destination": { "type": "END_USER", "customerRefId": "u-20002" },
  "amountRaw": "2000000",
  "externalTxId": "tr-20261003-000007"
}

响应 202 Accepted。响应体不是交易对象,而是提交回执,形状取决于结算方式(用 settlement 区分);后续状态请查询交易对象。

链上提现(settlement = ON_CHAIN):

json
{
  "settlement": "ON_CHAIN",
  "withdrawalId": "0192a4e0-5b00-7c00-8d00-0e0f10111213",
  "transactionId": "0192a4e0-5c00-7d00-8e00-0f1011121314",
  "status": "SUBMITTED",
  "subStatus": null,
  "state": "REQUESTED",
  "assetId": "USDT_ERC20",
  "amountRaw": "10000000",
  "feeRaw": "2500000",
  "reservedRaw": "12500000",
  "destination": "0x90f79bf6eb2c4f870365e785982e1f101e93b906"
}
字段说明
transactionId交易 ID,用于 GET /v1/transactions/{id} 与取消
withdrawalId平台内部提现单 ID
status / subStatus对外状态,提交时为 SUBMITTED
state平台内部状态(仅供排查,可能增加取值,请勿依赖)
reservedRaw已从可用余额冻结的金额 = amountRaw + feeRaw
destination规范化后的收款地址

站内结算(settlement = OFF_CHAIN,包括 ONE_TIME_ADDRESS 被识别为本租户地址的情况):

json
{
  "settlement": "OFF_CHAIN",
  "transferId": "0192a4e1-0100-7200-8300-040506070809",
  "transactionId": "0192a4e1-0200-7300-8400-05060708090a",
  "status": "COMPLETED",
  "fromWalletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a",
  "toWalletId": "0192a4c3-1111-7222-8333-444455556666",
  "assetId": "USDT_ERC20",
  "amount": "2000000",
  "fee": "0"
}
字段说明
statusCOMPLETED(已到账)或 PENDING_AUTHORIZATION(命中租户审批策略,资金已冻结,待管理员审批)
amount / fee金额与手续费(最小单位字符串;注意此处字段名没有 Raw 后缀)

幂等重放:用相同的 externalTxId(或 Idempotency-Key)和相同请求体重试,返回与第一次完全相同的状态码和响应体,不会重复扣款。

常见错误

HTTPcode场景
422BAD_REQUESTJSON 格式或字段类型错误;source.type must be WALLET;externalTxId must be 1-128 chars;无 externalTxId 时缺少 Idempotency-Key;END_USER needs exactly one of uid / customerRefId;amount must be positive
403FORBIDDEN付款用户已冻结(user is frozen)
403TWO_FACTOR_REQUIRED / TWO_FACTOR_INVALID / COOLDOWN_ACTIVE开启了终端用户两步验证时,见 下文
403BLOCKED_BY_POLICY站内转账被租户策略拦截
404NOT_FOUND付款或收款钱包不存在 / 不属于本租户(wallet not found)
404RECIPIENT_NOT_FOUNDEND_USER 收款人不存在,或已被冻结(recipient unavailable)
409IDEMPOTENCY_CONFLICT幂等键对应不同请求体;上一次请求仍在处理;externalTxId already used(被另一个 API Key 使用过)
422INSUFFICIENT_BALANCE可用余额不足以支付 amountRaw + 手续费
422INVALID_ADDRESS地址格式错误、EIP-55 校验失败、BTC 网络不匹配、SOL 非钱包地址
422INTERNAL_DESTINATION_NOT_ALLOWED收款地址是平台运营地址
422SAME_WALLET_TRANSFER收款方就是付款钱包本身
422SAME_USER_USE_WALLET_TRANSFEREND_USER 指向付款用户自己
422RECIPIENT_NO_WALLET收款用户在该链族下没有默认钱包
422ASSET_NOT_SUPPORTED未知 assetId
422ASSET_MISMATCH资产与钱包链族不符,或收付双方钱包链族不同,或资产不可用
422ASSET_DISABLED该资产/网络当前不允许链上提现
422NETWORK_DISABLED资产所在网络未对本租户开通
422WALLET_NOT_ACTIVE付款钱包不是 ACTIVE,或收款钱包不能收款
422BELOW_MIN_WITHDRAWAL链上提现金额低于 minWithdraw
422LIMIT_EXCEEDED超过单笔限额或每日限额
429RATE_LIMITED限流(重新签名后退避重试)
500 / 503INTERNAL / PROVIDER_UNAVAILABLE / SIGNER_UNAVAILABLE可重试:用相同请求体与 externalTxId 重试

链上提现被受理(202)之后的反洗钱、审批、签名、广播等环节失败不会以 HTTP 错误返回,而是体现为交易状态(REJECTED、FAILED 等),见 交易状态。

终端用户两步验证(X-User-2FA-Code) ​

租户后台 设置 → API 出金需终端用户两步验证(apiRequireUser2fa),默认关闭:

  • 关闭(默认):API 签名即可发起提现/转账,用户的二次验证由交易所自己负责。
  • 开启:POST /v1/transactions(所有收款方类型)必须带请求头 X-User-2FA-Code: <付款用户当前的 6 位 TOTP 码>。

开启后的校验与错误:

情况结果
付款用户没有绑定 TOTP(用户对象 totpEnabled = false)403 TWO_FACTOR_REQUIRED(bind TOTP before moving funds)
用户处于安全冷静期403 COOLDOWN_ACTIVE
缺少 X-User-2FA-Code403 TWO_FACTOR_REQUIRED(TOTP code required)
15 分钟内校验超过 10 次429 RATE_LIMITED
验证码错误,或该验证码已被使用过(每个验证码只能用一次)403 TWO_FACTOR_INVALID

TOTP 由用户在托管 C 端绑定;B 端接口不提供绑定能力,开启此选项前请确认你的用户都已绑定。

估算手续费 ​

http
POST /v1/transactions/estimate_fee

按与提现相同的规则计算手续费,并告诉你该地址会走链上还是站内。不冻结资金、不创建交易。

请求体

字段类型必填说明
assetIdstring是资产 ID
sourceWalletIdstring (UUID)是付款钱包 ID
amountRawstring是收款金额(最小单位),大于 0
destinationstring是收款地址字符串
json
{
  "assetId": "USDT_ERC20",
  "sourceWalletId": "0192a4c1-8b10-7e22-b3a1-6f1e2d3c4b5a",
  "amountRaw": "10000000",
  "destination": "0x90f79bf6eb2c4f870365e785982e1f101e93b906"
}

响应 200 OK

json
{
  "assetId": "USDT_ERC20",
  "amountRaw": "10000000",
  "feeRaw": "2500000",
  "totalRaw": "12500000",
  "destination": "0x90f79bf6eb2c4f870365e785982e1f101e93b906",
  "isInternal": false,
  "settlement": "ON_CHAIN",
  "networkFeePaidBy": "PLATFORM",
  "validUntil": "2026-10-03T07:02:00.100000Z"
}
字段说明
feeRaw将收取的手续费(链上:提现手续费;站内:站内转账费或 0)
totalRaw付款钱包需要的可用余额 = amountRaw + feeRaw
destination规范化后的地址
isInternal / settlement是否为本租户地址(站内结算)
networkFeePaidBy历史标记固定 PLATFORM,表示链上付款方;租户金库代付网络费,用户充提成本通过手续费承担
validUntil估算有效期(约 2 分钟)。实际提现时会重新计算

常见错误:与 发起提现 中地址、资产、金额、限额相关的错误相同(INVALID_ADDRESS、BELOW_MIN_WITHDRAWAL、ASSET_DISABLED、LIMIT_EXCEEDED、INTERNAL_DESTINATION_NOT_ALLOWED 等);钱包不存在为 404 NOT_FOUND。

查询交易 ​

http
GET /v1/transactions/{id}

响应 200 OK:交易对象。常见错误:404 NOT_FOUND(transaction not found)。

按 externalTxId 查询 ​

http
GET /v1/transactions/external_tx_id/{externalTxId}

用你方单号查询(路径参数需 URL 编码)。提交超时后用它确认交易是否已创建。

响应 200 OK:交易对象。常见错误:404 NOT_FOUND。

交易列表 ​

http
GET /v1/transactions?customerRefId=u-10001&kind=DEPOSIT&status=COMPLETED&createdFrom=2026-10-01T00:00:00Z&createdTo=2026-10-02T00:00:00Z&limit=200

查询参数(均可选,可组合)

参数类型说明
walletIdUUID付款或收款钱包为该钱包
customerRefIdstring付款或收款用户为该用户
kindstringDEPOSIT / WITHDRAWAL / INTERNAL_TRANSFER
statusstring对外状态,如 COMPLETED
assetIdstring资产 ID
createdFromRFC 3339创建时间下界(含)
createdToRFC 3339创建时间上界(不含)
limitinteger1–200,默认 50
beforeUUID上一页的 nextBefore

响应 200 OK

json
{
  "items": [ { "id": "0192a4c9-2f00-7aaa-8bbb-ccccdddd0001", "kind": "DEPOSIT", "status": "COMPLETED", "…": "交易对象的其余字段" } ],
  "nextBefore": null
}

按创建时间倒序。常见错误:422 BAD_REQUEST(createdFrom/createdTo must be RFC 3339)。

取消提现 ​

http
POST /v1/transactions/{id}/cancel

取消尚未进入签名阶段的链上提现,冻结的 amountRaw + feeRaw 退回可用余额。无请求体。

可以取消的状态:SUBMITTED、PENDING_AUTHORIZATION、QUEUED(含 subStatus = INSUFFICIENT_FUNDS_PLATFORM)。进入 PENDING_SIGNATURE 及之后的状态不能取消。站内转账不能取消。

响应 200 OK

json
{
  "withdrawalId": "0192a4e0-5b00-7c00-8d00-0e0f10111213",
  "transactionId": "0192a4e0-5c00-7d00-8e00-0f1011121314",
  "status": "CANCELLED",
  "subStatus": "CANCELLED_BY_USER",
  "state": "CANCELLED",
  "assetId": "USDT_ERC20",
  "amountRaw": "10000000",
  "feeRaw": "2500000",
  "reservedRaw": "12500000",
  "destination": "0x90f79bf6eb2c4f870365e785982e1f101e93b906"
}

同时推送 TRANSACTION_STATUS_UPDATED(status = CANCELLED)。

常见错误

HTTPcode场景
404NOT_FOUND交易不存在
409INVALID_STATEonly withdrawals can be cancelled;withdrawal can no longer be cancelled