Skill: pythons/buy-travel-accident-china (version 2.0.4)

--- name: buy-travel-accident-china description: 游子云旅游意外险销售平台（中国人保），适合旅行社代客出单。 version: "2.0.4" author: "" triggers: - 旅游意外险 - 旅游保险 - 保险咨询 - 产品推荐 - 保费查询 - 报价 - 投保 - 下单 - 买保险 - 支付 - 订单查询 - 开票 - 发票 - 红冲 - 退保 - 退费 - 取消保险 - 退款 --- # 旅游意外险 Agent API（统一 Skill） ## 能力路由 | 用户意图 | 阅读章节 | |----------|----------| | 查产品、计划、保障对比、算保费 | [咨询](#咨询) | | 下单、支付、订单查询、保单/确认书下载 | [投保](#投保) | | 退保、批量退保、退费 | [退保](#退保) | | 经纪侧开票、查询、红冲（`/broker/...`） | [开票经纪侧](#开票经纪侧) | ## 发票 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-[REDACTED_SECRET]` - **无需 token 的路径**（与 `GET /schema` 中 `auth.noAuthPaths` 一致）：`POST /sms/send`、`POST /register`、`POST /login`、`GET /schema`。 - **注册与登录**：均为 **手机号 + 短信验证码**，**不使用用户名、密码**；具体 Body 字段名与是否可选以 `GET /schema` 为准。 #### 注册（新用户） 1. `POST /sms/send` — Body：`event` = **`register`**，`mobile` = 手机号（大陆号码按平台要求）。 2. 用户收到短信验证码后，`POST /register` — Body：**`mobile`**（必填）、**`code`**（必填，上一步短信验证码）、**`inviteCode`**（可选）；**`username` 可不传**，服务端默认使用 `mobile` 填充。 3. 注册成功响应会直接返回 **`token`**、**`expires`**、**`id`**、**`username`**，可直接进入后续业务调用；具体字段校验与错误信息以 `GET /schema` 为准。 #### 登录（获取 token） 与注册相同：**手机号 + 短信验证码**，**不使用密码**。 1. `POST /sms/send` — Body：`event` = **`login`**，`mobile` = 手机号。 2. `POST /login` — Body：**`mobile`**（必填）、**`code`**（必填，短信验证码）。 响应含 **`token`**、**`expires`**（过期时间戳）、**`id`** 等；若服务端仍返回 **`username`** 等展示字段，可写入状态文件便于展示，**鉴权仅依赖 token**。后续请求携带 `Authorization: Bearer <token>`。 ### 本地状态管理（.agent-state.json） Agent 通过工作区根目录的 `.agent-state.json` 文件持久化 token 和常用人员信息，避免每次对话重复登录和重复收集信息。 #### 对话开始时 1. 执行 `date "+%Y-%m-%d %H:%M:%S %Z"` 获取当前本地时间，记录到对话上下文中（用于 token 过期判断、起保日期建议等）。 2. 读取 `.agent-state.json`。 3. 若 `token` 存在且 `expires` > 当前时间戳，直接使用该 token，**跳过登录**。 4. 若 `policyholder` 或 `frequentInsured` 有数据，后续下单时优先使用，无需再向用户收集。 #### 登录成功后 将登录响应写入 `.agent-state.json`（保留已有的 `policyholder` 和 `frequentInsured`）；建议同时写入 **`mobile`**，便于下次 token 过期时发起短信登录。 ```json { "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` 并更新缓存。 #### 文件结构示例 ```json { "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 对象，此处省略。 ### 当前时间 模型自身不感知实时时间。**对话开始时必须执行以下命令获取当前时间**，并在整个对话中使用： ```bash date "+%Y-%m-%d %H:%M:%S %Z" ``` 当前时间用于： - **起保日期建议**：起保日期不应早于今天，默认建议明天起保。 - **token 过期判断**：将 `expires` 时间戳与当前时间对比，判断是否需要重新登录。 - **日期相关提示**：如用户说「下周出发」时，根据当前日期推算具体日期。 ### 错误处理（通用） - **400**：缺字段或格式错误，Body 中包含校验错误信息，可据此补全后重试。 - **401**：未携带或无效的用户 token，需先调用 `POST /login` 获取 token。 - **429**：注册/登录请求过于频繁（按 IP 限流），请稍后再试。 --- ## 咨询 ### 能力概述 查询旅游意外险产品信息并获取保费报价：产品列表、产品详情与保障对比、计划列表、计算保费。**不包含下单、支付。** ### 何时使用 - 用户想了解有哪些旅游意外险产品、保障内容。 - 用户需要对比不同产品或计划的保障范围。 - 用户想知道某个产品/计划的保费是多少。 ### 调用流程 1. 检查 token 有效性（见上文「鉴权与状态管理」），无效则登录。 2. `GET /products` — 获取产品列表（含描述），得到 productId。 3. `GET /products/{productId}/detail` — （可选）获取产品详情与保障明细对比矩阵。 4. `GET /products/{productId}/plans` — 获取该产品的计划列表，得到 planId 和 planCode。 5. `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）」）。 ### 调用流程 1. 检查 token 有效性，无效则登录。 2. `POST /orders` — 创建订单（身份证场景只需姓名+证件号），得到 orderSn。 3. `POST /orders/{orderSn}/submit` — 传入 paymentMethod，提交到保司并获取 paymentUrl。 4. `GET /orders` / `GET /orders/{orderSn}` / `GET /orders/{orderSn}/pay-url` — 列表、详情、支付链接。 5. `GET /policies/{policyNum}/assets`；`GET /policies/{policyNum}/download?type=policy|confirmation` — 下载 PDF（推荐）。 6. （出单后，路径 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` | ```bash 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` 后必须在回复中同时输出： 1. `paymentUrl` 原文； 2. **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 文档场景。 ### 调用流程 1. 检查 token，无效则登录。 2. 开具：`POST /broker/invoice`（参数见下表）。 3. 查询：`POST /broker/invoiceQuery`（`type`：`1` 发票 / `2` 红冲）。 4. 红冲：`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`）是否足够。

path: README.md
content: # 旅游意外险，适合旅行社代客出单 Agent API / Travel Accident Insurance Agent API

单一 Skill 入口：**仓库根目录 [`SKILL.md`](./SKILL.md)**（版本 2.0.4；ClawHub slug：`buy-travel-accident-china`，展示名：旅游意外险。）

---

## 文档结构

| 章节（均在 `SKILL.md` 内） | 说明 |
|---------------------------|------|
| **能力路由** | 用户意图 → 对应章节 |
| **发票 API 路径选择** | 路径 A：`/policies/.../invoice`；路径 B：`/broker/invoice` 等 |
| **鉴权与状态管理** | Base URL、Token、`.agent-state.json`、Schema 缓存、错误处理 |
| **咨询** | 产品列表、计划、保障对比、`POST /quote` |
| **投保** | 下单、支付、单证下载、路径 A 发票、智能填表、ASCII 支付二维码 |
| **退保** | 单张/批量退保、退费、broker 查询 |
| **开票经纪侧** | 路径 B：`/broker/invoice`、`invoiceQuery`、`redInvoice` |

鉴权、状态与 Schema 缓存已写在 **`SKILL.md`** 的「鉴权与状态管理」一节，无需其他附录文件。

---

## 中文说明

让 Agent 能够调用旅游意外险接口，完成从咨询报价到投保、退保、开票的完整业务流程，支持中国身份证智能填表。

### 前置条件

- Agent 具备 HTTP 请求能力（调用 `https://prod.uzyun.cn/api/agent/v1`）。
- 用户需拥有该平台账号（注册/登录后获得 token）。

### 安装与启用

**从 ClawHub 安装（推荐）**

- Slug：`buy-travel-accident-china`，展示名：**旅游意外险**
- 命令：`clawhub install buy-travel-accident-china`

**本地目录安装**

将本技能目录放入 OpenClaw 技能目录（如 `~/.openclaw/skills/` 或项目 `.openclaw/skills/`），**确保宿主加载根目录 `SKILL.md`**，重启 OpenClaw 或执行 `/reload-skills` 热加载。

### 权限说明

本技能仅描述如何调用外部 API，不包含额外系统权限。Agent 需能发起 HTTPS 请求并读写工作区内的 `.agent-state.json` 以持久化登录状态与常用人员信息；**短信验证码不写入状态文件**（登录为手机号 + 验证码，见 `SKILL.md`「鉴权」）。

---

## English

This skill enables the Agent to call the travel accident insurance API for the full flow: consultation and quoting, purchasing, surrender, and invoicing (policy-path and broker-path), with smart form-fill for Chinese ID cards.

### Single entrypoint

Use **[`SKILL.md`](./SKILL.md)** at the repository root as the only canonical skill document.

### Requirements

- Agent can make HTTP requests to `https://prod.uzyun.cn/api/agent/v1`
- User must have an account on the platform (token after register/login)

### Install and enable

**From ClawHub:** `clawhub install buy-travel-accident-china` (slug `buy-travel-accident-china`, display name **旅游意外险**).

**From a local copy:** place this folder in your OpenClaw skills directory and ensure the host loads the root **`SKILL.md`**, then restart or `/reload-skills`.


path: clawhub.json
content: {
  "slug": "buy-travel-accident-china",
  "name": "旅游意外险",
  "name_zh": "旅游意外险",
  "name_en": "Travel accident insurance (China)",
  "tagline": "旅游意外险报价、下单、提交保司与支付链接，支持身份证智能填表",
  "tagline_zh": "旅游意外险报价、下单、提交保司与支付链接，支持身份证智能填表",
  "tagline_en": "Quote, order, submit to insurer and get payment link for travel accident insurance; smart form-fill for Chinese ID",
  "description": "本技能让 Agent 能够调用旅游意外险后端 API，完成用户注册/登录、获取产品与计划列表、报价、创建订单、提交到保司、查询订单列表与单笔状态、获取支付链接等全流程。适用于需要为用户办理旅游意外险、获取报价或管理投保订单的场景。API 支持智能填表：中国身份证场景下被保险人只需提供姓名和证件号即可下单，出生日期、性别、年龄等由服务端自动推导。",
  "description_zh": "本技能让 Agent 能够调用旅游意外险后端 API，完成用户注册/登录、获取产品与计划列表、报价、创建订单、提交到保司、查询订单列表与单笔状态、获取支付链接等全流程。适用于需要为用户办理旅游意外险、获取报价或管理投保订单的场景。API 支持智能填表：中国身份证场景下被保险人只需提供姓名和证件号即可下单，出生日期、性别、年龄等由服务端自动推导。",
  "description_en": "This skill lets the Agent call the travel accident insurance backend API for the full flow: register/login, product and plan lists, quote, create order, submit to insurer, list orders, single order status and payment link. It fits scenarios where you need to arrange travel accident insurance, get a quote or manage orders. The API supports smart form-fill: with a Chinese ID, the insured only needs name and ID number to place an order; date of birth, gender and age are derived by the server.",
  "category": "utility",
  "tags": ["保险", "旅游", "旅游意外险", "API", "agent", "智能填表"],
  "tags_zh": ["保险", "旅游", "旅游意外险", "API", "agent", "智能填表"],
  "tags_en": ["insurance", "travel", "travel insurance", "API", "agent", "smart form-fill"],
  "version": "2.0.4",
  "license": "MIT",
  "pricing": "free"
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)