兑换报价(默认只读;带 lock 才锁价)
代会员调用 · 必带
x-on-behalf-of
两种用法,由你在请求体里选:
- 不带
lock(缺省) —— 只读,不建单、不锁钱、不返回quote_id。
用途是给你的界面显示一个数;成交那一刻会按当时的价重新算。
lock: true—— 锁价。返回quote_id与quote_expires_at,
在到期之前拿它去 POST /v1/exchange/orders,按这份报价成交。
过期后再拿它成交一律被拒,我方不会按新价替你成交 ——
那等于替你做了一次你没同意的定价。
⚠ quote_id 就是这一单的订单号(同一个 exc_<uuid>)。锁价在我方
建的是一张真的订单行、状态 quoted,所以:它会出现在
GET /v1/exchange/orders 里(状态 quoted),可以用
GET /v1/exchange/orders/{id} 查 —— **成交请求超时时不要盲目重投,
先用这个 id 查一次它到底成没成**。没被用掉的锁价到期即作废,
不产生任何资金动作。
⚠ 锁的是价,不是授权。 成交那一刻照样跑全部闸:账户处置、方向
停用、强认证要求、日限额、余额、你的预付。锁价只保证「用哪套数字」。
⚠ 锁价不是默认行为,请按需索取。 一是这个端点常被当成价格展示口
高频调用,无条件建单会把你用来对账的订单清单灌满从未成交的 quoted
行;二是一份锁定的报价在窗口内对你是单向有利的,我方按需发放。
⚠ lock 必须是 JSON 布尔。传 "true" / 1 一律
invalid_fields,不会被当成 false 静默放过。
⚠ 入参是 from_amount 不是 amount(成交端点同)。传错的表现是
金额解析不出来 → invalid_request。
⚠ 幂等键在这个端点上是可选的:不锁价时它什么也不做;锁价时带上
它,超时重发会拿回同一份锁价,而不是攒出两张只有一张会被用掉的
报价单。
前置条件
- 该方向已启用(按方向配,
USDT→USD与USD→USDT互不影响) - 会员未被冻结 / 销户,且满足该方向的最低实名等级
请求头
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-on-behalf-of |
string | 必填 | 代哪个会员报价。报价按该会员的商户配置取费率与限额。 |
x-idempotency-key |
string | 可选 | 可选。只在 lock: true 时有意义:同一把键 + 同一个方向 + 同一个
金额,重发拿回同一份锁价(不会攒出第二张报价单)。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
from_asset |
string | 必填 | 源资产代码,如 USDT。大小写不敏感(服务端转大写)。 |
to_asset |
string | 必填 | 目标资产代码,如 USD。与 from_asset 相同会被拒。 |
from_amount |
string | 必填 | 源资产扣减数量。字符串定点,位数 = from_asset 的
ledger_scale。小数位超出且尾数非零一律拒,不四舍五入。USDT 是 6 位,形如 500.000000 |
lock |
boolean | 可选 | 是否锁价。缺省 false = 只读报价,响应里没有
quote_id 这个字段(不是 null —— 它压根不出现)。
true 时返回 quote_id + quote_expires_at,
在到期之前拿它去成交即按这份报价成交。
⚠ 必须是 JSON 布尔。"true" / 1 一律 invalid_fields。 |
响应
200报价成功。
fee_asset 可能是 from 侧也可能是 to 侧
(由该方向的配置决定),所以它单独带一个资产代码,
别假定它等于其中任何一个。
quote_id 与 quote_expires_at 只在你传了 lock: true 时出现。
quote_ttl_sec 两种情况下都给,但读法不同:锁了价它是一把真的锁
的窗口,没锁时它只是「这个数大约在多久内还算数」的参考值。{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"to_amount": "498.750000",
"rate": "1.0000",
"fee_amount": "1.250000",
"fee_asset": "USD",
"quote_id": "exc_7a1e5c30-2b44-4c11-9f8e-31d0a7b62c45",
"quote_expires_at": "2026-08-13T09:31:30Z",
"quote_ttl_sec": 90,
"ledger_scale_from": 6,
"ledger_scale_to": 6
}400已登记的对外码:
invalid_request 请求体不合法 / 金额格式不对 /
缺资产代码 · invalid_fields lock 不是布尔 ·
step_up_required 该方向要求强认证 —— 开放 API 不发这一档的锁价
凭据(发一份注定成交不了的报价只是把失败推迟 90 秒)·
request_rejected 该会员被冻结、销户或命中风控 ·
service_unavailable 这条线此刻不可用 ·
member_context_required · member_not_found
⚠ 还落在 500 api_error 的业务拒绝(见 info 里那一节):
方向未启用 / 资产已下架 · from 与 to 相同 · 低于起兑额 ·
高于单笔上限 · 超日累计额或日笔数 · 实名等级不足 ·
汇率暂不可用 · 手续费吃光了本金。收到 500 时不要无限重试。403
insufficient_scope —— 这把 Key 没有 exchange:write请求
curl -X POST 'https://api.zise.com/v1/exchange/quotes' \
-H 'x-auth-token: Bearer $TOKEN' \
-H 'x-on-behalf-of: $MEMBER_ID' \
-H 'content-type: application/json' \
-d '{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
}'const res = await fetch("https://api.zise.com/v1/exchange/quotes", {
method: "POST",
headers: {
"x-auth-token": "Bearer $TOKEN",
"x-on-behalf-of": "$MEMBER_ID",
"content-type": "application/json",
},
body: JSON.stringify({
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
}),
});
// 金额按字符串读,别让它变成 number
const data = await res.json();import requests
res = requests.post(
"https://api.zise.com/v1/exchange/quotes",
headers={
"x-auth-token": "Bearer $TOKEN",
"x-on-behalf-of": "$MEMBER_ID",
"content-type": "application/json",
},
json={
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
},
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()req, _ := http.NewRequest("POST", "https://api.zise.com/v1/exchange/quotes",
strings.NewReader(`{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
}`))
req.Header.Set("x-auth-token", "Bearer $TOKEN")
req.Header.Set("x-on-behalf-of", "$MEMBER_ID")
req.Header.Set("content-type", "application/json")
res, err := http.DefaultClient.Do(req)
// 金额字段用 string 接,不要 float64HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.zise.com/v1/exchange/quotes"))
.header("x-auth-token", "Bearer $TOKEN")
.header("x-on-behalf-of", "$MEMBER_ID")
.header("content-type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
}
"""))
.build();
// 金额字段用 String / BigDecimal,不要 double$ch = curl_init('https://api.zise.com/v1/exchange/quotes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-auth-token: Bearer $TOKEN',
'x-on-behalf-of: $MEMBER_ID',
'content-type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"lock": true
}
JSON,
]);
$res = curl_exec($ch);
// 金额用 bcmath / 字符串,不要 floatval
200
{
"from_asset": "USDT",
"to_asset": "USD",
"from_amount": "500.000000",
"to_amount": "498.750000",
"rate": "1.0000",
"fee_amount": "1.250000",
"fee_asset": "USD",
"quote_id": "exc_7a1e5c30-2b44-4c11-9f8e-31d0a7b62c45",
"quote_expires_at": "2026-08-13T09:31:30Z",
"quote_ttl_sec": 90,
"ledger_scale_from": 6,
"ledger_scale_to": 6
}