旅游意外险 Agent API(统一 Skill)
能力路由
发票 API 路径选择(必读)
两套路由并存,按场景选用,不要混用同一业务流程中的步骤:
| 路径 | 适用场景 | 接口前缀 |
|---|---|---|
| A. 保单路径 | 订单已出单;与投保/订单详情中的 policyNum 一致;Agent 流程从下单延续过来 | POST/GET /policies/{policyNum}/invoice |
| B. 经纪路径 | 需走经纪工作台式开票:多保单 policyNo[]、POST /broker/invoice、POST /broker/invoiceQuery、POST /broker/redInvoice | /broker/invoice 等 |
- 主订单合并/分开开票:路径 A 与路径 B 文档中均有
isMainOrder、invoiceMode(merge/separate)说明,以用户要求的集成入口为准;若用户只说「按保单开票且已对接订单接口」,优先路径 A。
鉴权与状态管理
鉴权
- Base URL:
https://prod.uzyun.cn/api/agent/v1 - 用户 token:除下面「无需 token」的路径外,其余接口均需登录后在请求头携带:
Authorization: Bearer <token>或X-User-Token: <token>
- 无需 token 的路径(与
GET /schema中auth.noAuthPaths一致):POST /sms/send、POST /register、POST /login、GET /schema。 - 注册与登录:均为 手机号 + 短信验证码,不使用用户名、密码;具体 Body 字段名与是否可选以
GET /schema为准。
注册(新用户)
POST /sms/send— Body:event=register,mobile= 手机号(大陆号码按平台要求)。- 用户收到短信验证码后,
POST /register— Body:mobile(必填)、code(必填,上一步短信验证码)、inviteCode(可选);username可不传,服务端默认使用mobile填充。 - 注册成功响应会直接返回
token、expires、id、username,可直接进入后续业务调用;具体字段校验与错误信息以GET /schema为准。
登录(获取 token)
与注册相同:手机号 + 短信验证码,不使用密码。
POST /sms/send— Body:event=login,mobile= 手机号。POST /login— Body:mobile(必填)、code(必填,短信验证码)。
响应含token、expires(过期时间戳)、id等;若服务端仍返回username等展示字段,可写入状态文件便于展示,鉴权仅依赖 token。后续请求携带Authorization: Bearer <token>。
本地状态管理(.agent-state.json)
Agent 通过工作区根目录的 .agent-state.json 文件持久化 token 和常用人员信息,避免每次对话重复登录和重复收集信息。
对话开始时
- 执行
date "+%Y-%m-%d %H:%M:%S %Z"获取当前本地时间,记录到对话上下文中(用于 token 过期判断、起保日期建议等)。 - 读取
.agent-state.json。 - 若
token存在且expires> 当前时间戳,直接使用该 token,跳过登录。 - 若
policyholder或frequentInsured有数据,后续下单时优先使用,无需再向用户收集。
登录成功后
将登录响应写入 .agent-state.json(保留已有的 policyholder 和 frequentInsured);建议同时写入 mobile,便于下次 token 过期时发起短信登录。
{
"token": "<登录返回的 token>",
"expires": 1735689600,
"userId": 1001,
"mobile": "13800138000"
}
若登录响应含
username等字段,可一并写入.agent-state.json供展示;登录方式仍为手机号 + 验证码,无密码。
token 过期处理
若请求返回 401 或 expires 已过期:使用保存的 mobile(或让用户再次提供手机号)走「登录」短信验证流程,登录成功后更新 .agent-state.json 中的 token。短信验证码不在状态文件中持久化。
Schema 缓存
Schema 数据纯静态(仅在服务端代码部署时变更),可本地缓存避免每次对话都调用 GET /schema:
- 首次:调用
GET /schema,将返回的完整内容存入.agent-state.json的schemaCache字段,同时记录schemaVersion(取自响应的version字段)。 - 后续对话:若
.agent-state.json中已有schemaCache,直接使用缓存内容,不调用GET /schema。 - 缓存更新:当需要调用 Schema 时(如缓存不存在),对比返回的
version与本地schemaVersion,若不同则更新schemaCache和schemaVersion。 - 手动刷新:若用户明确要求刷新 Schema,调用
GET /schema并更新缓存。
文件结构示例
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires": 1735689600,
"userId": 1001,
"mobile": "13800138000",
"policyholder": {
"holderType": "individual",
"fullName": "张三",
"idNumber": "310101199001011234",
"mobileNumber": "13800138000"
},
"frequentInsured": [
{ "fullName": "张三", "idNumber": "310101199001011234" },
{ "fullName": "李四", "idNumber": "310101199101011234" }
],
"schemaVersion": "2026.3",
"schemaCache": {}
}
schemaCache的值为GET /schema返回的完整 JSON 对象,此处省略。
当前时间
模型自身不感知实时时间。对话开始时必须执行以下命令获取当前时间,并在整个对话中使用:
date "+%Y-%m-%d %H:%M:%S %Z"
当前时间用于:
- 起保日期建议:起保日期不应早于今天,默认建议明天起保。
- token 过期判断:将
expires时间戳与当前时间对比,判断是否需要重新登录。 - 日期相关提示:如用户说「下周出发」时,根据当前日期推算具体日期。
错误处理(通用)
- 400:缺字段或格式错误,Body 中包含校验错误信息,可据此补全后重试。
- 401:未携带或无效的用户 token,需先调用
POST /login获取 token。 - 429:注册/登录请求过于频繁(按 IP 限流),请稍后再试。
咨询
能力概述
查询旅游意外险产品信息并获取保费报价:产品列表、产品详情与保障对比、计划列表、计算保费。不包含下单、支付。
何时使用
- 用户想了解有哪些旅游意外险产品、保障内容。
- 用户需要对比不同产品或计划的保障范围。
- 用户想知道某个产品/计划的保费是多少。
调用流程
- 检查 token 有效性(见上文「鉴权与状态管理」),无效则登录。
GET /products— 获取产品列表(含描述),得到 productId。GET /products/{productId}/detail— (可选)获取产品详情与保障明细对比矩阵。GET /products/{productId}/plans— 获取该产品的计划列表,得到 planId 和 planCode。POST /quote— 传入 productId、planId、起止日期、insuredAges[],得到保费。
接口说明
接口参数细节请通过本地缓存的 Schema 或调用 GET /schema 获取。以下仅列出核心要点。
GET /products
获取产品列表。返回产品名称、描述、状态等。
GET /products/{productId}/detail
获取产品详情,包含保障明细对比矩阵。
GET /products/{productId}/plans
获取指定产品的计划列表,返回 planId、planCode、保障额度等。
POST /quote
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| productId | int | 是 | 产品ID |
| planId | int | 是 | 计划ID |
| coverageStartTime | string | 是 | 起保日期 YYYY-MM-DD |
| coverageEndTime | string | 是 | 止保日期 YYYY-MM-DD |
| insuredAges | []int | 是 | 被保险人年龄数组 |
GET /options/{type}
枚举值查询接口,无需 token。
| type 值 | 说明 |
|---|---|
| sex | 性别 |
| country_code | 国家/地区代码 |
| individual_id_type | 证件类型 |
| policy_holder_type | 投保人类型 |
| relation_to | 与投保人关系 |
| unit_type | 单位性质 |
响应为 [{value, label}, ...],用 value 作为请求体字段值,用 label 展示给用户。
投保
能力概述
完成旅游意外险投保全流程:创建订单、提交到保司、获取支付链接、查询订单状态、下载保单/确认书;出单后可通过 路径 A 申请/查询电子发票。支持智能填表(中国身份证场景下被保险人只需姓名+证件号)。
何时使用
- 用户要为自己或他人办理旅游意外险。
- 用户已完成报价,需要创建投保订单。
- 用户要查询订单列表或单笔订单状态、获取支付链接、下载单证。
- 用户需要按 保单路径 开具电子发票或查询蓝票/红冲进度(见下文「电子发票(路径 A)」)。
调用流程
- 检查 token 有效性,无效则登录。
POST /orders— 创建订单(身份证场景只需姓名+证件号),得到 orderSn。POST /orders/{orderSn}/submit— 传入 paymentMethod,提交到保司并获取 paymentUrl。GET /orders/GET /orders/{orderSn}/GET /orders/{orderSn}/pay-url— 列表、详情、支付链接。GET /policies/{policyNum}/assets;GET /policies/{policyNum}/download?type=policy|confirmation— 下载 PDF(推荐)。- (出单后,路径 A)
POST /policies/{policyNum}/invoice;GET /policies/{policyNum}/invoice?queryType=1|2。
下载保单与投保确认书
- Base URL:
https://prod.uzyun.cn/api/agent/v1 - 鉴权:
Authorization: Bearer <token>(或X-User-Token)。 - 保单号:
policyNum来自订单详情或列表(出单后才有);仅当前登录用户本人订单可访问。
方式一(推荐):直接下载 PDF
| 文档 | 请求 |
|---|---|
| 保单 | GET /policies/{policyNum}/download?type=policy(type 可省略,默认即为保单) |
| 投保确认书 | GET /policies/{policyNum}/download?type=confirmation |
curl -sSL -H "Authorization: Bearer $TOKEN" \
-o "${policyNum}_保单.pdf" \
"https://prod.uzyun.cn/api/agent/v1/policies/${policyNum}/download?type=policy"
curl -sSL -H "Authorization: Bearer $TOKEN" \
-o "${policyNum}_投保确认书.pdf" \
"https://prod.uzyun.cn/api/agent/v1/policies/${policyNum}/download?type=confirmation"
方式二:GET /policies/{policyNum}/assets 返回 JSON:policyUrl、confirmationUrl(可能暂时为空)。
电子发票(路径 A:/policies/.../invoice)
- 仅本人订单可操作;
policyNum来自订单详情;主订单拆单时路径中可为任一子单保单号(见isMainOrder)。
申请开票 — POST /policies/{policyNum}/invoice,JSON body:
| 场景 | 必填 body | 说明 |
|---|---|---|
| 传统单笔 | invoiceTitle、isMainOrder: false | 抬头:个人一般为姓名,企业为税务一致全称 |
| 主单拆单 | isMainOrder: true、invoiceMode: merge 或 separate | 合并一张票 / 各子单一票 |
响应核心字段:policyNums、brokerStatus(如 1000 表示经纪受理成功)、invoiceUrl / policyInvoiceUrls。
查询进度 — GET /policies/{policyNum}/invoice?queryType=1(蓝字);queryType=2(红冲)。data.items:billStatus(0 开具中,1 成功,2 失败)、shortUrl、errorMessage。
若需 路径 B(/broker/invoice 等),见下文「开票经纪侧」章节。
智能填表规则(核心)
API 支持从中国居民身份证号自动推导(仅在字段为空/零值时填充,显式传入不覆盖):
| 自动推导字段 | 说明 |
|---|---|
idType | "ID" |
dateOfBirth | 身份证第7-14位 YYYY-MM-DD |
gender | 第17位奇偶 → male/female |
age | dateOfBirth + coverageStartTime 周岁 |
被保险人最少必填:中国身份证 → fullName + idNumber;护照/其他 → fullName + idType + idNumber + dateOfBirth。idType 枚举以 GET /options/individual_id_type 为准。
投保人最少必填:个人身份证 → holderType + fullName + idNumber;企业 → holderType(corporate)+ companyName + unifiedSocialCreditCode。
投保人/被保险人状态持久化
下单成功后写入 .agent-state.json(按 idNumber 去重):覆盖 policyholder;追加 frequentInsured。后续下单优先使用已存数据并向用户确认。
支付链接输出(ASCII 二维码)
拿到 paymentUrl 后必须在回复中同时输出:
paymentUrl原文;- ASCII 二维码(如
██/空格),不得以仅图片替代。
推荐:Node qrcode-terminal、Python qrcode、或 qrencode;禁止依赖第三方在线转码站。若无法生成二维码,至少输出链接并说明降级原因。
接口说明(投保)
POST /orders— 草稿订单;须再POST /orders/{orderSn}/submit才提交保司。paymentMethod:wechat、alipay、credit、recharge、insurance;channelPartnerId不传,服务端默认渠道。
错误处理(投保)
- 身份证格式错误、证件重复、被保险人上限 200 人等以接口返回为准;完整字段以
GET /schema为准。
退保
能力概述
单张保单退保、主订单批量退保(异步)、查询批量退保进度、订单退费。
何时使用
- 用户要退掉已承保成功的保单。
- 主订单下所有保单批量退保及进度查询。
- 用户要申请订单退费。
调用流程
单张退保:确认 policyNum,状态为 underwriting_approved → POST /broker/surrender。
批量退保:确认 mainOrderId → POST /broker/batchSurrender 得 taskId → 轮询 GET /broker/batchSurrenderProgress?taskId= 至 completed / failed。
退费:POST /broker/refund,传入 orderSn。
接口详情
POST /broker/surrender
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| policyNum | string | 是 | 保单号 |
POST /broker/batchSurrender
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mainOrderId | int64 | 是 | 主订单ID |
响应含 taskId、total。
GET /broker/batchSurrenderProgress
| 字段 | 说明 |
|---|---|
| status | pending/processing/completed/failed |
| successCount / failedCount / failedList / progress | 进度与结果 |
POST /broker/refund
| 字段 | 类型 | 必填 |
|---|---|---|
| orderSn | string | 是 |
POST /broker/queryOrderStatus
orderSn 与 policyNum 二选一。
注意事项
- 退保前确认承保成功;批量退保建议 2–3 秒间隔轮询。
- 退保与退费为独立操作;区分
policyNum、mainOrderId、orderSn。
开票经纪侧
能力概述
通过 路径 B:POST /broker/invoice 开具、POST /broker/invoiceQuery 查询、POST /broker/redInvoice 红冲。支持传统订单与主订单(合并/分开)。
何时使用
- 用户明确要求或集成约定使用经纪开票接口。
- 多保单批量传入
policyNo[](最多 100 张)等 broker 文档场景。
调用流程
- 检查 token,无效则登录。
- 开具:
POST /broker/invoice(参数见下表)。 - 查询:
POST /broker/invoiceQuery(type:1发票 /2红冲)。 - 红冲:
POST /broker/redInvoice。
POST /broker/invoice
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| policyNo | []string | 是 | 保单号列表(最多100张) |
| invoiceTitle | string | 条件必填 | 传统订单必填;主订单由后端获取 |
| isMainOrder | bool | 否 | 默认 false |
| invoiceMode | string | 否 | 主订单:merge / separate(默认) |
开票模式:传统订单必传抬头;主订单合并/分开见字段说明。
POST /broker/invoiceQuery
| 字段 | 必填 | 说明 |
|---|---|---|
| policyNum | 是 | 保单号 |
| type | 是 | 1 发票 / 2 红冲 |
响应 data 项:billStatus、shortUrl、errorMessage 等。
POST /broker/redInvoice
| 字段 | 必填 |
|---|---|
| policyNum | 是 |
注意事项
- 开票前保单需已承保成功;红冲不可逆,需用户确认。
- 若场景更符合订单/保单一体化流程,优先评估上文「投保」章中的路径 A(
/policies/{policyNum}/invoice)是否足够。