票据记账助手(Receipt Bookkeeper Skill)
面向中国个体户 / 小微企业的票据记账能力。核心价值:把一张发票 / 小票 / 支付凭证图片,自动变成一条结构化账目(日期、金额、渠道、收支类型、分类、发票)——直接喂给你的记账 / 报表 / 报税工作流,免去人工录单。
适用场景
- 个体户用手机拍一张小票 / 发票,自动提取金额、日期、付款方式
- 区分微信支付 / 支付宝 / 银行卡 / 现金,自动判断收入还是支出
- 识别专票 / 普票 / 发票号,便于做票账匹配与税前扣除
- 按商户自动归类(房租、油费、物料、推广、工资…),对接税务成本汇总
支持能力
- 多方向 OCR:图片横放 / 竖放自动转正识别(0°/90°/180°/270° 择优)
- 金额识别:阿拉伯数字 + 中文大写(壹佰伍拾伍元整 → 155.00)
- 渠道识别:微信 / 支付宝 / 对公银行卡 / 个人银行卡 / 现金
- 收支识别:收入(income) / 支出(expense) / 转账(transfer)
- 发票识别:增值税专票 / 增值税普票 / 无票 + 发票号提取
- 自动分类:按商户关键词归入 12 类常用科目(物料采购 / 房租场地费 / 人员工资 / 快递运费 / 平台推广费 / 服务器软件服务费 / 办公耗材 / 税费 / 杂费 等)
调用方式
对外 API(SkillHub 经此端点获取结构化账目):
POST https://emmaenglish.xyz/receipt/api/skill/receipt
Content-Type: application/json
Authorization: Bearer <SKILL_API_KEY>
{
"image": "data:image/png;base64,<图片base64>", // 也支持 multipart/form-data 字段 image(原始图片字节)
"tenant_id": "客户唯一ID(8-64位字母数字_-)" // 可选:传入则识别成功后直接落账到该客户账本
}
image:票据图片,base64(可带data:前缀)或 multipart 字段imagetenant_id:可选。客户唯一标识(合法格式^[A-Za-z0-9_-]{8,64}$,建议用终端用户的 openid / 会话 ID / 账号 ID)。传入后,识别到有效金额(>0)即自动把这笔账写入该客户的专属账本,对话中始终用同一个tenant_id串联该客户的多笔识别与查账(见下方「查账与导出」),无需网页端。- 鉴权:
Authorization: Bearer <SKILL_API_KEY>(服务端配置;未配置时本地放行,生产务必设置) - 响应为 JSON(见下)
- 直接落账响应:外层为
{"ok":true,"result":{<上列字段>},"saved":true,"tenant":"<tenant_id>","record_id":"<本笔ID>"};未传tenant_id或金额无效时saved:false并附save_skipped原因(如「未提供有效 tenant_id,仅返回识别结果(不落账)」「未识别到有效金额,未保存」),此时仍返回result识别结果、不落账。 - 调用方需用同一个
tenant_id串联「同一客户」的多笔识别与查账,保证同一本账。
文字 / 口述记账(自然语言或结构化,无图片也能记)
当用户用文字描述一笔花销(例如「今天买菜花了 50 块现金」「8 月 12 号收到客户货款 2000 支付宝」「买菜35元现金」),不需要图片,直接传给同一个 /api/skill/receipt 端点即可落账。支持两种文字入口:
方式 A:自然语言口述(最少操作,推荐) —— 把原话放进 text 字段,服务端自动解析金额 / 收支 / 渠道 / 备注:
POST https://emmaenglish.xyz/receipt/api/skill/receipt
Content-Type: application/json
{ "text": "买菜35元现金", "tenant_id": "<可选>" } // 自动解析为 35元 / 现金 / 支出 / 备注"买菜"
{ "text": "收到客户货款2000微信", "tenant_id": "<可选>" } // 自动解析为 2000元 / 微信 / 收入
方式 B:结构化 entry —— 调用方先整理成结构化字段再传:
POST https://emmaenglish.xyz/receipt/api/skill/receipt
Content-Type: application/json
{
"entry": {
"date": "2026-08-20", // 可选,缺省为今天(YYYY-MM-DD)
"amount": 50, // 必填且 >0(数字)
"type": "expense", // income / expense / transfer(缺省 expense)
"channel": "现金", // 微信 / 支付宝 / 对公银行卡 / 个人银行卡 / 现金
"category": "物料采购", // 可选,缺省 杂费
"note": "买菜", // 备注 / 商户名
"invoice": "无票", // 可选:增值税专票 / 增值税普票 / 无票
"invoiceNo": "" // 可选
},
"tenant_id": "<可选,同图片模式>"
}
- 两种文字入口响应与图片模式一致:
saved:true表示已落账,并额外带"manual":true标记。若既无图片又无有效amount(方式 A 解析不出金额、方式 B 缺 amount),返回 400 并提示可改用文字记账。 - 关键行为(务必遵守):每次成功记账(无论图片还是文字)后,必须紧接着调用
/api/skill/ledger(同一tenant_id)把记账表格读出来讲给用户听(汇总 + 最近几笔明细),让用户确认「这笔已经记进去了」。绝不要只回「收到」「好的」之类空话,也不要让用户自己猜有没有记上。
查账与导出(Skill 只读端点)
网页端已停用,查账 / 导出全部走 Skill。在对话中让 Agent 调用本端点即可把账本读出来讲给用户听,或导出 CSV:
POST https://emmaenglish.xyz/receipt/api/skill/ledger
Content-Type: application/json
Authorization: Bearer <SKILL_API_KEY>
{ "tenant_id": "<客户唯一ID>", "month": "2026-08" } // month 可选,按"YYYY-MM"过滤某一月
- 响应(JSON):
count:流水条数summary:income/expense/balance(余额 = 收入 − 支出),以及by_channel(按渠道汇总)、by_category(按分类汇总)records:流水明细(按日期倒序,字段同上方输出规范)csv:可直接下载 / 转发给客户的 CSV 文本(含表头:日期,类型,金额,渠道,分类,备注,往来方,单号,发票,发票号)
- 鉴权同 receipt 端点(
Bearer <SKILL_API_KEY>);tenant_id非法返回 400。 - Agent 用法示例:「查看客户 X 本月账本」→ 调用 ledger(tenant_id=X, month=本月)→ 用自然语言把
summary+records讲给用户,需要明细就附上csv。
注:线上同时兼容旧路径
https://emmaenglish.xyz/api/skill/ledger(nginx 已做兼容反代)。
输出规范(给调用方 / Agent 的约束)
- 返回字段固定为:
date:交易日期YYYY-MM-DD(识别失败为空串)amount:金额,字符串两位小数(如"56.80")store:商户名(如"全家便利店")channel:微信/支付宝/对公银行卡/个人银行卡/现金/ 空串type:income/expense/transfercategory:自动归类科目(如"物料采购")invoice:增值税专票/增值税普票/无票invoiceNo:发票号码(无则空串)rawText:OCR 原文(便于追溯 / 复核)orientation:识别所用的旋转角0/90/180/270
- 金额以「实付 / 收款」优先,优惠场景记实际支付额
- 未识别到的字段返回空字符串,不臆造
典型请求示例
- 上传一张超市小票 →
{amount:"86.40", channel:"现金", category:"物料采购", type:"expense", invoice:"无票"} - 上传一张增值税专用发票 →
{invoice:"增值税专票", invoiceNo:"044001900211", type:"expense"} - 上传一张「货款收款」凭证 →
{type:"income", channel:"支付宝"} - 口述记账 →
{"text":"买菜35元现金"}→ 自动解析为 35元 / 现金 / 支出 / 备注"买菜"
计费
本 Skill 为 SkillHub Pay Skill,采用按次付费模式:
- 单价:¥0.2 / 次(早期推广价;具体价格以 SkillHub 平台「定价入口」配置为准)。
- 支付与计费流程由 SkillHub 平台通过 X402 协议统一处理,结算至开发者绑定的微信商户号;开发者侧无需在 Skill 内部自行实现微信支付扣款逻辑。
- 用户在 SkillHub 内调用本 Skill 时,平台会根据配置的单价自动完成计费,Skill 后端只负责接收已计费的请求并返回记账结果。
计费单价与结算规则以 SkillHub 平台侧「发布团队 Skill」流程中的定价入口为准,此处仅为对外公示口径。
X402 支付协议(Pay Skill 改造)
本 Skill 遵循 SkillHub X402 支付协议,按以下流程处理付费调用:
前置检查
每次调用前,服务端检查请求头 WeixinPay-Paid 是否携带有效支付凭证。无凭证或凭证失效时进入付费触发流程;环境变量(SKILL_ID + WXPAY_APPID)未配置时自动降级为免费放行。
支付触发(X402)
未支付时,服务端完成「微信 Native 下单 + X402 预下单」,返回 HTTP 402 并携带 WeixinPay-Required 响应头(值为 paymentCode)。调用方将该值交给 weixinpay_pay 向用户申请支付授权,支付金额按单次调用价从用户微信 AI 专属卡余额扣除。
重试机制
用户完成支付授权后,客户端携带 WeixinPay-Paid 支付凭证重新发起同一请求,服务端校验通过即返回识别/查账结果。支付失败或取消时返回友好提示,用户可重新发起支付后重试,无需重新上传票据图片。
订单号传递
每次付费调用生成唯一订单号(out_trade_no),经 X402 预下单接口与 SkillHub 支付平台关联,并通过 /api/pay/notify 支付回调接口与微信支付平台同步订单状态,用于对账、退款与争议处理。
异常处理
- 支付超时:返回提示引导用户检查微信 AI 专属卡余额或重新发起支付
- 支付回调验签失败:记录异常日志并拒绝落账,防止伪造通知
- 订单状态不一致:以微信支付平台回调为准,启动补偿重试保证最终一致
- 退款/争议:凭订单号追溯单次调用记录,支持退款处理
微信扫一扫