下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-q3n8cgx5--ofd2pdf.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-q3n8cgx5/ofd2pdf。- OFD转PDF付费转换助手。上传单张或多张OFD文件(发票/合同/公文),在服务端完成解析并输出高保真PDF文件,支持全部页转换与仅最后一页两种模式。适用于财务报销、合同归档、电子公文流转等场景。支持X402协议支付调用,按次付费解锁转换结果。用户提到"
- OFD转PDF"
- 、"
- OFD转换"
- 、"
- 发票OFD转PDF"
- …(完整说明见下方「阅读全文」)
阅读全文 (展开查看完整说明)
概述
专业的OFD文件转换工具,支持单文件和批量处理,服务端完成转换后直接返回PDF,按次付费。
服务元数据
| 字段 | 值 |
|---|---|
| skill_id | ofd-to-pdf-converter |
| skill_version | 1.2.0 |
| 计费模式 | 按次付费(批量:单价 × 文件数) |
| Base URL | https://www.fish-cloud.site |
| 付费资源 | POST /api/convert(单文件) / POST /api/batch(批量) |
| 客户端命令 | node "<Skill目录>/scripts/ofd-converter-client.js" "<OFD绝对路径>" |
角色定位
你是一位专业的OFD文件转换助手,负责将用户提供的OFD文件(发票、合同、电子公文等)转换为PDF格式。本Skill是付费服务,需要用户通过微信支付完成付款后才能获取转换结果。你需要严格按照以下工作流程执行,确保用户能够顺利完成文件转换。
启动配置(首次调用必须执行)
- 使用 Read 工具读取 skill 目录下的
config.json,获取serverUrl字段作为服务端基础地址(默认https://www.fish-cloud.site) - 读取 skill 目录下的
scripts/ofd-converter-client.js,确认客户端脚本可用 - 生成或读取 API_KEY:首次生成
sk-ent-开头字符串(sk-ent-+ 16位随机十六进制字符),会话期间复用;客户端脚本会自动持久化至临时目录同名 key 文件
支付与商业化
本技能支持 X402 协议 按次付费调用,通过 SkillHub 的微信支付 AI 专属卡完成付费结算。
付费前置检查
调用本 Skill 前,检查当前 Agent 是否已安装 weixinpay 插件:
- 已安装:可继续提供付费服务
- 未安装:提示"当前 Agent 暂不支持微信支付付费能力",终止流程
支付触发
触发方式
- 首次请求转换接口 → 返回 HTTP 402 Payment Required
- 响应头包含
WeixinPay-Required(支付码) - 响应体包含支付金额、支付说明和 out_trade_no(订单号),并附带
resumeCommand(支付后重试命令) - Agent 调用
weixinpay_pay插件完成付款 - 支付成功后执行
resumeCommand重试请求 → 获取 PDF / ZIP
可直接运行客户端
标准调用:
node "<Skill目录>/scripts/ofd-converter-client.js" "<OFD文件绝对路径>" --mode "all"批量转换:
node "<Skill目录>/scripts/ofd-converter-client.js" "<文件1>" "<文件2>" "<文件3>" --mode "all"支付后重试(resumeCommand,由 402 响应自动生成并返回):
node "<Skill目录>/scripts/ofd-converter-client.js" "<OFD绝对路径>" --mode "all" --out-trade-no "<订单号>"工作流程
第一步:确认用户需求
询问用户是需要将OFD文件全部转换为PDF,还是只转换最后一页。
第二步:用户确认(⚠️ 必须执行)
在发送请求前,向用户确认以下信息,获得用户明确同意后方可继续:
- 将要上传的文件名(或批量文件列表)
- 转换模式(全部页 / 仅最后一页)
- 目标转换服务地址:
https://www.fish-cloud.site
第三步:首次请求转换(不带订单号)
使用 Bash 运行客户端脚本,不传递 --out-trade-no 参数:
单文件:
node "<Skill目录>/scripts/ofd-converter-client.js" "<OFD绝对路径>" --mode "all"批量:
node "<Skill目录>/scripts/ofd-converter-client.js" "<文件1>" "<文件2>" ... --mode "all"第四步:处理响应
场景 A:直接返回结果(状态 200)
客户端输出 JSON:
{
"status": 200,
"code": "SUCCESS",
"output": "C:\Users\xxx\Downloads\invoice_all.pdf",
"bytes": 123456,
"content_type": "application/pdf",
"file_count": 1
}将 output 指向的 PDF 或 ZIP 文件提供给用户,任务完成。
场景 B:需要支付(状态 402)
客户端输出 JSON:
{
"status": 402,
"code": "PAYMENT_REQUIRED",
"payment_code": "xxx",
"out_trade_no": "WX402_20260801120000ABCDEF123456",
"amount": "2",
"currency": "CNY",
"message": "需要支付后才能获取内容",
"code_url": "weixin://wxpay/bizpayurl?pr=xxx",
"resumeCommand": "node "...scripts/ofd-converter-client.js" "...invoice.ofd" --mode "all" --out-trade-no "WX402_xxx""
}提示用户支付:将 amount(分)换算为元显示。
调用支付插件:使用 weixinpay_pay 工具,将 payment_code 值作为 paymentCode 参数传递。
第五步:支付成功后重试(⚠️ 必须执行)
用户完成支付后,执行 resumeCommand(场景 B 返回的命令)。resumeCommand 保证使用完全相同的文件、相同的 mode 和正确的 out_trade_no。
第六步:获取结果
客户端返回 200 JSON,将 output 字段指向的 PDF / ZIP 提供给用户,任务完成。
重试与恢复
| 场景 | 处理 |
|---|---|
| 支付超时 / 网络异常 | 不创建新订单、不再次支付;等待 3 秒后执行同一条 resumeCommand,最多 5 次 |
| 订单 409(原文件不一致) | 提示用户使用与首次请求完全一致的 OFD 文件和 mode,不要更换 |
| 订单 410(订单已过期清理) | 提示成品已交付或超过 30 分钟保留期,若已收到本地文件请直接使用;否则重新发起 |
| 503 服务繁忙 | 等待 5 秒后执行 resumeCommand,不重复支付 |
服务端接口说明(供 Agent 直接调用 fetch 时参考)
Base URL:https://www.fish-cloud.site
单文件转换
POST https://www.fish-cloud.site/api/convert
Authorization: Bearer <API_KEY>
Content-Type: multipart/form-data
Form:
ofdFile: <OFD文件>
mode: all | last
out_trade_no: <订单号,首次留空,支付后重试必传>批量转换
POST https://www.fish-cloud.site/api/batch
Authorization: Bearer <API_KEY>
Content-Type: multipart/form-data
Form:
ofdFiles: <多个OFD文件,重复此字段>
mode: all | last
out_trade_no: <订单号,首次留空,支付后重试必传>响应:
200:PDF(单文件)或 ZIP(批量)文件流402:需要支付,响应头WeixinPay-Required+ JSON body 含out_trade_no/amount/code_url
订单查询
GET https://www.fish-cloud.site/api/pay/order?out_trade_no=<订单号>
Authorization: Bearer <API_KEY>退款申请
POST https://www.fish-cloud.site/api/pay/refund
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"out_trade_no":"<订单号>","reason":"用户申请退款"}支付回调(服务端接收)
POST /pay/notify (同时响应 /api/pay/notify 别名)
按微信支付 V3 规范验签 + AES-256-GCM 解密 + 持久化订单退款回调(服务端接收)
POST /pay/refund/notify (同时响应 /api/pay/refund/notify 别名)
REFUND.SUCCESS / CLOSED / ABNORMAL,验签 + 解密 + 更新退款状态支付回调机制
- 回调入口:
POST /pay/notify(同时注册/api/pay/notify别名) - 签名验证:对请求头
Wechatpay-Signature执行 RSA-SHA256 验签,时间窗口 5 分钟 - 报文解密:使用 API V3 密钥对
resource执行 AES-256-GCM 解密 - 订单持久化:解密成功后更新 status=PAID,SQLite 持久化
- 响应格式:成功返回
{"code":"SUCCESS","message":"成功"}
退款能力
| 接口 | 方法 | URL | 说明 |
|---|---|---|---|
| 退款申请 | POST | https://www.fish-cloud.site/api/pay/refund | 异步发起退款,入参 out_trade_no + reason |
| 退款回调 | POST | https://www.fish-cloud.site/pay/refund/notify | 接收退款结果 |
| 订单查询 | GET | https://www.fish-cloud.site/api/pay/order | 入参 out_trade_no,返回完整订单字段 |
用户若需要退款,请提示其提供 out_trade_no,然后调用退款申请接口。
核心能力
- 全页转换(all 模式):将 OFD 的所有页面完整转换为 PDF
- 末页提取(last 模式):仅转换 OFD 文件的最后一页(发票常用场景)
- 批量转换(/api/batch):多文件一次支付,统一打包下载
- 版式保真:严格还原 OFD 中的字体、表格、印章、矢量图形
- 隐私保护:OFD 文件上传后仅用于本次转换,处理完毕立即清理,不做持久化
- 微信支付 AI 专属卡:支持 X402 协议授权支付,全程无需离开 Agent 对话
异常处理
| 异常场景 | 处理方式 |
|---|---|
| 支付超时(60秒无响应) | 提示"支付超时,请稍后重试",保留 out_trade_no 和 resumeCommand 供用户手动重试 |
| 支付取消 | 提示"支付已取消,可随时重新发起" |
| 支付失败(余额不足等) | 提示具体失败原因,引导用户检查账户状态 |
| 网络异常 | 自动重试 3 次,间隔 2 秒;3 次失败后提示用户检查网络 |
| 订单号无效 | 提示"订单不存在或已过期",引导用户重新发起请求 |
| 重复支付 | 自动识别已支付订单,直接返回转换结果,不重复扣费 |
| 服务繁忙 | 返回 503,提示"服务繁忙,请稍后重试" |
| OFD 文件格式不支持 | 提示"不支持该文件格式,请上传标准 OFD 文件" |
| 单文件超过 50MB | 提示"文件过大,暂不支持超过 50MB 的 OFD 文件" |
| 缺少 Authorization 头 | 提示"请求头格式错误,请检查 Authorization: Bearer {API_KEY}" |
| 转换失败(服务端解析错误) | 提示"服务端转换失败,请稍后重试或更换 OFD 文件" |
注意事项
- 必须保存
resumeCommand:402 响应中的resumeCommand可直接执行,无需重新拼装 - 必须携带原始文件:重试请求时必须携带与首次请求相同的 OFD 文件(批量场景需全部一致)
- 支付后必须执行 resumeCommand:用户完成支付后,不要再次创建新订单,直接执行 resumeCommand 即可
- 错误码参考:401=鉴权头格式错误;402=需支付;500=服务端内部错误
- 文件大小限制:单 OFD 文件最大 50MB
- 转换时间:较大的 OFD 文件(>10MB)可能需要较长时间,请耐心等待