接口连不上或返回 404:核验网关与短信主机的地址、路径与三类报错定位
核验类走 api2.nztapi.com,短信走 http://api.nztapi.com/sms.php。路径写错返回 404 HTML 而非错误码,漏传必填参数返回 1108。附四类症状实测对照与联调自查顺序。
一句话结论
诺正通的接口分两台服务器、两种传输协议:身份证 / 手机号 / 银行卡核验类走 https://api2.nztapi.com,短信验证码走 http://api.nztapi.com/sms.php(注意是 http)。写错主机或写错路径,拿不到任何错误码——核验端点路径写错时服务器直接回 404 HTML 页面,短信主机上做 HTTPS 握手则证书校验失败。你在错误码表里翻遍也找不到,因为那不是错误码问题。
两台服务器,别把地址写混
| 能力 | 主机 | 协议 | 端点 |
|---|
| 身份证二要素 | api2.nztapi.com | HTTPS | /v2/id-server |
|---|---|---|---|
| 手机号二要素 | api2.nztapi.com | HTTPS | /phone/name |
| 手机号三要素(详版) | api2.nztapi.com | HTTPS | /phone/three-detail |
| 银行卡二要素 | api2.nztapi.com | HTTPS | /v3/card2-server |
| 银行卡三要素 | api2.nztapi.com | HTTPS | /v3/card3-server |
| 银行卡四要素 | api2.nztapi.com | HTTPS | /v3/card4-server |
| 短信验证码 | api.nztapi.com | HTTP | /sms.php |
这里最容易出事的一点是:短信主机的 HTTPS 证书与主机名不匹配,它的证书签发给的是另一个域名(签发主体为 www.nuozhengtong.cn,且已于 2021 年过期)。所以对短信地址做 HTTPS 请求,失败发生在 TLS 握手阶段,连 HTTP 响应都没有——表现为客户端侧的证书校验错误,而不是任何业务码。核验网关 api2.nztapi.com 用的是有效期内的 Let's Encrypt 证书,证书名与主机名一致。
短信侧明确是 http://,这一点在官方接口文档里也写明了。核验密钥与短信密钥不要在同一个客户端配置里复用:地址、签名算式(短信不含 tm)、返回结构(短信是扁平的、无 data / status 包装)三样都不一样,详见接口返回怎么解析。
四类症状,四种定位
联调时拿不到预期返回,按下面四类症状分,能省掉大部分来回试。这四类的实测结果如下(用占位凭据打真实网关,只取响应形态):
| 症状 | 典型请求 | HTTP | 响应体 | 真实原因 |
|---|
| 拿到 JSON 错误码 | 地址与路径都对,签名算错 | 200 | {"data":{"code":"1104","message":"签名不合法"},"status":"2001"} | 业务层,查签名拼接顺序 |
|---|---|---|---|---|
| 拿到 JSON 错误码 | 地址与路径都对,漏了必填参数 | 200 | {"data":{"code":"1108","message":"参数异常"},"status":"2005"} | 业务层,查必填字段 |
| 拿到 HTML 页面 | 路径写错(多字符 / 下划线 / 缺版本段) | 404 | ...Apache Tomcat... Error report... | 路由层,路径根本没匹配上 |
| 客户端抛证书错误 | 对短信主机做 HTTPS | — | 无 HTTP 响应,握手失败 | 传输层,协议用错,短信走 http |
实测输出(逐条请求真实网关):
api2 + /v2/id-server(正确) HTTP=200 {"data":{"code":"1104","message":"签名不合法"},"status":"2001"}
api2 + /v2/id-serverx(多一个字符) HTTP=404 <html><head><title>Apache Tomcat/7.0.56 - Error report</title> api2 + /v2/id_server(下划线) HTTP=404 <html><head><title>Apache Tomcat/7.0.56 - Error report</title> api2 + /id-server(缺版本段) HTTP=404 <html><head><title>Apache Tomcat/7.0.56 - Error report</title> api2 + /v3/card4-server(正确) HTTP=200 {"data":{"code":"1104","message":"签名不合法"},"status":"2001"} api2 + /v3/card4-server(漏 bankPreMobile)HTTP=200 {"data":{"code":"1108","message":"参数异常"},"status":"2005"}
404 与 1108 的分界是这一节最值钱的地方:路径写错 → 404 HTML;路径对但参数缺 → 200 + 1108。所以客户端里如果写了 resp.json() 而路径写错,会直接抛 JSON 解析异常(拿到的是 HTML,不是 JSON),错误栈指向解析代码,而不是指向你拼错的路径。排查这类问题时先看 HTTP 状态码,再谈业务码——顺序反了就会一路查签名和参数,而真因只是路径少了一段。
三个只有读接口文档才看得出的点
1. 核验类端点有版本段,短信类没有
核验类路径都带 /v2 或 /v3(/v2/id-server、/v3/card2-server),手机号两个端点不带(/phone/name、/phone/three-detail)。这不是风格问题:省略版本段会 404,因为路由根本匹配不到。反过来,给短信路径 /sms.php 加一个 /v2 前缀同样 404。
2. 必填但不参与签名的字段,漏了照样报 1108
银行卡四要素要传 bankPreMobile(银行预留手机号,注意是大驼峰拼写,不是 phone / mobile),但签名串里不含它,签的是 md5(mall_id + realname + cardnum + tm + appkey)。它的作用是"必填但不参与签名"——所以漏传它不会触发 1104 签名不合法,而是触发 1108 参数异常。这类字段是最容易漏的,因为你在算签名时根本看不到它,代码 review 也容易跳过去。
同理,手机号三要素详版的 phone 也是必填但不参与签名(签名串不含 phone);短信侧的 title 同样是必填但不参与签名(短信签名只签 mall_id + phone + code + appkey)。完整对照见接口参数怎么传。
3. 路径写法对但仍然 404:下划线与大小写
核验端点路径是连字符 + 全部小写:/v2/id-server、/phone/three-detail、/v3/card4-server。写成 /v2/id_server 或 /phone/three_detail 都是 404——因为路由匹配的是连字符。实测两种下划线写法都返回同一个 Tomcat 404 页面。
一个能直接抄的地址常量
把地址抽成常量,而不是散落在各处硬编码,能从源头消除这类错误:
# 两台服务器,两个协议,写在一起比分散在各处更不容易写混
VERIFY_BASE = "https://api2.nztapi.com" # 身份证 / 手机号 / 银行卡核验 SMS_BASE = "http://api.nztapi.com" # 短信验证码,注意是 http
VERIFY_ENDPOINTS = { "idcard2": "/v2/id-server", "phone2": "/phone/name", "phone3": "/phone/three-detail", "card2": "/v3/card2-server", "card3": "/v3/card3-server", "card4": "/v3/card4-server", }
联调自查顺序
拿到一个不预期的返回,按这个顺序走,不要跳步:
api.nztapi.com?那台只服务短信/v2、/v3)在不在?连字符还是下划线?status:status != 2001 时即使 data.code=1000 也要复核data.code 定位:1104 查签名拼接顺序,1108 查必填字段(含"必填但不签名"的那些),1101 查 mall_id 与出口 IP 白名单tm 必须是同一个值相关阅读
status 与 data.code 正交的判定顺序关于诺正通
身份证、手机号、银行卡核验接口与短信验证码接口按量计费、面议,含 100 次免费试用用于联调,具体价格向商务询价。