鉴权与签名
两段式:API Key 换令牌,令牌调业务。写请求还要再过一道签名。
第一段:换令牌
一把 API Key 建出来的时候下发两个值,用途不同,别混:
| 值 | 用途 | 我方存的形态 |
|---|---|---|
api_key | 换令牌 | 只存哈希,创建时展示一次,之后取不回来 |
signing_key | 请求验签(HMAC) | 可取回(对称密钥,两边都要有原文) |
POST /v1/connect/token
x-zise-merchant: <你的商户短码>
content-type: application/json
{ "api_key": "sk_live_…" }
令牌有效期 30 分钟。过期前换一把新的即可,我方不提供 refresh —— 换令牌本身
就是一次轻量调用,再加一条 refresh 链路只会多一个会过期的东西。
第二段:调业务
authorization: Bearer <token>
x-zise-merchant: <你的商户短码>
x-on-behalf-of: <会员标识> # 只有「代会员」的端点要
哪些端点要 x-on-behalf-of,每个端点页顶部的徽章上写着。
签名
写请求默认强制签名,POST /v1/deposits 的签名不可关闭——
它是全系统唯一一个凭空产生会员余额的端点。
签名串是五段,用 \n 连接:
METHOD
/v1/path?with=query
x-timestamp
x-nonce
sha256_hex(raw_body)
signature = hex(HMAC_SHA256(signing_key, 签名串)),放进 x-signature。
四条会让你调不通的细节:
- PATH 必须进签名串(含 query)。这是防「同一份 body 被重放到另一个端点」的
唯一手段 —— 少了它,一笔 /v1/transfers 的签名可以原样打到别处。
- 用 raw body 算哈希,不要重新序列化。 你的 JSON 库和我方的键顺序、空格、
Unicode 转义几乎一定不同,重新序列化出来的哈希对不上,而错误长得像「密钥不对」。
- 空 body 的 sha256 是定值:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-timestamp是秒,容差 ±300 秒。机器时钟漂了就会全线 401。
x-nonce 每次换新,我方落库 5 分钟内不可二用。nonce 的消费发生在验签之后——
放在之前的话,任何人拿一个猜的 nonce 就能把你的合法 nonce 提前烧掉。
环境
判据是你打的域名,不是请求头。
| 环境 | 域名 |
|---|---|
| 生产 | https://api.zise.com |
| 沙盒 | https://api-sandbox.zise.com |
跨环境凭据一律拒,且返回专门的码 environment_mismatch,不是笼统的
「凭据无效」—— 沙盒 Key 打到生产上是接入期最常见的一次卡壳,把它和「密钥配错了」
分开能省掉一轮排查。
IP 白名单
Live 环境的 Key 强制非空。四种写法都收:单 IP、CIDR(/8 /16 /24 /28)、
多条逗号分隔。
⚠ 认不出的写法一律不匹配(宁可漏放不可错放)。所以填错格式的表现是
「全部请求 403」,而不是「白名单没生效」—— 这是刻意的:后者是个静默的洞。
被拒时返回 ip_not_allowed,响应里不回显你配了什么 —— 那等于把白名单
念给调用方听。到商户后台的「开发者 → API Keys」里看。