提交会员 L1 KYC(服务端直交)
商户自身
需
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
}400
invalid_request · product_not_available · state_invalid404
member_not_found · card_product_not_found409
idempotency_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 接,不要 float64HttpRequest 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
}