/v1/remit/quotes
汇款试算(不建单不冻结;必读 applied_rate)
remittances:read
代会员调用 · 必带 x-on-behalf-of
不建单、不冻结、不写任何库、不带幂等键。 纯读 + 纯算,
可以随用户输入连续调。
两个方向二选一:
- 给
payout_amount= 「收款人收多少」→ 算出customer_total; - 给
source_amount= 「我出多少」→ 反算出payout_amount,
且保证正向算回来的 customer_total ≤ 你说的那个数
(每步向下取整;反了就是未经同意的多扣)。
两个都给或都不给一律 400 —— 静默挑一个会让另一个数字看起来被忽略了。
必读:indicative_rate 与 applied_rate 是两个数
indicative_rate 是上游此刻报的价,applied_rate 是**实际用来
折算到账额的那个价**(前者折保守幅度之后)。只拿前者算,
你的界面上三个数字推不出到账金额 —— 2026-08-10 实测差 2.37%,
而差额不出现在任何一项费用里。给用户看 applied_rate,
indicative_rate 留给复盘。
两个都不是成交价。成交价在分发那一刻确定,由用户设的滑点上限罩着。
汇率取不到是 200,不是 5xx
rate_available: false + reason 说明为什么,手续费仍然给
(那部分本地算得出)。把汇率那一格标成不可用,其余照常渲染 ——
一起藏起来会让用户以为整个功能坏了。
reason 的三种取值处置完全不同:
remit_settlement_unconfigured我方配置问题,用户等也没用;remit_rate_unavailable上游暂时取不到,稍后重试有意义;remit_amount_too_small伴随amount_too_small: true,
用户改个数字就能解决 —— 别把它渲染成「稍后再试」。
below_min 由我方判,你不要自己再比一次
你手里有 min_amount,但真正的判据在 payout 网格上,你算不出来
(没有费率、没有折价、没有锚定汇率)。自己比的下场:用户填「我出
10 USDT」而最低额正好是 10,被你自己的界面挡住 —— 往返换算的量化
误差让 customer_total 落在 9.999115。
⚠ line 传了认不出的值会静默回落到 express,不报错。
⚠ 出参会原样回显 line / source_asset / source_amount ——
拿它们判断「这份响应是不是我这次输入算出来的」(响应到达顺序 ≠
发出顺序)。反方向上这件事没有别的判据。
前置条件
- 这条业务线对你已开通且我方已配好结算币
- 源资产已启用且可支付、锚定为固定值
- 收款人在这个会员名下
请求头
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-on-behalf-of |
string | 必填 | 代哪个会员调用(费率与限额都是会员维度的)。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
payee_id |
string | 必填 | 收款人号。pye_ 前缀可带可不带;剥掉后必须是纯数字。 |
line |
"express" | "pobo" | 可选 | 业务线。express 极速(付款主体是平台)、
pobo 个人汇款(付款主体是该会员自己的上游子账户)。
缺省 express;认不出的值静默按 express 处理。 |
asset |
string | 可选 | 从哪个资产扣款。缺省 USDT。 |
payout_amount |
string | 可选 | 收款人收多少(目标币)。与 source_amount 二选一。
位数由币种决定,多给一位会被上游以格式拒。GBP 为 2 位:"380.00";JPY 为 0 位:"50000" |
source_amount |
string | 可选 | 这个会员最多出多少(源资产)。与 payout_amount 二选一。
字符串定点,位数 = 该资产 ledger_scale。USDT 为 6 位:"500.000000" |
响应
rate_available: false +
reason(见正文),那时只有 fee_bps / fee_fixed /
source_asset 三项可用。{
"rate_available": true,
"line": "express",
"source_asset": "USDT",
"payout_currency": "GBP",
"payout_amount": "380.00",
"source_amount": "",
"payer_name": "",
"customer_total": "499.980000",
"below_min": false,
"min_amount": "10.000000",
"fee": "2.480000",
"fee_bps": 50,
"fee_fixed": "1.000000",
"indicative_rate": "1.2899",
"applied_rate": "1.2743",
"slippage": {
"default_bps": 100,
"min_bps": 50,
"max_bps": 1000
}
}invalid_request 两个金额都给了 / 都没给 / payee_id 不是数字 /
请求体不是合法 JSON。
resource_not_found 这个收款人不在这个会员名下。
product_not_available 这条业务线未对你开通,或源资产不可用。
invalid_fields 金额本身算不出来(位数超过记账精度等)。curl -X POST 'https://api.zise.com/v1/remit/quotes' \
-H 'authorization: Bearer $TOKEN' \
-H 'x-zise-merchant: $MERCHANT_ID' \
-H 'x-on-behalf-of: $MEMBER_ID' \
-H 'content-type: application/json' \
-d '{
"payee_id": "pye_1042",
"line": "express",
"asset": "USDT",
"payout_amount": "380.00"
}'
const res = await fetch(
"https://api.zise.com/v1/remit/quotes",
{
method: "POST",
headers: {
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "MERCHANT_ID",
"x-on-behalf-of": "MEMBER_ID",
"content-type": "application/json"
},
body: JSON.stringify({
"payee_id": "pye_1042",
"line": "express",
"asset": "USDT",
"payout_amount": "380.00"
}),
},
);
// 金额一律按字符串读,不要 JSON.parse 成 number
const data = await res.json();
import requests
res = requests.post(
"https://api.zise.com/v1/remit/quotes",
headers={
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "$MERCHANT_ID",
"x-on-behalf-of": "$MEMBER_ID",
"content-type": "application/json"
},
json={
"payee_id": "pye_1042",
"line": "express",
"asset": "USDT",
"payout_amount": "380.00"
},
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()