通用接入规范(签名 / 鉴权 / 错误码)
本页汇总诺正通所有 API 接口共享的接入规范:webservice + MD5 签名鉴权机制、 通用鉴权参数、返回结构、错误码体系。无论您接入哪个产品接口, 请先阅读本页。
① 通用鉴权参数
所有 API 接口(身份证、手机号、银行卡、人脸、短信)都共享以下 3 个鉴权参数,缺一不可。
| 参数名 | 中文名 | 必填 | 说明 |
|---|---|---|---|
| mall_id | 商户ID | 必填 | 在诺正通注册时获得的商户唯一标识 |
| tm | 随机时间戳 | 必填 | 13位毫秒级时间戳,防止重放攻击 |
| sign | 签名字符串 | 必填 | MD5 签名,详见下方签名规则 |
除上述 3 个公参外,每个接口还有专属的"业务参数"(如身份证接口需要 realname + idcard)。 请前往对应产品页查看:身份证核验手机号核验银行卡核验人脸识别短信验证码身份证 OCR
② 签名规则
md5(mall_id + 业务参数 + tm + appkey)将 mall_id、所有业务参数值、tm、appkey 顺序拼接,不含 + 号,然后做 MD5 哈希
// Java 示例 String sign = DigestUtils.md5Hex( mall_id + realname + idcard + tm + appKey );
⚠️ 签名 3 大常见错误:
1. 忘记加上 tm/appkey;2. 业务参数顺序与公式不一致;3. 字符串拼接含 + 号(应仅按顺序拼接,不含连接符)。 这 3 种错误会直接导致 code=1104 签名不合法。
③ 返回结构
所有接口返回 JSON,包含两层状态码: data.code(业务结果) + status(服务状态)。 判断调用是否成功要看 data.code == "1000"。
{
"data": {
"code": "1000", // 业务结果码
"message": "一致" // 业务结果说明
},
"status": "2001" // 服务状态码
}返回 JSON 包含 data.code(业务结果)和 status(服务状态)
④ 错误码速查表
所有接口共享的错误码体系。共 17 个 code,按"业务 / 参数 / 鉴权 / 账户 / 服务"5 大类分组。
| code | 类型 | 说明 / 处理建议 |
|---|---|---|
| 1000 | 成功 | 一致/验证成功(按次收费) |
| 1001 | 业务 | 不一致/卡号姓名不匹配(按次收费) |
| 1002 | 业务 | 库中无此号/无法认证 |
| 1003 | 系统 | 第三方服务异常,稍后再试 |
| 1101 | 参数 | 商家 ID 不合法 |
| 1102 | 参数 | 姓名不合法 |
| 1103 | 参数 | 身份证号/银行卡号编码不合法 |
| 1104 | 鉴权 | 签名不合法 |
| 1105 | 系统 | 权威/银联/运营商中心超时 |
| 1106 | 账户 | 账户余额不足 |
| 1107 | 参数 | tm 参数不合法 |
| 1108 | 参数 | 参数异常 |
| 1109 | 账户 | 帐号被暂停 |
| 2001 | 服务 | 正常服务 |
| 2002 | 服务 | 第三方服务器异常 |
| 2003 | 服务 | 服务器维护 |
| 2004 | 服务 | 帐号余额不足 |
| 2005 | 服务 | 参数异常 |
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.nuozhengtong.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.nuozhengtong.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.nuozhengtong.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.nuozhengtong.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);⑥ 各产品业务参数
除了通用鉴权参数外,每个接口还有自己的业务参数。 点击下方产品卡片查看完整业务参数和接入说明。
准备接入?
注册即送 100 次免费调用,1 个工作日开通,7×24 技术支持