/v1/remit/payee-form-schema
该走廊要填哪些字段(先验走廊再给表单)
remittances:read
商户自身
这是这条线上最要紧的一个只读端点。理由是**上游建档发生在「分发」
那一步,不在「提交收款人」那一步**:本地漏校一条格式,代价不是
一次 400,而是钱已经冻进 locked 桶之后才发现这个收款人
建不出来 —— 而那时订单卡在 dispatching,收款人被上游钉成
failed 终态,只能人工处置。
所以:别在你那一侧硬编码字段清单。 拿这份契约渲染表单、
拿它的 pattern / max_length / required 做前端校验、
提交时把用户填的原样放进 POST /v1/remit/payees 的 fields。
我方加一个国家、加一条清算网络、收紧一条格式,你一行不用改。
字段是按走廊求值出来的,不是一张固定表。同样是「个人」,
GB/GBP 要 IBAN + 6 位 sort code,US/USD/ACH 要账号 + ABA,
SG/SGD 连姓名和地址都免填(上游明写不需要)。
⚠ 只下发「必填、或参与指纹、或文档措辞模糊」的字段 ——
表单上多一个永远用不到的框,用户只会以为自己漏填了什么。
于是 required: false 的字段不是可有可无:它多半参与收款人
指纹(in_fingerprint: true),填与不填决定这次是新建还是
关联到已有收款人。
⚠ 入参是 snake_case(country_code),而出参的 corridor
对象是 camelCase(countryCode)—— 原样回显我方内部形态。
别把出参直接回灌进入参。
⚠ bind 的语义:该字段被填写时要一起提交的固定值。
例如 GBP + FASTER PAYMENTS 的 6 位 sort code,字段是
bank_details.routing_code_value1,同时必须带
bank_details.routing_code_type1: sort_code。类型由走廊唯一决定,
不让用户选 —— 让他选就是给了一个改路由类型的口子,
而上游对这一维根本不校验,错的类型会让钱走错清算轨道。
⚠ pending_confirm 有值 = 上游文档措辞模糊,我方按更宽松处理:
可以提示「选填」但仍允许提交。照文档补校验会当天挡住合法用户。
前置条件
- 走廊必须在你的清单里且已启用(受限辖区、上游已下架的一律拒)
- 我方必须能为这条走廊确认一个路由码类型;确认不了一律拒并指向 SWIFT
查询参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
country_code |
string | 必填 | 收款银行所在国家,两位大写。别名 country。 |
currency |
string | 必填 | 到账币种,三位大写。 |
payment_method |
string | 必填 | LOCAL 或 SWIFT。别名 method。 |
clearing_system |
string | 必填 | 清算网络,如 FASTER PAYMENTS / ACH / PAYNOW / CHATS。
大小写原样传(其余四项我方会转大写,这一项不动)。
别名 clearing。 |
entity_type |
"INDIVIDUAL" | "COMPANY" | 必填 | 收款人是个人还是公司。别名 entity。 |
响应
fields 已按「组序 → 组内序」排好,顺序渲染即可;
同一个 group 的字段一定连续出现(分步向导一组一屏)。
组序固定为 payee → bank → account → address → extra。{
"corridor": {
"countryCode": "GB",
"currency": "GBP",
"paymentMethod": "LOCAL",
"clearingSystem": "FASTER PAYMENTS",
"entityType": "INDIVIDUAL"
},
"fields": [
{
"key": "first_name",
"label_key": "payee.first_name",
"type": "text",
"group": "payee",
"order": 10,
"width": "half",
"required": true,
"max_length": 45,
"in_fingerprint": false
},
{
"key": "last_name",
"label_key": "payee.last_name",
"type": "text",
"group": "payee",
"order": 20,
"width": "half",
"required": true,
"max_length": 45,
"in_fingerprint": false
},
{
"key": "bank_details.account_holder",
"label_key": "payee.account_holder",
"type": "text",
"group": "payee",
"order": 40,
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "bank_details.swift_code",
"label_key": "payee.swift_code",
"type": "text",
"group": "bank",
"order": 10,
"required": true,
"pattern": "^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$",
"normalize": "alnum_upper",
"in_fingerprint": true
},
{
"key": "bank_details.bank_name",
"label_key": "payee.bank_name",
"type": "text",
"group": "bank",
"order": 20,
"required": true,
"in_fingerprint": false
},
{
"key": "bank_details.bank_address",
"label_key": "payee.bank_address",
"type": "text",
"group": "bank",
"order": 30,
"required": true,
"in_fingerprint": false
},
{
"key": "bank_details.account_number",
"label_key": "payee.account_number",
"type": "text",
"group": "account",
"order": 10,
"required": false,
"pattern": "^[a-zA-Z0-9]*$",
"normalize": "alnum_upper",
"in_fingerprint": true
},
{
"key": "bank_details.iban",
"label_key": "payee.iban",
"type": "text",
"group": "account",
"order": 20,
"required": true,
"normalize": "alnum_upper",
"in_fingerprint": true
},
{
"key": "bank_details.routing_code_value1",
"label_key": "payee.routing.sort_code",
"type": "text",
"group": "account",
"order": 30,
"required": true,
"pattern": "^[0-9]{6}$",
"normalize": "alnum_upper",
"in_fingerprint": true,
"bind": {
"bank_details.routing_code_type1": "sort_code"
}
},
{
"key": "additional_info.proxy_id",
"label_key": "payee.proxy_id",
"type": "text",
"group": "account",
"order": 50,
"required": false,
"normalize": "trim",
"in_fingerprint": true
},
{
"key": "address.country",
"label_key": "payee.country",
"type": "text",
"group": "address",
"order": 10,
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "address.state",
"label_key": "payee.state",
"type": "text",
"group": "address",
"order": 20,
"width": "half",
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "address.city",
"label_key": "payee.city",
"type": "text",
"group": "address",
"order": 30,
"width": "half",
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "address.street_address",
"label_key": "payee.street",
"type": "text",
"group": "address",
"order": 40,
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "address.postal_code",
"label_key": "payee.postal_code",
"type": "text",
"group": "address",
"order": 50,
"required": true,
"normalize": "trim",
"in_fingerprint": false
},
{
"key": "additional_info.organization_code",
"label_key": "payee.organization_code",
"type": "text",
"group": "extra",
"order": 50,
"required": false,
"in_fingerprint": false,
"pending_confirm": "上游文档未写「Required when」,只说用于中国大陆注册的企业"
}
],
"fingerprint_keys": [
"bank_details.swift_code",
"bank_details.account_number",
"bank_details.iban",
"bank_details.routing_code_value1",
"additional_info.proxy_id"
],
"pending_count": 1
}corridor_not_supported 四段没填全 / 这条走廊未启用 / 受限辖区 /
我方没有一个能确认的路由码类型。处置不是重试,是换一条走廊
(多数情况下改用同国的 SWIFT 就能走)。curl -X GET 'https://api.zise.com/v1/remit/payee-form-schema' \
-H 'authorization: Bearer $TOKEN' \
-H 'x-zise-merchant: $MERCHANT_ID'
const res = await fetch(
"https://api.zise.com/v1/remit/payee-form-schema",
{
method: "GET",
headers: {
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "MERCHANT_ID"
},
},
);
// 金额一律按字符串读,不要 JSON.parse 成 number
const data = await res.json();
import requests
res = requests.get(
"https://api.zise.com/v1/remit/payee-form-schema",
headers={
"authorization": "Bearer $TOKEN",
"x-zise-merchant": "$MERCHANT_ID"
},
)
# 金额用 Decimal(str(...)),不要 float
data = res.json()