← Back to skills
extension
Category: Data & AnalyticsAPI key required

商家记账助手

票据记账助手 —— 个体户/小微企业专用,拍照或上传票据图片,自动识别日期/金额/收付款渠道(微信/支付宝/银行卡/现金)/收支类型/发票(专票/普票)/分类,返回结构化账目 JSON。当用户需要 OCR 识别发票小票、自动记账、提取票据结构化信息、生成流水、记账自动化、invoice OCR、receipt OCR、expense tracking 时使用。

personAuthor: u_d7704acfhubenterprise

票据记账助手(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 字段 image
  • tenant_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 的约束)

  1. 返回字段固定为:
    • date:交易日期 YYYY-MM-DD(识别失败为空串)
    • amount:金额,字符串两位小数(如 "56.80")
    • store:商户名(如 "全家便利店")
    • channel:微信 / 支付宝 / 对公银行卡 / 个人银行卡 / 现金 / 空串
    • type:income / expense / transfer
    • category:自动归类科目(如 "物料采购")
    • invoice:增值税专票 / 增值税普票 / 无票
    • invoiceNo:发票号码(无则空串)
    • rawText:OCR 原文(便于追溯 / 复核)
    • orientation:识别所用的旋转角 0/90/180/270
  2. 金额以「实付 / 收款」优先,优惠场景记实际支付额
  3. 未识别到的字段返回空字符串,不臆造

典型请求示例

  • 上传一张超市小票 → {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 专属卡余额或重新发起支付
  • 支付回调验签失败:记录异常日志并拒绝落账,防止伪造通知
  • 订单状态不一致:以微信支付平台回调为准,启动补偿重试保证最终一致
  • 退款/争议:凭订单号追溯单次调用记录,支持退款处理