# 海宇数据 API 对接 Skill > 海宇数据 (haiyudata.com) 企业级大数据 API 接口对接 > 官网: https://www.haiyudata.com/ | 控制台: https://console.haiyudata.com/ ## 核心理解 **所有接口调用方式完全一致**,区别仅在于: 1. **接口编码**(下表第二列)— 决定调用哪个产品 2. **入参** — 不同接口需要的参数不同 ## ⚠️ 重要:入参仅为示例! 下方所有入参中的身份证号、手机号、姓名、车牌号等**均为示例占位值**,调用时**必须替换为真实数据**。 ## 标准入参字段 所有接口统一使用以下字段名: | 字段 | 类型 | 说明 | |------|------|------| | `id_card` | string | 身份证号 | | `name` | string | 姓名 | | `mobile_no` | string | 手机号 | | `vin` | string | 车架号 | | `plate` | string | 车牌号 | | `image` | string | 图片 URL 或 Base64 | | `bankcard` | string | 银行卡号 | | `ent_code` | string | 企业统一社会信用代码 | | `ent_name` | string | 企业名称 | | `callback_url` | string | 回调地址 | | `token` | string | 任务凭证 | > 单人查询传 `id_card` + `name`;双人查询传双方的 `id_card` + `name`;企业查询传 `ent_code` 或 `ent_name`。 ## 调用方式 ### 请求 ``` POST https://api.haiyudata.com/api/v1/{接口编码}?t={13位时间戳} ``` - URL 中的 `t` 为当前时间的 13 位毫秒级时间戳,需实时生成 ### 请求头 ``` Content-Type: application/json Access-Id: 你的 Access-Id ``` ### 请求体(AES 加密) 业务参数需先 JSON 序列化,再用 **AES-128-CBC** 加密,最后 Base64 编码,放入 `data` 字段: ```json { "data": "加密后的Base64字符串" } ``` #### 加密规则 - 算法:AES-128-CBC - 密钥:账户的 Access Key(16 进制字符串,`bytes.fromhex()` 转为 16 字节密钥) - IV:每次随机生成 16 字节 - 填充:PKCS7 - 传输格式:`Base64( IV + 密文 )` #### 解密规则 返回的 `data` 字段同样为加密数据: 1. Base64 解码 2. 前 16 字节为 IV,其余为密文 3. AES-128-CBC 解密 4. 去除 PKCS7 填充 ### 返回格式 #### 外层(明文,所有接口统一) ```json { "code": 0, "message": "业务成功", "transaction_id": "平台流水号(海宇计费流水号,重要!)", "data": "加密后的Base64字符串(需解密后才是真正的业务数据)" } ``` > ⚠️ **`transaction_id` 是海宇数据的计费流水号,每次调用都会返回。** > 如果对某次调用有疑问(如重复扣费、结果异常、数据争议),**凭此 ID 向海宇客服提交查询**。 > 请务必在日志中记录每次调用的 `transaction_id`。 **先看 `code`,只有 `code = 0` 时 `data` 才有意义的业务数据。** | code | 含义 | 说明 | |------|------|------| | 0 | 业务成功 | data 中为查询结果 | | 1003 | 参数校验不正确 | 入参字段名错误或缺失,检查字段拼写 | | 1004 | 未经授权的IP | 调用方IP未加入白名单,需到控制台添加 | | 1005 | 缺少Access-Id | 请求头未传 Access-Id | #### data 解密后(业务数据,因接口而异) `data` 字段是 AES 加密的 JSON 字符串,解密后得到该接口的具体业务结果。 **以 `IVYZSQ0E`(公安二要素)为例,解密后:** ```json { "result": 0, // 核验结果:0=一致,1=不一致,2=查无 "desc": "一致", // 结果中文描述 "address": "XX省XX市", // 身份证登记地址 "sex": "男", // 性别 "birthday": "19790713",// 出生日期 "order_no": "xxxxx" // 本次计费订单号 } ``` **常见业务返回字段:** | 字段 | 说明 | |------|------| | `result` | 核验结论编码(0=一致/通过,1=不一致/不通过,2=查无/未命中) | | `desc` | 结论中文描述 | | `order_no` | 计费订单号(每次调用消耗费用的凭证) | | `address` | 身份证登记地址(身份验证类接口) | | `sex` | 性别(身份验证类接口) | | `birthday` | 出生日期(身份验证类接口) | > ⚠️ 不同接口返回的 data 字段结构不同,以上为身份验证类的示例。金融风控、企业信息、车辆等接口返回字段更多,以实际返回为准。 **调用完成后,应该向用户说明:** 1. 接口是否调用成功(code 是否为 0) 2. 查询的核验结论(result / desc) 3. 返回的关键信息(地址、性别、评分等) 4. 如调用失败,说明失败原因(IP未授权/参数错误/余额不足等) --- ## 接口编码清单(真实编码) ### 📱 运营商验证 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 移动手机号易诉分 | `YYSYS7Y1` | `mobile_no` | | 手机停机验证 | `YYSY7R4V` | `mobile_no` | | 手机消费区间验证 | `YYSY2M8Q` | `mobile_no` | | 全网手机三要素验证 | `YYSYGLSF` | `mobile_no, id_card, name` | | 运营商二要素V即时版 | `YYSY0YYV` | `mobile_no, name` | | 运营商三要素简版V即时版 | `YYSYXHHO` | `mobile_no, id_card, name` | | 运营商三要素简版V政务版 | `YYSYN8DI` | `mobile_no, id_card, name` | | 运营商三要素详版V即时版 | `YYSYS66T` | `mobile_no, id_card, name` | | 号码二次放号V即时版 | `YYSYP7PL` | `mobile_no` | | 手机空号检测V即时版 | `YYSYJXZF` | `mobile_no` | | 手机携号转网V即时版 | `YYSYXAES` | `mobile_no` | | 手机在网状态V即时版 | `YYSYKTQO` | `mobile_no` | | 手机号码在网时长V即时版 | `YYSYUO7E` | `mobile_no` | ### 🪪 身份验证 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 公安二要素认证即时版 | `IVYZSQ0E` | `id_card, name` | | 公安二要素政务版 | `IVYZFO5K` | `id_card, name` | | 公安三要素即时版 | `IVYZE42I` | `id_card, name, mobile_no` | | 人脸身份证比对 | `IVYZDXMD` | `id_card, name, image` | | 身份证OCR | `IVYZZSCG` | `image` | | 身份证OCR-A | `IVYZ9OHN` | `image` | | 活体识别V步骤1 | `IVYZWVYA` | `callback_url` | | 活体识别步骤二 | `IVYZKJ31` | `token` | | 收入等级VJJ6 | `IVYZ6W0U` | `id_card, name` | | 身份风险V106 | `IVYZOQFB` | `id_card, name` | | 消费能力 | `IVYZBI6F` | `id_card, name` | | 双人婚姻评估查询V1 | `IVYZPYSO` | 双方 `id_card, name` | | 双人婚姻状态查询 | `IVYZRHT5` | 双方 `id_card, name` | | 双人婚姻状况核验 | `IVYZYDQM` | 双方 `id_card, name` | | 单人婚姻状态查询 | `IVYZO4RX` | `id_card, name` | | 单人婚姻状况核验 | `IVYZYQKX` | `id_card, name` | ### 🚗 汽车相关 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 汽车车辆五项 | `QCXG1S2L` | `vin` 或 `plate` | | 全国车辆配置查验 | `QCXGA8V3` | `vin` | | 全国车辆配置查验(车辆详情) | `QCXGCP77` | `vin` | | 行驶证信息核验V2 | `QCXGX2X6` | `vin` | | 名下车辆 | `QCXGIJY3` | `id_card, name` | | 车辆静态信息查询 | `QCXG521L` | `vin` | | 车辆维保记录 | `QCXGC6W8` | `vin` | | 新能源车检测报告V1 | `QCXGX7N1` | `vin` | | 新能源车检测报告(里程查询) | `QCXGX7N2` | `vin` | | 疑似营运车辆注册平台数 | `QCXGFV9W` | `plate` | | 疑似运营车辆查询(月度里程) | `QCXG76VA` | `plate` | | 疑似运营车辆查询(季度里程) | `QCXGYQDC` | `plate` | | 疑似运营车辆查询(半年度里程) | `QCXGGFWW` | `plate` | | 疑似运营车辆查询(年度里程) | `QCXGYWSV` | `plate` | ### 🏢 企业相关 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 企业全量信息核验V2 | `QYGLALPK` | `ent_code` 或 `ent_name` | | 企业综合风险报告V2 | `QYGL7HBN` | `ent_code` 或 `ent_name` | | 企业涉诉V2版 | `QYGLLUCM` | `ent_code` 或 `ent_name` | | 企业年报信息核验 | `QYGLUDJG` | `ent_code` 或 `ent_name` | | 企业进出口信用核查 | `QYGLM7AZ` | `ent_code` 或 `ent_name` | | 企业税收违法核查 | `QYGLWYEK` | `ent_code` 或 `ent_name` | | 企业股权结构全景 | `QYGL9MYB` | `ent_code` 或 `ent_name` | ### ⚖️ 风险管控 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 个人涉诉V2版 | `FLXGC4CT` | `id_card, name` | | 董监高司法综合信息核验A | `FLXGJI17` | `id_card` | ### 💰 金融验证 | 接口名称 | 编码 | 入参(示例值,请替换为真实数据) | |---------|------|------| | 银行卡四要素验证(详版) | `JRZQOICN` | `name, id_card, bankcard, mobile_no` | | 银行卡OCR | `JRZQMDQ1` | `image` | | 银行卡OCR-A | `JRZQDMLO` | `image` | | 洞侦多头履约行为 | `JRZQ1AIJ` | `id_card, name, mobile_no` | | 信用全景V21 | `JRZQV7YZ` | `id_card, name, mobile_no` | | 借贷意向验证 | `JRZQX5DM` | `id_card, name, mobile_no` | | 风险量级V8 | `JRZQNKEI` | `id_card, name, mobile_no` | | 风险量级V9 | `JRZQQKEC` | `id_card, name, mobile_no` | | 风险量级V10 | `JRZQI079` | `id_card, name, mobile_no` | | 智瞳分尊享版 | `JRZQAH34` | `id_card, name` | | 智瞳-通用版 | `JRZQLY6D` | `id_card, name` | | 智享分 | `JRZQNEP0` | `id_card, name` | | 支付行为指数 | `JRZQ65ZO` | `id_card, name` | | 坤羽模型V3-标签版 | `JRZQML9G` | `id_card, name, mobile_no` | | 租赁申请意向 | `JRZQZ05I` | `id_card, name, mobile_no` | | 租赁申请意向V22 | `JRZQNK43` | `id_card, name, mobile_no` | | 人企关联 | `QYGLWV7U` | `id_card, name` | | 个人涉诉定制版 | `FLXGMMG7` | `id_card, name` | | 企业诉讼定制版 | `QYGL7Z0O` | `ent_code` 或 `ent_name` | | 行为黑名单 | `JRZQTM1V` | `id_card, name, mobile_no` | | 黑名单V110_c10 | `JRZQBQIR` | `id_card, name, mobile_no` | | 特殊名单 | `JRZQMLZX` | `id_card, name, mobile_no` | | 债务逾期黑名单V3_1 | `JRZQQD4F` | `id_card, name, mobile_no` | | 风险变量V5F4 | `JRZQNVM8` | `id_card, name, mobile_no` | | 投诉风险筛查V709 | `JRZQVBHJ` | `id_card, name, mobile_no` | --- ## Python 完整调用代码 ```python import json, time, base64, os, requests from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad ACCESS_ID = os.getenv("HAIYU_ACCESS_ID", "") # 控制台获取 ACCESS_KEY = os.getenv("HAIYU_ACCESS_KEY", "") # 控制台获取(16进制字符串) BASE_URL = "https://api.haiyudata.com" def _encrypt(plaintext: str, key_hex: str) -> str: """AES-128-CBC 加密,返回 Base64(IV + 密文)""" key = bytes.fromhex(key_hex) iv = os.urandom(16) cipher = AES.new(key, AES.MODE_CBC, iv) enc = cipher.encrypt(pad(plaintext.encode("utf-8"), AES.block_size)) return base64.b64encode(iv + enc).decode() def _decrypt(b64_str: str, key_hex: str) -> str: """AES-128-CBC 解密""" key = bytes.fromhex(key_hex) raw = base64.b64decode(b64_str) iv, ct = raw[:16], raw[16:] cipher = AES.new(key, AES.MODE_CBC, iv) return unpad(cipher.decrypt(ct), AES.block_size).decode("utf-8") def call_api(api_code: str, **params) -> dict: """ 调用海宇数据接口(统一入口) :param api_code: 接口编码,如 "IVYZSQ0E" :param params: 入参(请传入真实值),如 id_card="...", name="..." :return: {"code": 0, "message": "...", "data": {...}, ...} 示例: call_api("IVYZSQ0E", id_card="真实身份证号", name="真实姓名") call_api("YYSYJXZF", mobile_no="真实手机号") """ ts = str(int(time.time() * 1000)) url = f"{BASE_URL}/api/v1/{api_code}?t={ts}" encrypted = _encrypt(json.dumps(params, ensure_ascii=False), ACCESS_KEY) resp = requests.post( url, headers={ "Content-Type": "application/json", "Access-Id": ACCESS_ID, }, json={"data": encrypted}, timeout=30, ) resp.raise_for_status() raw = resp.json() # 解密 data 字段 if raw.get("data") and isinstance(raw["data"], str): try: decrypted = _decrypt(raw["data"], ACCESS_KEY) raw["data"] = json.loads(decrypted) except Exception: pass # data 可能不是 JSON return raw ``` ### 调用示例(入参请替换为真实值) ```python # 公安二要素 result = call_api("IVYZSQ0E", id_card="真实身份证号", name="真实姓名") # 手机空号检测 result = call_api("YYSYJXZF", mobile_no="真实手机号") # 个人涉诉V2版 result = call_api("FLXGC4CT", id_card="真实身份证号", name="真实姓名") # 企业全量信息核验 result = call_api("QYGLALPK", ent_name="真实企业名称") # 汽车车辆五项 result = call_api("QCXG1S2L", vin="真实车架号") # 银行卡四要素验证 result = call_api("JRZQOICN", name="真实姓名", id_card="真实身份证号", bankcard="真实银行卡号", mobile_no="真实手机号") # 运营商三要素详版 result = call_api("YYSYS66T", mobile_no="真实手机号", id_card="真实身份证号", name="真实姓名") ``` --- ## ⚠️ 注意事项 ### 入参相关 1. **入参为示例值** — 文档中所有身份证、手机号、姓名等均为占位示例,调用时必须替换为真实数据 2. **字段名严格匹配** — 必须用 `id_card`(不是 idcard/idCard)、`mobile_no`(不是 mobile/phone)、`name` 等标准字段名,字段名错误会返回 `code: 1003 参数校验不正确` ### 鉴权与网络 3. **IP 白名单** — 需在控制台添加调用方服务器公网 IP,否则返回 `code: 1004 未经授权的IP` 4. **Access Key 是 16 进制字符串** — 加密时用 `bytes.fromhex()` 转为 16 字节密钥,不是直接把字符串当 key 5. **时间戳实时生成** — URL 中的 `t` 参数每次请求都要重新生成当前的 13 位毫秒时间戳 6. **Access-Id 在请求头** — 不是放在请求体里,是在 HTTP Header 中 ### 加密 7. **请求和响应都加密** — 发送的参数和返回的 data 都是 AES-128-CBC 加密的 8. **IV 每次随机** — 加密时随机生成 16 字节 IV,拼在密文前面一起 Base64 编码 9. **解密时先取 IV** — Base64 解码后,前 16 字节是 IV,剩余是密文 ### 合规与安全 10. **敏感数据合规** — 查询个人信息需确保业务合规、用户已授权 11. **日志脱敏** — 记录日志时对身份证、手机号等做脱敏处理(如 110101****1234) 12. **按次计费** — 所有接口按调用次数扣费,注意余额;失败请求(code 非 0)一般不计费 13. **保留 transaction_id** — 每次调用都会返回 `transaction_id`(计费流水号),如对调用结果有疑问(重复扣费、数据异常等),凭此 ID 向海宇客服提交查询,务必在日志中记录