本文档详细介绍应用场景集成服务的API对接操作方法,包括接口鉴权、核心接口调用、回调通知处理等内容,帮助技术人员快速完成接口对接。
在开始API对接前,需要获取以下凭证:
| 凭证 | 说明 | 获取方式 |
|---|---|---|
| AppKey | 应用标识,用于识别对接方 | 技术支持提供 |
| AppSecret | 应用密钥,用于生成签名 | 技术支持提供(请妥善保管) |
| API地址 | 接口调用地址 | 测试环境:https://api-test.example.com/v1 生产环境:https://api.example.com/v1 |
重要: 为了保障接口安全,需要配置服务器IP白名单。
注意: 如果服务器IP不固定,请联系技术支持协商解决方案。
推荐开发环境:
依赖库(以Java为例):
<!-- HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
所有API接口调用需要在Header中携带鉴权信息,鉴权流程如下:
接口地址: POST /auth/access_token
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| app_key | String | 是 | 应用标识 |
| app_secret | String | 是 | 应用密钥 |
| grant_type | String | 是 | 授权类型,固定值:client_credentials |
请求示例:
curl -X POST "https://api-test.example.com/v1/auth/access_token" \
-H "Content-Type: application/json" \
-d '{
"app_key": "YOUR_APP_KEY",
"app_secret": "YOUR_APP_SECRET",
"grant_type": "client_credentials"
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "read write"
}
}
字段说明:
| 字段 | 说明 |
|---|---|
| access_token | 接口调用凭证,后续所有接口调用需要在Header中携带 |
| expires_in | access_token有效期,单位:秒(通常7200秒,即2小时) |
| token_type | token类型,固定值:Bearer |
获取access_token后,在调用业务接口时,需要在HTTP Header中携带:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
注意:
推荐刷新策略:
public class AccessTokenManager {
private String accessToken;
private long expireTime;
public String getAccessToken() {
// 如果access_token为空或即将过期(少于5分钟),则重新获取
if (accessToken == null || System.currentTimeMillis() > expireTime - 5 * 60 * 1000) {
refreshAccessToken();
}
return accessToken;
}
private synchronized void refreshAccessToken() {
// 调用获取access_token接口
// 更新accessToken和expireTime
}
}
| 接口名称 | 接口地址 | 请求方式 | 功能说明 |
|---|---|---|---|
| 获取AccessToken | /auth/access_token |
POST | 获取接口调用凭证 |
| 续保查询 | /v1/insurance/renewal/query |
POST | 查询车辆续保信息 |
| 报价接口 | /v1/insurance/quote |
POST | 获取保险公司报价 |
| 核保接口 | /v1/insurance/underwrite |
POST | 提交核保申请 |
| 支付接口 | /v1/insurance/pay |
POST | 发起支付请求 |
| 出单接口 | /v1/insurance/issue |
POST | 确认出单 |
| 保单查询 | /v1/insurance/policy/query |
GET | 查询保单详情 |
| 保单列表 | /v1/insurance/policy/list |
GET | 查询保单列表 |
所有业务接口都需要在Header中携带以下参数:
| Header参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| Authorization | String | 是 | Bearer |
| Content-Type | String | 是 | application/json |
| X-Request-Id | String | 否 | 请求唯一标识,用于问题排查 |
所有接口返回数据格式统一为:
{
"code": 0,
"message": "success",
"data": {
// 业务数据
},
"request_id": "req_1234567890abcdef"
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| code | Integer | 返回码,0表示成功,非0表示失败 |
| message | String | 返回信息,成功时为"success",失败时为错误描述 |
| data | Object | 业务数据,具体结构见各接口说明 |
| request_id | String | 请求唯一标识,用于问题排查 |
| 错误码 | 说明 | 处理建议 |
|---|---|---|
| 0 | 成功 | - |
| 10001 | 参数错误 | 检查请求参数是否正确 |
| 10002 | 鉴权失败 | 检查access_token是否有效 |
| 10003 | 权限不足 | 检查账号权限配置 |
| 10004 | 接口调用次数超限 | 联系技术支持提升配额 |
| 10005 | IP不在白名单 | 在管理后台添加服务器IP |
| 20001 | 保司接口异常 | 稍后重试或联系技术支持 |
| 20002 | 报价失败 | 检查车辆信息是否正确 |
| 20003 | 核保不通过 | 根据返回信息调整投保方案 |
| 20004 | 支付失败 | 检查支付信息或更换支付方式 |
| 50000 | 系统错误 | 联系技术支持 |
接口功能: 根据车牌号或车架号查询车辆续保信息
接口地址: POST /v1/insurance/renewal/query
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vehicle_number | String | 否 | 车牌号(与车架号二选一) |
| frame_number | String | 否 | 车架号(与车牌号二选一) |
| owner_name | String | 否 | 车主姓名(部分保司必填) |
| owner_id_card | String | 否 | 车主身份证号(部分保司必填) |
请求示例:
curl -X POST "https://api-test.example.com/v1/insurance/renewal/query" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Request-Id: req_$(date +%s)" \
-d '{
"vehicle_number": "京A12345",
"owner_name": "张三",
"owner_id_card": "110101199001011234"
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"vehicle_number": "京A12345",
"frame_number": "LVSHDAC27AN123456",
"owner_name": "张三",
"renewal_info": [
{
"insurer_code": "PICC",
"insurer_name": "人保财险",
"policy_no": "PDAA20241100012345",
"start_date": "2024-01-01",
"end_date": "2024-12-31",
"premium": 3500.00,
"status": "valid"
}
]
},
"request_id": "req_1234567890abcdef"
}
接口功能: 向多家保司发起报价请求
接口地址: POST /v1/insurance/quote
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vehicle_number | String | 是 | 车牌号 |
| frame_number | String | 是 | 车架号 |
| owner_name | String | 是 | 车主姓名 |
| owner_id_card | String | 是 | 车主身份证号 |
| insurer_codes | Array | 否 | 指定保司列表(为空则查询所有已配置保司) |
| coverage_list | Array | 是 | 险种方案列表 |
coverage_list参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| coverage_code | String | 是 | 险种代码(如:vehicle_damage(车损险)、third_party(三者险)) |
| coverage_amount | BigDecimal | 否 | 保额(三者险必填) |
| deductible | String | 否 | 不计免赔(Y/N) |
请求示例:
curl -X POST "https://api-test.example.com/v1/insurance/quote" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vehicle_number": "京A12345",
"frame_number": "LVSHDAC27AN123456",
"owner_name": "张三",
"owner_id_card": "110101199001011234",
"insurer_codes": ["PICC", "CPIC", "PAIC"],
"coverage_list": [
{
"coverage_code": "vehicle_damage",
"deductible": "Y"
},
{
"coverage_code": "third_party",
"coverage_amount": 2000000,
"deductible": "Y"
}
]
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"quote_id": "Q20241100012345",
"quotes": [
{
"insurer_code": "PICC",
"insurer_name": "人保财险",
"total_premium": 3500.00,
"coverage_detail": [
{
"coverage_code": "vehicle_damage",
"coverage_name": "机动车损失保险",
"premium": 1500.00
},
{
"coverage_code": "third_party",
"coverage_name": "机动车第三者责任保险",
"coverage_amount": 2000000,
"premium": 2000.00
}
],
"status": "success"
},
{
"insurer_code": "CPIC",
"insurer_name": "太保财险",
"total_premium": 3400.00,
"coverage_detail": [...],
"status": "success"
}
]
},
"request_id": "req_1234567890abcdef"
}
接口功能: 提交核保申请
接口地址: POST /v1/insurance/underwrite
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| quote_id | String | 是 | 报价ID(从报价接口返回) |
| insurer_code | String | 是 | 保司代码 |
| applicant | Object | 是 | 投保人信息 |
| insured | Object | 是 | 被保人信息 |
| policy_holder | Object | 是 | 车主信息 |
请求示例:
curl -X POST "https://api-test.example.com/v1/insurance/underwrite" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "Q20241100012345",
"insurer_code": "PICC",
"applicant": {
"name": "张三",
"id_card": "110101199001011234",
"phone": "13800138000",
"address": "北京市朝阳区XXX街道XXX号"
},
"insured": {
"name": "张三",
"id_card": "110101199001011234",
"phone": "13800138000",
"address": "北京市朝阳区XXX街道XXX号"
},
"policy_holder": {
"name": "张三",
"id_card": "110101199001011234"
}
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"underwrite_id": "UW20241100012345",
"insurer_code": "PICC",
"status": "approved",
"message": "核保通过",
"policy_no": "PDAA20241100012345"
},
"request_id": "req_1234567890abcdef"
}
核保状态说明:
| 状态 | 说明 |
|---|---|
| approved | 核保通过,可以支付 |
| rejected | 核保不通过,需要修改投保方案 |
| pending | 核保中,等待保司审核 |
接口功能: 发起支付请求
接口地址: POST /v1/insurance/pay
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| underwrite_id | String | 是 | 核保ID(从核保接口返回) |
| pay_type | String | 是 | 支付方式(wechat、alipay、bank_card) |
| return_url | String | 否 | 支付完成后的回调地址(H5支付必填) |
请求示例:
curl -X POST "https://api-test.example.com/v1/insurance/pay" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"underwrite_id": "UW20241100012345",
"pay_type": "wechat",
"return_url": "https://yourdomain.com/pay/result"
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"pay_id": "P20241100012345",
"pay_type": "wechat",
"pay_amount": 3500.00,
"pay_status": "pending",
"pay_qrcode": "weixin://wxpay/bizpayurl?pr=xxx",
"expire_time": "2024-11-01 15:30:00"
},
"request_id": "req_1234567890abcdef"
}
接口功能: 支付完成后确认出单
接口地址: POST /v1/insurance/issue
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pay_id | String | 是 | 支付ID(从支付接口返回) |
| underwrite_id | String | 是 | 核保ID |
请求示例:
curl -X POST "https://api-test.example.com/v1/insurance/issue" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pay_id": "P20241100012345",
"underwrite_id": "UW20241100012345"
}'
返回示例:
{
"code": 0,
"message": "success",
"data": {
"policy_no": "PDAA20241100012345",
"issue_time": "2024-11-01 15:35:00",
"policy_url": "https://api.example.com/v1/insurance/policy/download?policy_no=PDAA20241100012345",
"status": "success"
},
"request_id": "req_1234567890abcdef"
}
在交易的关键节点(支付成功、出单成功等),开放平台会向您配置的回调URL发送通知,您需要正确处理这些通知。
| 通知类型 | 说明 |
|---|---|
| quote_result | 报价结果通知 |
| underwrite_result | 核保结果通知 |
| pay_result | 支付结果通知 |
| issue_result | 出单结果通知 |
回调通知以HTTP POST方式发送,Content-Type为application/json,Body为JSON格式:
{
"notify_type": "pay_result",
"notify_time": "2024-11-01 15:30:00",
"data": {
"pay_id": "P20241100012345",
"underwrite_id": "UW20241100012345",
"pay_status": "success",
"pay_time": "2024-11-01 15:30:00",
"pay_amount": 3500.00
},
"sign": "ABCDEF1234567890..."
}
为了保障回调通知的安全性,您需要验证签名:
签名算法:
sign = MD5(app_key + notify_data + timestamp + app_secret)
验证步骤:
Java示例:
@RestController
@RequestMapping("/api")
public class CallbackController {
@PostMapping("/callback")
public Map<String, Object> handleCallback(@RequestBody Map<String, Object> callbackData) {
// 1. 验证签名
String sign = (String) callbackData.get("sign");
String calculatedSign = calculateSign(callbackData);
if (!sign.equals(calculatedSign)) {
return buildResponse(10001, "签名验证失败");
}
// 2. 处理回调通知
String notifyType = (String) callbackData.get("notify_type");
Map<String, Object> data = (Map<String, Object>) callbackData.get("data");
switch (notifyType) {
case "quote_result":
handleQuoteResult(data);
break;
case "underwrite_result":
handleUnderwriteResult(data);
break;
case "pay_result":
handlePayResult(data);
break;
case "issue_result":
handleIssueResult(data);
break;
}
// 3. 返回成功响应
return buildResponse(0, "success");
}
private Map<String, Object> buildResponse(int code, String message) {
Map<String, Object> response = new HashMap<>();
response.put("code", code);
response.put("message", message);
return response;
}
}
注意: 处理回调通知时,请务必返回正确的响应格式({"code": 0, "message": "success"}),否则开放平台会认为通知失败,会进行重试。
如果您的服务器在收到回调通知后,没有返回成功的响应(HTTP状态码不是200,或响应内容不是{"code": 0, "message": "success"}),开放平台会进行重试。
重试策略:
| 重试次数 | 间隔时间 |
|---|---|
| 第1次重试 | 1分钟 |
| 第2次重试 | 5分钟 |
| 第3次重试 | 30分钟 |
| 第4次重试 | 1小时 |
| 第5次重试 | 6小时 |
| 第6次重试 | 12小时 |
注意: 请确保您的回调接口幂等性,即重复处理同一条通知不会产生副作用。
| 错误码 | 错误信息 | 处理建议 |
|---|---|---|
| 10001 | 参数错误 | 检查请求参数是否完整、格式是否正确 |
| 10002 | 鉴权失败 | 检查access_token是否过期,如果过期则重新获取 |
| 10003 | 权限不足 | 联系技术支持,确认账号权限配置 |
| 10004 | 接口调用次数超限 | 联系技术支持,提升接口调用配额 |
| 10005 | IP不在白名单 | 在管理后台添加服务器IP到白名单 |
| 20001 | 保司接口异常 | 稍后重试,如果持续失败则联系技术支持 |
| 20002 | 报价失败 | 检查车辆信息是否正确,险种方案是否合理 |
| 20003 | 核保不通过 | 根据返回的错误信息,调整投保方案后重新核保 |
| 20004 | 支付失败 | 检查支付信息是否正确,或引导用户更换支付方式 |
| 50000 | 系统错误 | 记录请求ID(request_id),联系技术支持排查 |
建议重试策略:
| 错误类型 | 是否重试 | 重试次数 | 重试间隔 |
|---|---|---|---|
| 网络超时 | 是 | 3次 | 指数退避(1s、2s、4s) |
| 保司接口异常(20001) | 是 | 2次 | 5秒 |
| 系统错误(50000) | 是 | 2次 | 10秒 |
| 参数错误(10001) | 否 | - | - |
| 鉴权失败(10002) | 否(先刷新token) | - | - |
重试示例代码(Java):
public class RetryTemplate {
public <T> T execute(Callable<T> task, int maxRetries, long interval) throws Exception {
int retries = 0;
while (true) {
try {
return task.call();
} catch (Exception e) {
retries++;
if (retries > maxRetries) {
throw e;
}
Thread.sleep(interval);
interval *= 2; // 指数退避
}
}
}
}
建议:
示例(Java):
public class AccessTokenManager {
private static AccessTokenManager instance;
private String accessToken;
private long expireTime;
private AccessTokenManager() {}
public static synchronized AccessTokenManager getInstance() {
if (instance == null) {
instance = new AccessTokenManager();
}
return instance;
}
public synchronized String getAccessToken() {
if (accessToken == null || System.currentTimeMillis() > expireTime - 5 * 60 * 1000) {
refreshAccessToken();
}
return accessToken;
}
private void refreshAccessToken() {
// 调用获取access_token接口
// 更新accessToken和expireTime
}
}
建议:
日志示例:
[2024-11-01 15:30:00] INFO ApiClient - 请求:POST /v1/insurance/quote, request_id: req_1234567890abcdef, 耗时:1200ms
[2024-11-01 15:30:01] INFO ApiClient - 响应:POST /v1/insurance/quote, request_id: req_1234567890abcdef, code: 0, message: success
建议:
建议监控的指标:
| 指标 | 告警阈值 | 说明 |
|---|---|---|
| 接口响应时间 | > 3秒 | 接口响应时间过长 |
| 接口成功率 | < 99% | 接口调用失败率过高 |
| 交易成功率 | < 80% | 报价→支付→出单转化率过低 |
| AccessToken过期 | 过期前5分钟 | AccessToken即将过期 |
建议:
最后更新:2026-07-02
文档版本:v1.0