Z Zise Developers

提交会员 L1 KYC(服务端直交)

POST /v1/kyc/applications scope: kyc:write
商户自身 需 x-idempotency-key

给这个会员交一份人级 L1 实名档案。审核按人,不是按卡头:一个人同时只能有一份未驳回的档案。card_product_id 可选:传了只把这次提交挂到你目录里看得见的一款产品上(盖快照);省略则只交人档。不要自己传发卡方或 BIN。

L1 通过之后,开第二款、第三款卡直接走 POST /v1/cards/applications(换 product_id),不必再调本接口。开卡闸只看这个人的 L1 是否已通过。

同一商户 + 会员 + 同一产品,未终态或已通过再交 → 200 回已有单。被驳回的可以再交。第一份还在 pending 时去交另一款产品会state_invalid —— 等 GET /v1/kyc 出结论,不要并行交两份。

L1 已经 approved 时若仍对本接口换一款产品再打一次,只会补一条已通过快照(profile 可空对象),不是再审一遍,开卡也不依赖它。

轮询结论用 GET /v1/kyc。提交当时不推 webhook;通过 / 驳回 / 补件才发 kyc.result.updated。

字段类型必填说明
x-idempotency-key string 必填
x-on-behalf-of string 必填 会员的 external_member_id 或 mem_<uuid>。

请求体

字段类型必填说明
card_product_id string 可选 可选。卡产品标识(可带 cpd_ 前缀),取自 GET /v1/cards/products。 传了只盖一枚产品快照,开卡不读它;省略则只交人档。 通过后开其他产品改走开卡接口的 product_id。
profile object 必填 会员 L1 实名资料。首次提交必须完整。 L1 已通过后再调本接口时可为 {}。

响应

201已受理人级 L1(status=pending)。不传 card_product_id 时 id 为人级 kyc_<id>、card_product_id 为空串;传了产品则仍 可能为该产品补一条 approved 快照。开其他卡产品以 GET /v1/kyc 的人级结论为准。
{
  "id": "cpkyc_visa_virtual_usd_42",
  "card_product_id": "visa_virtual_usd",
  "kyc_id": "42",
  "status": "pending",
  "level": 0
}
400invalid_request · product_not_available · state_invalid
404member_not_found · card_product_not_found
409idempotency_key_required · idempotency_key_reused
请求
curl -X POST 'https://api.zinfra.vip/v1/kyc/applications' \
  -H 'x-auth-token: Bearer $TOKEN' \
  -H 'x-idempotency-key: $IDEMPOTENCY_KEY' \
  -H 'content-type: application/json' \
  -d '{
    "profile": {
      "first_name": "Jane",
      "last_name": "Doe",
      "nationality": "US"
    }
  }'
const res = await fetch("https://api.zinfra.vip/v1/kyc/applications", {
  method: "POST",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
    "x-idempotency-key": "$IDEMPOTENCY_KEY",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "profile": {
      "first_name": "Jane",
      "last_name": "Doe",
      "nationality": "US"
    }
  }),
});
// 金额按字符串读,别让它变成 number
const data = await res.json();
import requests

res = requests.post(
    "https://api.zinfra.vip/v1/kyc/applications",
    headers={
        "x-auth-token": "Bearer $TOKEN",
        "x-idempotency-key": "$IDEMPOTENCY_KEY",
        "content-type": "application/json",
    },
    json={
      "profile": {
        "first_name": "Jane",
        "last_name": "Doe",
        "nationality": "US"
      }
    },
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()
req, _ := http.NewRequest("POST", "https://api.zinfra.vip/v1/kyc/applications",
    strings.NewReader(`{
  "profile": {
    "first_name": "Jane",
    "last_name": "Doe",
    "nationality": "US"
  }
}`))
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 接,不要 float64
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.zinfra.vip/v1/kyc/applications"))
    .header("x-auth-token", "Bearer $TOKEN")
    .header("x-idempotency-key", "$IDEMPOTENCY_KEY")
    .header("content-type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
{
  "profile": {
    "first_name": "Jane",
    "last_name": "Doe",
    "nationality": "US"
  }
}
"""))
    .build();
// 金额字段用 String / BigDecimal,不要 double
$ch = curl_init('https://api.zinfra.vip/v1/kyc/applications');
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'
{
  "profile": {
    "first_name": "Jane",
    "last_name": "Doe",
    "nationality": "US"
  }
}
JSON,
]);
$res = curl_exec($ch);
// 金额用 bcmath / 字符串,不要 floatval
201
{
  "id": "cpkyc_visa_virtual_usd_42",
  "card_product_id": "visa_virtual_usd",
  "kyc_id": "42",
  "status": "pending",
  "level": 0
}