申报一笔预付充值(主要用于线下结算)
x-idempotency-key
⚠ 这个端点不动任何余额,一分都不动。 它只登记一条**待处理的
申报**。入账永远发生在我方确认到账之后:链上那一档由到账事实驱动
自动入账,线下那一档走双人审批。
这不是保守,是这条线的定义:一个能自己给自己加预付余额的接口就是
无限授信。(同一条理由让 POST /v1/deposits —— 全系统唯一能凭空
产生会员余额的端点 —— 挂了六道闸。)
⚠ channel 缺省是 chain,而那多半不是你要的
判据是精确等于 fiat:缺省、拼错、FIAT、Fiat 全部落成
chain,且不报错。而链上那条腿你本来就不需要申报 ——
到账我方会自动落单并入账。你手工申报的那条 chain 记录**没有链上
交易号,永远不会自动入账**,它只会挂在待处理里等一个人去看。
申报电汇请显式传 "fiat"。
其余三件事
reference_no(汇款回单号)不是一个独立出参:它被并进note
并加上「回单号:」前缀,列表接口只回 note。这是刻意的 ——
不加前缀的话事后没有任何办法把它从备注里分出来,而线下结算的
对账全靠这个号。
amount是十进制串,且校验比商户后台严一档:必须匹配
「至多 20 位整数 + 至多 12 位小数」且为正,否则 400 invalid_fields
(带 fields 数组)。机器填的字段该有形状 —— 一条
amount: "大概五万" 的申报要等到审批人打开它才发现,
而那时你已经在等入账了。
asset必须在资产目录里且已启用,认不出一律拒、不兜底挑一个:
一条币种拼错的申报没有任何人能入账,它会一直挂在待处理里。
出参的 status 恒为 pending。后续进展轮询 GET /v1/merchant/topups;
这条线不发 Webhook。
⚠ 幂等窗口是 24 小时,过了窗口同键会落第二条申报
窗口内同键 + 同 body 拿回首次那份 201(带 X-Idempotent-Replay: true
响应头),不会落第二行。但这条线只有这一层幂等 —— 没有任何库级
约束兜底,所以一把 25 小时前用过的键会真的再建一条待处理申报,
而两条申报可能被两个人各审一次。补录历史时请逐条用新键,
别把键当成「这笔电汇的编号」长期复用。
前置条件
- 资产在
assets目录里且已启用 - 这把 Key 已获授
merchant:write(受限 scope,须我方单独审批)
请求头
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-idempotency-key |
string | 必填 | UUID v4。同键重放拿回同一条申报,不会落第二行 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
asset |
string | 必填 | 资产代码,大小写不敏感(服务端转大写)。认不出回 asset_not_allowed |
channel |
"chain" | "fiat" | 可选 | ⚠ 精确等于 fiat 才是法币那一档,其余一切取值
(含缺省与大小写变体)都静默落成 chain。 |
amount |
string | 必填 | 申报金额。十进制串且必须为正;至多 20 位整数、
12 位小数。落库时原样保留(amount_text)。"50000.00" |
reference_no |
string | 可选 | 汇款回单号,最长 64 字符。不会作为独立字段回显 ——
它以「回单号:<值>」的形式并进 note。 |
note |
string | 可选 | 备注。与 reference_no 拼接后整体截到 300 字符 |
响应
status 恒为 pending。{
"id": "5d2c8a41-3f6b-4e0a-9c77-1b8e0d4f2a56",
"asset": "USDT",
"channel": "fiat",
"amount_text": "50000.00",
"status": "pending"
}invalid_request body 非 JSON / 缺 asset ·
invalid_fields amount 不是一个正的十进制串(fields[].key = "amount")·
asset_not_allowed 资产不在目录里或已停用insufficient_scope 缺 merchant:write(受限 scope,
须我方单独审批才能授出 —— 勾了不等于拿到了)idempotency_key_reused · idempotency_in_progresscurl -X POST 'https://api.zise.com/v1/merchant/topups' \
-H 'x-auth-token: Bearer $TOKEN' \
-H 'x-idempotency-key: $IDEMPOTENCY_KEY' \
-H 'content-type: application/json' \
-d '{
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
}'const res = await fetch("https://api.zise.com/v1/merchant/topups", {
method: "POST",
headers: {
"x-auth-token": "Bearer $TOKEN",
"x-idempotency-key": "$IDEMPOTENCY_KEY",
"content-type": "application/json",
},
body: JSON.stringify({
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
}),
});
// 金额按字符串读,别让它变成 number
const data = await res.json();import requests
res = requests.post(
"https://api.zise.com/v1/merchant/topups",
headers={
"x-auth-token": "Bearer $TOKEN",
"x-idempotency-key": "$IDEMPOTENCY_KEY",
"content-type": "application/json",
},
json={
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
},
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()req, _ := http.NewRequest("POST", "https://api.zise.com/v1/merchant/topups",
strings.NewReader(`{
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
}`))
req.Header.Set("x-auth-token", "Bearer $TOKEN")
req.Header.Set("x-idempotency-key", "$IDEMPOTENCY_KEY")
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/merchant/topups"))
.header("x-auth-token", "Bearer $TOKEN")
.header("x-idempotency-key", "$IDEMPOTENCY_KEY")
.header("content-type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
}
"""))
.build();
// 金额字段用 String / BigDecimal,不要 double$ch = curl_init('https://api.zise.com/v1/merchant/topups');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-auth-token: Bearer $TOKEN',
'x-idempotency-key: $IDEMPOTENCY_KEY',
'content-type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"asset": "USDT",
"channel": "fiat",
"amount": "50000.00",
"reference_no": "TT20260813001",
"note": "8 月备付金"
}
JSON,
]);
$res = curl_exec($ch);
// 金额用 bcmath / 字符串,不要 floatval
{
"id": "5d2c8a41-3f6b-4e0a-9c77-1b8e0d4f2a56",
"asset": "USDT",
"channel": "fiat",
"amount_text": "50000.00",
"status": "pending"
}