Files
haiyushuke-website/public/download/hydata-skill/SKILL.md
2026-06-18 13:06:18 +08:00

373 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 海宇数据 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 Key16 进制字符串,`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 向海宇客服提交查询,务必在日志中记录