# 企查查模块 API 接口文档 ## 概述 企查查模块提供企业工商信息和失信核查查询功能,数据来源于企查查API。 ### 基础信息 |项目 |说明 | |---|---| |基础路径 |`/api/v2/qichacha` | |认证方式 |Bearer Token(JWT) | |数据格式 |JSON | ### 费用说明 |接口 |企查查接口 |单价 | |---|---|---| |工商信息 |410接口 |0.20元/次 | |失信核查 |740接口 |0.30元/次 | |完整查询 |410+740 |0.50元/次 | > **注意**:仅调用企查查API时产生费用,使用数据库记录不产生费用。 ### 权限要求 |权限键 |说明 |分配角色 | |---|---|---| |`qichacha:company:query` |查询企业信息 |市级管理员、省级管理员、普通员工 | |`qichacha:status:read` |查看记录状态 |市级管理员、省级管理员、普通员工 | --- ## 业务逻辑 ### 核心流程 企查查模块的核心设计理念是**数据库优先**,通过本地数据库存储已查询过的企业信息,减少对企查查API的调用次数,从而节省费用。 #### 查询流程图 ``` ┌─────────────────────────────────────────────────────────┐ │ 用户发起查询请求 │ │ keyword = "腾讯科技" 或 信用代码 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌────────────────────────┐ │ 1. 查询数据库 │ │ (三字段OR匹配) │ │ search_key = keyword │ │ OR credit_code = keyword │ │ OR company_name = keyword │ └────────────────────────┘ │ ┌────────────┴────────────┐ │ │ ▼ ▼ ┌──────────┐ ┌──────────┐ │ 无记录 │ │ 有记录 │ └──────────┘ └──────────┘ │ │ │ ▼ │ ┌─────────────────────────┐ │ │ 2. 检查force_refresh │ │ │ 参数是否为true? │ │ └─────────────────────────┘ │ │ │ │ true false │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ 3. 检查数据新鲜度 │ │ │ │ updated_at距今 │ │ │ │ 是否超过30天? │ │ │ └──────────────────┘ │ │ │ │ │ │ >=30天 <30天 │ │ │ │ ▼ ▼ ▼ ▼ ┌─────────────────────────────┐ ┌──────────────┐ │ 4. 调用企查查API │ │ 5. 直接返回 │ │ ├─ 410接口(工商) 0.20元 │ │ 数据库记录 │ │ └─ 740接口(失信) 0.30元 │ │ │ │ │ │ ✓ 不产生费用 │ │ 5. 写入/更新数据库 │ │ ✓ 响应更快 │ │ ├─ search_key = keyword │ └──────────────┘ │ ├─ credit_code (从API获取) │ │ ├─ company_name (从API获取)│ │ ├─ enterprise = JSON │ │ └─ dishonesty = JSON │ │ │ │ 6. 返回查询结果 │ │ ✗ 产生费用: 0.50元/次 │ └─────────────────────────────┘ ``` ### 数据刷新策略 |场景 |条件 |动作 |是否产生费用 | |---|---|---|---| |首次查询 |数据库无此企业记录 |调用API → 写入数据库 |✓ 0.50元 | |强制刷新 |`force_refresh=true` |调用API → 更新数据库 |✓ 0.50元 | |数据过期 |记录存在但超过30天 |调用API → 更新数据库 |✓ 0.50元 | |数据有效 |记录存在且未超30天 |直接返回数据库记录 |✗ 免费 | ### 三字段匹配机制 数据库查询使用**OR逻辑**匹配以下三个字段: |字段 |说明 |示例 | |---|---|---| |`search_key` |原始查询关键词 |"腾讯科技" | |`credit_code` |统一社会信用代码 |"91440300708461136T" | |`company_name` |企业全称(从API获取) |"腾讯科技(深圳)有限公司" | **匹配示例:** 1. 用户首次用 `"腾讯科技"` 查询 - 数据库无记录 → 调用API - API返回企业全称和信用代码 - 写入数据库:`search_key="腾讯科技"`, `credit_code="91440300708461136T"`, `company_name="腾讯科技(深圳)有限公司"` 2. 用户再用 `"91440300708461136T"` 查询 - 数据库查询:`WHERE search_key='91440300708461136T' OR credit_code='91440300708461136T' OR company_name='91440300708461136T'` - 命中 `credit_code` 字段 → 返回已有记录(不调用API) 3. 用户再用 `"腾讯科技(深圳)有限公司"` 查询 - 命中 `company_name` 字段 → 返回已有记录(不调用API) ### 数据存储结构 数据库表:`qcc_company_info` |字段 |类型 |说明 | |---|---|---| |id |SERIAL |主键 | |search_key |VARCHAR(500) |查询关键词(唯一索引) | |credit_code |VARCHAR(50) |统一社会信用代码 | |company_name |VARCHAR(500) |企业名称 | |enterprise |JSONB |410接口原始返回(工商信息) | |dishonesty |JSONB |740接口原始返回(失信信息) | |created_at |TIMESTAMPTZ |创建时间 | |updated_at |TIMESTAMPTZ |更新时间(用于判断数据新鲜度) | ### API调用说明 #### 企查查接口 |接口代码 |接口名称 |请求路径 |单价 | |---|---|---|---| |410 |企业工商信息 |`/ECIV4/GetBasicDetailsByName` |0.20元/次 | |740 |失信核查 |`/ShixinCheck/GetList` |0.30元/次 | #### Token生成规则 ``` Token = MD5(AppKey + Timespan + SecretKey).toUpperCase() ``` - `AppKey`: 企查查分配的应用Key - `Timespan`: Unix时间戳(秒) - `SecretKey`: 企查查分配的密钥 #### 请求头 |Header |值 | |---|---| |Token |MD5签名(大写) | |Timespan |Unix时间戳 | |Content-Type |application/json | ### 并发处理 查询完整企业信息时,系统会**并发调用**410和740两个接口: ```python # 并发请求示例 enterprise_task = client.get_enterprise_info(keyword) # 410接口 dishonesty_task = client.get_dishonesty_info(keyword) # 740接口 enterprise_resp, dishonesty_resp = await asyncio.gather( enterprise_task, dishonesty_task, return_exceptions=True ) ``` 优点: - 减少总响应时间(两个请求并行执行) - 单个接口失败不影响另一个接口的结果 --- ## API 接口 ### 1. 查询企业信息 查询企业完整信息(工商信息 + 失信核查) **请求** ``` POST /api/v2/qichacha/company Content-Type: application/json Authorization: Bearer ``` **请求参数** |字段 |类型 |必填 |说明 | |---|---|---|---| |keyword |string |是 |查询关键词(企业名称或统一社会信用代码),2-200字符 | |force_refresh |boolean |否 |是否强制刷新,默认false | **请求示例** ```json { "keyword": "腾讯科技(深圳)有限公司", "force_refresh": false } ``` **响应参数** |字段 |类型 |说明 | |---|---|---| |success |boolean |查询是否成功 | |message |string |响应消息 | |data |object |企业信息(见下表) | |error_code |string |错误码(失败时返回) | |error_details |object |错误详情(失败时返回) | **data 字段说明** |字段 |类型 |说明 | |---|---|---| |search_key |string |查询关键词 | |credit_code |string |统一社会信用代码 | |company_name |string |企业名称 | |enterprise |object |企业工商信息(410接口原始返回) | |dishonesty |object |失信核查信息(740接口原始返回) | |has_dishonesty |boolean |是否有失信记录 | |dishonesty_count |integer |失信记录数量 | |updated_at |datetime |数据更新时间 | **enterprise 字段说明(410接口返回)** |字段 |类型 |说明 | |---|---|---| |KeyNo |string |企查查内部KeyNo | |Name |string |企业名称 | |No |string |工商注册号 | |BelongOrg |string |登记机关 | |OperId |string |法定代表人ID | |OperName |string |法定代表人姓名 | |DesignatedRepresentativeList |array |指定代表人列表 | |StartDate |string |成立日期(格式:YYYY-MM-DD HH:mm:ss) | |EndDate |string |注销日期(空字符串表示未注销) | |Status |string |企业状态(存续、注销、吊销等) | |Province |string |省份代码(如JS=江苏) | |UpdatedDate |string |数据更新日期 | |CreditCode |string |统一社会信用代码(部分老企业可能为空) | |RegistCapi |string |注册资本(含单位,如"36225万元") | |RegisteredCapital |string |注册资本数值 | |RegisteredCapitalUnit |string |注册资本单位(如"万") | |RegisteredCapitalCCY |string |注册资本币种(如"CNY") | |EconKind |string |企业类型(如"有限责任公司"、"全民所有制"等) | |Address |string |注册地址 | |Scope |string |经营范围 | |TermStart |string |营业期限起始日期 | |TermEnd |string |营业期限终止日期 | |CheckDate |string |核准日期 | |OrgNo |string |组织机构代码 | |IsOnStock |string |是否上市("0"=否,"1"=是) | |StockNumber |string |股票代码(非上市为null) | |StockType |string |股票类型(非上市为null) | |OriginalName |array |曾用名列表 | |ImageUrl |string |企业Logo图片URL | |EntType |string |企业类型代码 | |RecCap |string |实缴资本(含单位) | |PaidUpCapital |string |实缴资本数值 | |PaidUpCapitalUnit |string |实缴资本单位 | |PaidUpCapitalCCY |string |实缴资本币种 | |RevokeInfo |object |注销/吊销信息 | |Area |object |地区信息 | |AreaCode |string |地区代码 | **enterprise.DesignatedRepresentativeList[] 指定代表人** |字段 |类型 |说明 | |---|---|---| |PartnerName |string |股东名称 | |DelegatedName |string |委派代表姓名 | **enterprise.OriginalName[] 曾用名** |字段 |类型 |说明 | |---|---|---| |Name |string |曾用名称 | |ChangeDate |string |变更日期 | **enterprise.RevokeInfo 注销/吊销信息** |字段 |类型 |说明 | |---|---|---| |CancelDate |string |注销日期 | |CancelReason |string |注销原因 | |RevokeDate |string |吊销日期 | |RevokeReason |string |吊销原因 | **enterprise.Area 地区信息** |字段 |类型 |说明 | |---|---|---| |Province |string |省份 | |City |string |城市 | |County |string |区县 | **dishonesty 字段说明(740接口返回)** |字段 |类型 |说明 | |---|---|---| |VerifyResult |integer |核查结果:0-无失信记录,1-有失信记录 | |Data |array |失信记录列表(VerifyResult=0时为null或空数组) | **dishonesty.Data[] 失信记录字段说明** |字段 |类型 |说明 | |---|---|---| |Id |string |记录唯一标识 | |Liandate |string |立案日期(格式:YYYY-MM-DD) | |Anno |string |案号 | |Executegov |string |执行法院 | |Executestatus |string |执行情况(全部未履行/部分履行/全部履行) | |Publicdate |string |发布日期(格式:YYYY-MM-DD) | |Executeno |string |执行依据文号 | |ActionRemark |string |失信被执行人行为具体情形 | |Amount |string |执行标的金额(元) | **响应示例(成功)** ```json { "success": true, "message": "查询成功", "data": { "search_key": "腾讯科技(深圳)有限公司", "credit_code": "91440300708461136T", "company_name": "腾讯科技(深圳)有限公司", "enterprise": { "KeyNo": "p5ef6e1c39f4817d33dfb4e9", "Name": "腾讯科技(深圳)有限公司", "No": "440301103206221", "BelongOrg": "深圳市市场监督管理局", "OperId": "p5ef6e1c39f4817d33dfb4e9op", "OperName": "马化腾", "DesignatedRepresentativeList": [], "StartDate": "2000-02-24 00:00:00", "EndDate": "", "Status": "存续", "Province": "GD", "UpdatedDate": "2024-12-10 15:30:00", "CreditCode": "91440300708461136T", "RegistCapi": "65000万人民币", "RegisteredCapital": "65000", "RegisteredCapitalUnit": "万", "RegisteredCapitalCCY": "CNY", "EconKind": "有限责任公司", "Address": "深圳市南山区粤海街道科技中一路腾讯大厦35层", "Scope": "从事计算机软硬件及周边设备、通讯设备、数码产品、网络设备的技术开发、销售及相关的技术咨询、技术服务;经营进出口业务;从事广告业务;物业管理", "TermStart": "2000-02-24 00:00:00", "TermEnd": "2050-02-24 00:00:00", "CheckDate": "2023-08-15 00:00:00", "OrgNo": "708461136", "IsOnStock": "1", "StockNumber": "00700.HK", "StockType": "港股", "OriginalName": [ { "Name": "深圳市腾讯计算机系统有限公司", "ChangeDate": "2000-06-01" } ], "ImageUrl": "https://img.qichacha.com/xxx.png", "EntType": "1", "RecCap": "65000万人民币", "PaidUpCapital": "65000", "PaidUpCapitalUnit": "万", "PaidUpCapitalCCY": "CNY", "RevokeInfo": { "CancelDate": "", "CancelReason": "", "RevokeDate": "", "RevokeReason": "" }, "Area": { "Province": "广东省", "City": "深圳市", "County": "南山区" }, "AreaCode": "440305" }, "dishonesty": { "VerifyResult": 0, "Data": null }, "has_dishonesty": false, "dishonesty_count": 0, "updated_at": "2024-12-12T10:30:00+08:00" } } ``` **响应示例(有失信记录)** ```json { "success": true, "message": "查询成功", "data": { "search_key": "某某建设工程有限公司", "credit_code": "91440106MA5CXXXX12", "company_name": "某某建设工程有限公司", "enterprise": { "KeyNo": "abc123def456ghi789jkl", "Name": "某某建设工程有限公司", "No": "440106000123456", "BelongOrg": "广州市天河区市场监督管理局", "OperId": "abc123def456ghi789jklop", "OperName": "张三", "DesignatedRepresentativeList": [], "StartDate": "2018-05-10 00:00:00", "EndDate": "", "Status": "存续", "Province": "GD", "UpdatedDate": "2024-12-01 09:00:00", "CreditCode": "91440106MA5CXXXX12", "RegistCapi": "5000万人民币", "RegisteredCapital": "5000", "RegisteredCapitalUnit": "万", "RegisteredCapitalCCY": "CNY", "EconKind": "有限责任公司(自然人投资或控股)", "Address": "广州市天河区某某路123号", "Scope": "建筑工程施工;市政公用工程施工;房屋建筑工程施工;建筑装饰、装修工程施工;园林绿化工程施工", "TermStart": "2018-05-10 00:00:00", "TermEnd": "2048-05-09 00:00:00", "CheckDate": "2023-06-20 00:00:00", "OrgNo": "MA5CXXXX1", "IsOnStock": "0", "StockNumber": null, "StockType": null, "OriginalName": [], "ImageUrl": "", "EntType": "1", "RecCap": "1000万人民币", "PaidUpCapital": "1000", "PaidUpCapitalUnit": "万", "PaidUpCapitalCCY": "CNY", "RevokeInfo": { "CancelDate": "", "CancelReason": "", "RevokeDate": "", "RevokeReason": "" }, "Area": { "Province": "广东省", "City": "广州市", "County": "天河区" }, "AreaCode": "440106" }, "dishonesty": { "VerifyResult": 1, "Data": [ { "Id": "c2edc410f8ceed3ed256055baa8df1432", "Liandate": "2021-08-10", "Anno": "(2021)粤0106执34224号", "Executegov": "广州市天河区人民法院", "Executestatus": "全部未履行", "Publicdate": "2022-01-07", "Executeno": "(2020)粤0106民初12345号", "ActionRemark": "有履行能力而拒不履行生效法律文书确定义务", "Amount": "1098000" } ] }, "has_dishonesty": true, "dishonesty_count": 1, "updated_at": "2024-12-12T10:30:00+08:00" } } ``` **响应示例(失败)** ```json { "success": false, "message": "当前KEY已欠费", "data": null, "error_code": "102", "error_details": { "order_number": "20241212103000123", "is_charged": false, "is_valid_request": false } } ``` --- ### 2. 仅查询工商信息 仅查询企业工商信息(410接口),费用 0.20元/次 **请求** ``` POST /api/v2/qichacha/enterprise Content-Type: application/json Authorization: Bearer ``` **请求参数** 同 [查询企业信息](#1-查询企业信息) **响应参数** 同 [查询企业信息](#1-查询企业信息),但 `dishonesty` 字段为 null --- ### 3. 仅查询失信信息 仅查询企业失信信息(740接口),费用 0.30元/次 **请求** ``` POST /api/v2/qichacha/dishonesty Content-Type: application/json Authorization: Bearer ``` **请求参数** 同 [查询企业信息](#1-查询企业信息) **响应参数** 同 [查询企业信息](#1-查询企业信息),但 `enterprise` 字段为 null --- ### 4. 批量查询企业信息 批量查询多个企业信息,单次最多10个 **请求** ``` POST /api/v2/qichacha/batch Content-Type: application/json Authorization: Bearer ``` **请求参数** |字段 |类型 |必填 |说明 | |---|---|---|---| |keywords |array[string] |是 |查询关键词列表,1-10个 | |force_refresh |boolean |否 |是否强制刷新,默认false | **请求示例** ```json { "keywords": ["腾讯科技", "阿里巴巴", "华为技术"], "force_refresh": false } ``` **响应参数** |字段 |类型 |说明 | |---|---|---| |success |boolean |是否全部成功 | |total |integer |总查询数 | |success_count |integer |成功数 | |failed_count |integer |失败数 | |results |array |查询结果列表(每个元素同单个查询响应) | **响应示例** > 注:`results` 数组中每个元素的 `data` 结构与单个查询响应的 `data` 字段完全一致,包含完整的 `enterprise` 和 `dishonesty` 对象。 ```json { "success": true, "total": 3, "success_count": 3, "failed_count": 0, "results": [ { "success": true, "message": "查询成功", "data": { "search_key": "腾讯科技", "credit_code": "91440300708461136T", "company_name": "腾讯科技(深圳)有限公司", "enterprise": { "KeyNo": "p5ef6e1c39f4817d33dfb4e9", "Name": "腾讯科技(深圳)有限公司", "No": "440301103206221", "BelongOrg": "深圳市市场监督管理局", "OperId": "p5ef6e1c39f4817d33dfb4e9op", "OperName": "马化腾", "DesignatedRepresentativeList": [], "StartDate": "2000-02-24 00:00:00", "EndDate": "", "Status": "存续", "Province": "GD", "UpdatedDate": "2024-12-10 15:30:00", "CreditCode": "91440300708461136T", "RegistCapi": "65000万人民币", "RegisteredCapital": "65000", "RegisteredCapitalUnit": "万", "RegisteredCapitalCCY": "CNY", "EconKind": "有限责任公司", "Address": "深圳市南山区粤海街道科技中一路腾讯大厦35层", "Scope": "从事计算机软硬件及周边设备、通讯设备、数码产品、网络设备的技术开发、销售及相关的技术咨询、技术服务;经营进出口业务;从事广告业务;物业管理", "TermStart": "2000-02-24 00:00:00", "TermEnd": "2050-02-24 00:00:00", "CheckDate": "2023-08-15 00:00:00", "OrgNo": "708461136", "IsOnStock": "1", "StockNumber": "00700.HK", "StockType": "港股", "OriginalName": [], "ImageUrl": "https://img.qichacha.com/xxx.png", "EntType": "1", "RecCap": "65000万人民币", "PaidUpCapital": "65000", "PaidUpCapitalUnit": "万", "PaidUpCapitalCCY": "CNY", "RevokeInfo": { "CancelDate": "", "CancelReason": "", "RevokeDate": "", "RevokeReason": "" }, "Area": { "Province": "广东省", "City": "深圳市", "County": "南山区" }, "AreaCode": "440305" }, "dishonesty": { "VerifyResult": 0, "Data": null }, "has_dishonesty": false, "dishonesty_count": 0, "updated_at": "2024-12-12T10:30:00+08:00" } }, { "success": true, "message": "查询成功", "data": { "search_key": "阿里巴巴", "credit_code": "91330100799655058B", "company_name": "阿里巴巴(中国)有限公司", "enterprise": { "/* 完整enterprise对象,结构同上 */" : "..." }, "dishonesty": { "VerifyResult": 0, "Data": null }, "has_dishonesty": false, "dishonesty_count": 0, "updated_at": "2024-12-12T10:31:00+08:00" } }, { "success": true, "message": "查询成功", "data": { "search_key": "华为技术", "credit_code": "914403006194776951", "company_name": "华为技术有限公司", "enterprise": { "/* 完整enterprise对象,结构同上 */" : "..." }, "dishonesty": { "VerifyResult": 0, "Data": null }, "has_dishonesty": false, "dishonesty_count": 0, "updated_at": "2024-12-12T10:32:00+08:00" } } ] } ``` --- ### 5. 查询数据库记录状态 查询企业在数据库中的记录状态(不调用企查查API,不产生费用) **请求** ``` GET /api/v2/qichacha/status?keyword=腾讯科技 Authorization: Bearer ``` **请求参数** |字段 |类型 |必填 |说明 | |---|---|---|---| |keyword |string |是 |查询关键词,最少2字符 | **响应参数** |字段 |类型 |说明 | |---|---|---| |exists |boolean |记录是否存在 | |keyword |string |查询关键词 | |search_key |string |数据库中的search_key | |credit_code |string |统一社会信用代码 | |company_name |string |企业名称 | |has_enterprise |boolean |是否有工商信息 | |has_dishonesty |boolean |是否有失信信息 | |updated_at |datetime |数据更新时间 | |age_days |integer |数据已存在天数 | |refresh_threshold_days |integer |刷新阈值(默认30天) | |need_refresh |boolean |是否需要刷新 | **响应示例(有记录)** ```json { "exists": true, "keyword": "腾讯科技", "search_key": "腾讯科技(深圳)有限公司", "credit_code": "91440300708461136T", "company_name": "腾讯科技(深圳)有限公司", "has_enterprise": true, "has_dishonesty": true, "updated_at": "2024-12-01T10:30:00+08:00", "age_days": 11, "refresh_threshold_days": 30, "need_refresh": false } ``` **响应示例(无记录)** ```json { "exists": false, "keyword": "某某不存在的公司" } ``` --- ## 错误码 ### 企查查API状态码 #### 有效请求(会计费) |状态码 |说明 | |---|---| |200 |查询成功 | |201 |查询无结果 | |202 |查询参数错误 | |205 |等待处理中 | |207 |请求数据条目数超过上限 | |208 |此接口不支持此公司类型查询 | |209 |企业数量超过上限 | |213 |参数长度不能小于2 | |215 |不支持的查询关键字 | #### 无效请求(不计费) |状态码 |说明 | |---|---| |101 |当前的KEY无效或还未生效 | |102 |当前KEY已欠费 | |103 |当前KEY被暂停使用 | |107 |被禁止的IP或签名错误 | |111 |接口权限未开通 | |112 |账号剩余使用量不足或已过期 | ### HTTP状态码 |状态码 |说明 | |---|---| |200 |成功 | |401 |未认证(Token无效或过期) | |403 |无权限(缺少qichacha:company:query权限) | |500 |服务器内部错误 | --- ## 配置说明 在环境配置文件中添加: ```ini # 企查查API配置 QCC_APP_KEY=你的AppKey QCC_SECRET_KEY=你的SecretKey # 可选配置 QCC_BASE_URL=https://api.qichacha.com QCC_TIMEOUT=30 QCC_CACHE_DAYS=30 ``` --- ## 使用示例 ### cURL ```bash # 查询企业信息 curl -X POST "http://localhost:8000/api/v2/qichacha/company" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{"keyword": "腾讯科技", "force_refresh": false}' # 批量查询 curl -X POST "http://localhost:8000/api/v2/qichacha/batch" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{"keywords": ["腾讯", "阿里", "华为"]}' # 查询记录状态 curl -X GET "http://localhost:8000/api/v2/qichacha/status?keyword=腾讯" \ -H "Authorization: Bearer " ``` ### Python ```python import httpx async def query_company(keyword: str, token: str): async with httpx.AsyncClient() as client: response = await client.post( "http://localhost:8000/api/v2/qichacha/company", json={"keyword": keyword, "force_refresh": False}, headers={"Authorization": f"Bearer {token}"} ) return response.json() ``` ### JavaScript ```javascript async function queryCompany(keyword, token) { const response = await fetch('/api/v2/qichacha/company', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ keyword: keyword, force_refresh: false }) }); return await response.json(); } ```