通用接入规范(签名 / 鉴权 / 错误码)
本页汇总诺正通所有 API 接口共享的接入规范:webservice + MD5 签名鉴权机制、 通用鉴权参数、返回结构、错误码体系。无论您接入哪个产品接口, 请先阅读本页。
① 通用鉴权参数
所有 API 接口(身份证、手机号、银行卡、人脸、短信)都共享以下 3 个鉴权参数,缺一不可。
| 参数名 | 中文名 | 必填 | 说明 |
|---|---|---|---|
| mall_id | 商户ID | 必填 | 在诺正通申请开通后获得的商户唯一标识 |
| tm | 时间戳 | 必填 | 13 位毫秒级时间戳,防重放(注意:短信接口 /sms.php 不使用 tm) |
| sign | 签名字符串 | 必填 | MD5 签名;各接口拼接顺序不同,详见下方签名顺序表 |
除上述 3 个公参外,每个接口还有专属的"业务参数"(如身份证接口需要 realname + idcard)。 请前往对应产品页查看:身份证核验手机号核验银行卡核验人脸识别短信验证码身份证 OCR
② 签名规则
md5(mall_id + 业务参数 + tm + appkey)将 mall_id、该接口的业务参数值、tm、appkey 按「签名顺序表」中的顺序直接拼接(不含 + 号、不含连接符),再做 MD5 取十六进制小写。注意各接口业务参数不完全相同,银行卡三/四要素的签名串不含 idcard、手机三要素的签名串不含 phone。
// Java 示例(身份证核验 /v2/id-server) String sign = DigestUtils.md5Hex( mall_id + realname + idcard + tm + appKey );
⚠️ 签名 3 大常见错误:
1. 忘记加上 tm/appkey;2. 业务参数顺序与公式不一致;3. 字符串拼接含 + 号(应仅按顺序拼接,不含连接符)。 这 3 种错误会直接导致 code=1104 签名不合法。
⚠️ 各接口签名拼接顺序(照抄其他接口会返回 1104)
同一套 MD5 规则,但业务参数参与签名的字段各不相同。 下表为官方口径,请按对应接口的公式拼接。
| 接口 | 路径 | 签名公式 | 注意 |
|---|---|---|---|
| 身份证核验 | /v2/id-server | md5(mall_id + realname + idcard + tm + appkey) | 身份证号末位 X 需转小写 x |
| 手机号二要素 | /phone/name | md5(mall_id + realname + phone + tm + appkey) | 只核姓名 + 手机号,不需身份证号 |
| 手机号三要素(详版) | /phone/three-detail | md5(mall_id + realname + idcard + tm + appkey) | ★ 签名串不含 phone,把手机号拼进去会返回 1104 |
| 银行卡二要素 | /v3/card2-server | md5(mall_id + realname + cardnum + tm + appkey) | cardnum 为银行卡号 |
| 银行卡三要素 | /v3/card3-server | md5(mall_id + realname + cardnum + tm + appkey) | ★ 签名串不含 idcard |
| 银行卡四要素 | /v3/card4-server | md5(mall_id + realname + cardnum + tm + appkey) | ★ 签名串不含 idcard、也不含 bankPreMobile(银行预留手机号) |
| 短信验证码 | /sms.php | md5(mall_id + phone + code + appkey) | ★ 不含 tm;code 传短信内容原文;表单编码 application/x-www-form-urlencoded |
③ 返回结构
所有接口返回 JSON,包含两层状态码: data.code(业务结果) + status(服务状态)。 判断调用是否成功要看 data.code == "1000"。注意:短信接口 /sms.php 是例外, 其返回为扁平结构(无 data / status 包装),code 为数字。
{
"data": {
"code": "1000", // 业务结果码
"message": "一致" // 业务结果说明
},
"status": "2001" // 服务状态码
}返回 JSON 包含 data.code(业务结果)和 status(服务状态);仅 code=1000/1001 计费。
④ 错误码速查表
核验类接口(身份证 / 手机号 / 银行卡)共享的错误码体系,共 21 个 code,按"业务 / 参数 / 鉴权 / 账户 / 服务"5 大类分组。短信接口使用另一套数字码,见本节末。
| code | 类型 | 说明 / 处理建议 |
|---|---|---|
| 1000 | 成功 | 一致 / 验证成功(计费) |
| 1001 | 业务 | 不一致(计费) |
| 1002 | 业务 | 库中无此号 / 系统无记录 / 无法认证(不计费) |
| 1003 | 业务 | 第三方服务异常;手机号三要素详版中表示部分一致(计费) |
| 1004 | 业务 | 手机号三要素详版:手机号与证件号一致、姓名不一致(计费) |
| 1005 | 业务 | 手机号三要素详版:手机号与姓名一致、证件号不一致(计费) |
| 1101 | 参数 | 商家 ID 不合法 |
| 1102 | 参数 | 姓名不合法 |
| 1103 | 参数 | 身份证号 / 手机号 / 银行卡号编码不合法 |
| 1104 | 鉴权 | 签名不合法(对照「签名顺序表」检查拼接顺序) |
| 1105 | 系统 | 第三方 / 银联 / 运营商中心超时,可重试 |
| 1106 | 账户 | 账户余额不足 |
| 1107 | 参数 | tm 参数不合法(须 13 位毫秒时间戳) |
| 1108 | 参数 | 参数异常 |
| 1109 | 账户 | 帐号被暂停 |
| 1110 | 系统 | 身份中心超时,可重试 |
| 2001 | 服务 | 正常服务 |
| 2002 | 服务 | 第三方服务器异常 |
| 2003 | 服务 | 服务器维护 |
| 2004 | 服务 | 帐号余额不足 |
| 2005 | 服务 | 参数异常 |
📩 短信接口错误码(/sms.php,与上表不通用)
短信接口为独立体系:报文字段扁平、code 为数字、签名不含 tm。
{
"code": 1000, // 数字码,非字符串
"message": "发送成功"
}短信接口为扁平结构,code 为数字;与核验类接口的错误码表不通用。
| code | 类型 | 说明 / 处理建议 |
|---|---|---|
| 1000 | 成功 | 发送成功(计费) |
| 1001 | 业务 | 发送短信失败 |
| 1002 | 鉴权 | 签名错误(检查 mall_id + phone + code + appkey,勿拼入 tm) |
| 1003 | 账户 | 可发送短信条数为 0 |
| 1004 | 参数 | 短信内容为空 |
| 1005 | 参数 | 短信内容存在敏感词 |
| 1006 | 参数 | 错误的手机号 |
| 1007 | 业务 | 号码在黑名单中 |
| 1008 | 业务 | 验证码类短信发送频率过快(同号限频) |
| 1009 | 业务 | 短信内容缺少签名信息(短信内容需包含【签名】) |
1000 vs 1001 的区别?
1000 = 一致(按次收费),1001 = 不一致(也按次收费)。 "查不到"会返回 1002(不收费)。所有调用建议先看 status,再看 data.code。
账户欠费怎么办?
收到 1106(账户余额不足)或 2004 时,登录控制台充值即可。 建议设置余额预警,避免生产环境调用中断。
1104 签名不合法排查?
检查 3 项:① 拼接顺序与公式一致 ② 业务参数值非空 ③ MD5 结果小写。 可用 在线 MD5 工具 比对。
1105 超时如何处理?
权威源/银联/运营商偶发超时(1105),建议加退避重试:间隔 500ms × 2 次, 仍失败则放弃(避免拖累业务主流程)。
⑤ 多语言签名示例
下面以身份证核验接口为例, 展示 Java / PHP / Python / Go / Node.js 5 种语言的签名生成 + 请求示例。 其他接口(银行卡、手机号等)只需替换业务参数部分。
Java
Copyimport org.apache.commons.codec.digest.DigestUtils; String tm = String.valueOf(System.currentTimeMillis()); // mall_id + 业务参数 + tm + appkey(不含 + 号)顺序拼接 String sign = DigestUtils.md5Hex( mallId + realname + idcard + tm + appKey ); // 请求示例 String url = "https://api.nztapi.com/v2/id-server" + "?mall_id=" + mallId + "&realname=" + URLEncoder.encode(realname, "UTF-8") + "&idcard=" + idcard + "&tm=" + tm + "&sign=" + sign;
PHP
Copy$tm = (string)(int)(microtime(true) * 1000);
$sign = md5($mallId . $realname . $idcard . $tm . $appKey);
$url = "https://api.nztapi.com/v2/id-server?mall_id={$mallId}"
. "&realname=" . urlencode($realname)
. "&idcard={$idcard}&tm={$tm}&sign={$sign}";
$response = file_get_contents($url);
$result = json_decode($response, true);Python
Copyimport time, hashlib, requests
tm = str(int(time.time() * 1000))
raw = mall_id + realname + idcard + tm + app_key
sign = hashlib.md5(raw.encode("utf-8")).hexdigest()
params = {
"mall_id": mall_id,
"realname": realname,
"idcard": idcard,
"tm": tm,
"sign": sign,
}
r = requests.get("https://api.nztapi.com/v2/id-server", params=params)
print(r.json())Go
Copypackage main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strconv"
"time"
)
func sign(mallId, realname, idcard, appKey string) string {
tm := strconv.FormatInt(time.Now().UnixMilli(), 10)
raw := mallId + realname + idcard + tm + appKey
h := md5.Sum([]byte(raw))
return hex.EncodeToString(h[:])
}Node.js
Copyconst crypto = require("crypto");
const tm = Date.now().toString();
const raw = mallId + realname + idcard + tm + appKey;
const sign = crypto.createHash("md5").update(raw).digest("hex");
const url = `https://api.nztapi.com/v2/id-server?mall_id=${mallId}&realname=${encodeURIComponent(realname)}&idcard=${idcard}&tm=${tm}&sign=${sign}`;
fetch(url).then(r => r.json()).then(console.log);⑥ 各产品业务参数
除了通用鉴权参数外,每个接口还有自己的业务参数。 点击下方产品卡片查看完整业务参数和接入说明。
准备接入?
提交申请后 1 个工作日内完成资质核验并开通,含免费试用额度