发票云(智能特性)
旗舰版标准版智能特性生态版
旗舰版标准版智能特性生态版
  1. 三单匹配
  • 整体介绍
  • 开发指南
  • 授权
    • token获取
      POST
  • 智能特性
    • 文档信息识别
      • 国际发票识别
      • 国际发票识别(明细)
      • 文档信息识别(反馈)
      • 银行回单识别
    • 三单匹配
      • 三单匹配-normal 正常匹配场景
      • 三单匹配-init 初始化匹配场景
      • 三单匹配-refine 指定候选集合精配场景(规划中)
      • 三单匹配-同步接口
        POST
      • 三单匹配-异步匹配任务提交
        POST
      • 三单匹配-异步匹配结果查询
        POST
      • 三单匹配-异步数据入库
        POST
      • 三单匹配-异步数据入库结果查询
        POST
      • 三单匹配-异步标注数据导入
        POST
      • 三单匹配-异步标注数据导入结果查询
        POST
      • 三单匹配-异步训练接口
        POST
      • 三单匹配-异步训练结果查询
        POST
      • 三单匹配-异步模型一键部署接口
        POST
      • 三单匹配-异步模型一键部署查询接口
        POST
    • 统一反馈
      • 三单匹配反馈详细说明
      • 算法服务统一反馈接口
    • 文档分类(区分发票、附件)
      POST
    • 智能赋码税收分类编码识别
      POST
  • 文档中心
    • 外部文件上传接口
      POST
  • 国际发票
  • 数据模型
    • 示例数据模型
      • Pet
      • Category
      • Tag
  1. 三单匹配

三单匹配-refine 指定候选集合精配场景(规划中)

refine:指定候选集合精配场景#

规划中,尚未实现。 本文用于业务对接的接口契约说明,当前服务不能据此调用 refine 场景。

一、适用场景#

业务已确定一张发票整体对应的完整入库明细集合,需要将这些明细进一步分配到发票行。仍调用异步匹配任务提交接口,显式传 requestScene="refine",不增加专用 URL。
规则约定
请求范围单个客户、单个供应商的一张发票;两侧文件均至少一行,发票文件全部 doc_id 相同
候选范围candidateUrl 只放本张发票已选定、需要全部使用的明细,不能附带其他待检索候选
完整分配成功时覆盖全部发票行,每行至少一条连线;每条候选都参与分配,已提供的金额、数量分别全部分完
匹配关系允许一对多、多对多及同一候选跨发票行拆分
金额数量偏差不强制逐行或整票配平;无调整行、调整后仍有差额均可处理,不因超出普通匹配容差而拒绝
旧结果参考优先复用仍适用的普通明细关系及可用分配;删除旧候选的行、没有旧结果的行继续匹配;可追加候选和重新分配
调整行调用方提供并标记,可正、可负、可为零;可分给一行或分摊到多行,服务不会自动生成调整行凑平
反馈不建立反馈任务,不需要调用反馈接口;旧结果不代表客户确认事实,不作为反馈或历史学习数据
旧候选被删除时,无需先替系统清理旧结果中的连线,直接回传原结果即可。已不在本次发票文件中的旧发票行不会重新加入本次输入。旧候选全部保留的行也允许追加候选;额度超出本次可用值、共享额度冲突或仍有未覆盖行时,可重新分配。

二、请求参数#

请求方式为 POST,地址为 /ai/knowledge/nlpService/item/match/push,Body 为 application/json。鉴权参数沿用主接口。
参数类型必填说明
requestScenestring是固定 refine,不能省略;省略会按 normal 处理
clientIdstring是非空客户 ID
supplierIdstring是非空供应商 ID,两份文件均属于该客户及供应商
targetUrlstring是本张发票明细 CSV 下载地址,见第三节
candidateUrlstring是本张发票完整候选集合 CSV 下载地址,见第四节
previousMatchDetailsarray是之前的匹配明细;无旧结果时传空数组 [],见第五节
本场景无需传 settings、enableFeedback、useVectorStore。传入时直接忽略其内容,不执行普通匹配对这些参数的校验。 不启用反馈,不应用容差、过滤、匹配关系、返回模式、单位模式、正负号或优先级策略。必须通过两个 URL 提供 CSV。
不增加队列选择参数,也不将 refine 解释为新的高低优先级档位。可按现有流程先调用数据入库接口,但不会改变本次 candidateUrl 表示的选定集合,不要求调用方预先保证全部明细已有向量。

三、发票明细 CSV#

UTF-8 编码,首行为列名,一行一条明细。
列名类型必填说明
item_idstring是非空、文件内唯一,与旧结果 targetItemId 保持一致
doc_idstring是非空发票 ID,同一请求所有发票行一致
product_namestring是发票商品名称;发票自身有折扣等明细时填写实际名称
specification_modelstring否规格型号,可为空
unitstring否数量单位;缺失或不可比较时不强制判断数量一致
quantitynumber条件必填本次待分配数量,与 amount 至少一项有值
amountnumber条件必填本次待分配金额,与 quantity 至少一项有值;存在金额调整时建议提供
unit_pricenumber否本次单价,仅作参考,不做价格容差硬过滤
business_timestring否业务日期,建议 yyyy-mm-dd,可为空
tax_ratenumber否税率,小数表示,如 0.13;可为空,不据此硬过滤

四、候选入库明细 CSV#

UTF-8 编码,首行为列名,一行一条候选。每行必须用完,is_adjustment 列必填。
列名类型必填说明
item_idstring是非空、文件内唯一;旧普通明细沿用原 ID,调整行使用独立、不冲突的明细 ID
doc_idstring是非空入库单 ID;普通行沿用原 ID,调整行由调用方生成独立单号
is_adjustment0/1 或 boolean 文本是普通明细填 0 / false,调整行填 1 / true;建议填 0 或 1,不得为空,布尔文本大小写不敏感
product_namestring是普通行填实际商品名;调整行可填“调整行”,无需与发票语义接近
specification_modelstring否规格型号,调整行可为空
unitstring否候选原生单位,调整行可为空
quantitynumber条件必填本次分给该发票的全部可用数量;普通行与 amount 至少一项有值;调整行可为空,已知真实数量为零时填 0
amountnumber条件必填本次分给该发票的全部可用金额;普通行与 quantity 至少一项有值;调整行必填,允许正数、负数或零
unit_pricenumber否本次单价,可为空,仅作参考
product_codestring否商品编码,调整行可为空
business_timestring否业务日期,建议 yyyy-mm-dd,调整行可为空
tax_ratenumber否税率,小数表示,可为空,不据此硬过滤
两侧数值缺失用空单元格表示,不用 0 代替;仅接受有限数,不接受 NaN 或无穷大。金额或数量允许负数,零与缺失不同。候选已提供的零值维度也按零守恒;所有已提供数值都为零的候选仍返回关联关系。
额度由调用方确定:同一入库明细总额 10 元,本张发票应使用 5 元,则本次只填 5 元;若填 10 元会全部分配,不自动扣除其他发票额度,也不进行跨请求余额扣减。同一明细不得重复 CSV 行,应合并本次额度后仅传一行,返回可拆成多条连线。两侧币种及含税/不含税口径须一致,服务不做税额或币种转换。

五、previousMatchDetails 旧结果#

结构沿用之前返回的 matchDetails:同步结果取 data.matchDetails,异步查询结果取 data.result.matchDetails。异步 JSON 请求直接传数组。无旧结果时传 [],本次全部连线标记 ADDED。score 可省略,即使传入也忽略。
字段类型说明
[].targetItemIdstring原发票明细 ID
[].candidateItemarray原候选连线列表
[].candidateItem[].candidateDocIdstring原入库单据 ID
[].candidateItem[].candidateItemIdstring原入库明细 ID
[].candidateItem[].allocatedAmountnumber / null原分配金额;缺失视为未知,不能视为 0
[].candidateItem[].allocatedQuantitynumber / null原分配数量(候选原生单位);缺失视为未知

六、提交响应与结果查询#

提交成功仍返回 data.taskId,使用原异步匹配结果查询接口传 {"taskId":"..."} 查询。任务状态沿用该查询接口,完成后本节结果位于 data.result。本场景不返回反馈 task 标识。
结果字段(相对 data.result)类型说明
matchDocIdsarray of string全部候选单据 ID 去重汇总,包含调整行单据
matchDetailsarray包含本次全部发票行
matchDetails[].targetItemIdstring发票明细 ID
matchDetails[].candidateItemarray至少一条实际分配连线;已删除的旧连线不返回
candidateItem[].candidateDocIdstring本次候选单据 ID
candidateItem[].candidateItemIdstring本次候选明细 ID,可出现在多个发票行下
candidateItem[].isAdjustmentboolean对应输入 is_adjustment
candidateItem[].allocatedAmountnumber / null当前连线分配金额;候选未提供该维度时为 null,不以 0 替代,也不凭单价补算
candidateItem[].allocatedQuantitynumber / null当前连线分配数量,使用候选原生单位;缺失时为 null
candidateItem[].changeStatusstringUNCHANGED / MODIFIED / ADDED,见下表
上表 candidateItem 字段均位于 matchDetails[].candidateItem[]。不要求返回普通匹配的 score,不提供发票行级的变更汇总。
changeStatus判断规则
UNCHANGED原结果存在同一“发票明细 ID + 候选明细 ID”连线,金额按两位小数、数量按四位小数归一后均未变化
MODIFIED原结果存在该连线,但金额或数量至少一维归一后变化,包括未知与已知值之间变化
ADDED原结果不存在该连线;更换候选明细 ID 即算新增,即使商品名称相同
比较采用十进制 ROUND_HALF_UP,两次都缺失的维度视为未变化。两位/四位仅用于变更比较,实际分配可保留更多小数位以保证逐候选守恒。调用方展示可自行格式化,不应逐条简单舍入后用展示值判断原始结果是否守恒。
UNCHANGED 不表示客户确认正确或算法保证正确。不返回 REMOVED 列表;业务判断哪些发票行需要复核时,须同时比较前后候选 ID 集合及本次连线标识,避免漏掉旧连线被删除的行。

七、完整示例#

发票两行分别为 9.99 元、9.98 元;普通入库明细各 10 元,另提供 −0.03 元调整行。
targetUrl 文件:
item_id,doc_id,product_name,specification_model,unit,quantity,amount,unit_price,business_time,tax_rate
INV001_1,INV001,阿莫西林胶囊,,盒,1,9.99,9.99,2026-10-14,0.13
INV001_2,INV001,维生素C片,,盒,1,9.98,9.98,2026-10-14,0.13
candidateUrl 文件:
item_id,doc_id,is_adjustment,product_name,specification_model,unit,quantity,amount,unit_price,business_time,tax_rate
GR001_1,GR001,0,阿莫西林胶囊,,盒,1,10,10,2026-10-14,0.13
GR001_2,GR001,0,维生素C片,,盒,1,10,10,2026-10-14,0.13
ADJ001_1,ADJ001,1,调整行,,,,-0.03,,,
异步提交请求:
{
  "requestScene": "refine",
  "clientId": "client_001",
  "supplierId": "supplier_001",
  "targetUrl": "https://file.example.com/invoice-refine.csv",
  "candidateUrl": "https://file.example.com/candidates-refine.csv",
  "previousMatchDetails": [
    {
      "targetItemId": "INV001_1",
      "candidateItem": [
        {
          "candidateDocId": "GR001",
          "candidateItemId": "GR001_1",
          "allocatedAmount": 10,
          "allocatedQuantity": 1
        }
      ]
    },
    {
      "targetItemId": "INV001_2",
      "candidateItem": [
        {
          "candidateDocId": "GR001",
          "candidateItemId": "GR001_2",
          "allocatedAmount": 10,
          "allocatedQuantity": 1
        }
      ]
    }
  ]
}
异步完成后的 data.result:
{
  "matchDocIds": [
    "GR001",
    "ADJ001"
  ],
  "matchDetails": [
    {
      "targetItemId": "INV001_1",
      "candidateItem": [
        {
          "candidateDocId": "GR001",
          "candidateItemId": "GR001_1",
          "isAdjustment": false,
          "allocatedAmount": 10,
          "allocatedQuantity": 1,
          "changeStatus": "UNCHANGED"
        },
        {
          "candidateDocId": "ADJ001",
          "candidateItemId": "ADJ001_1",
          "isAdjustment": true,
          "allocatedAmount": -0.01,
          "allocatedQuantity": null,
          "changeStatus": "ADDED"
        }
      ]
    },
    {
      "targetItemId": "INV001_2",
      "candidateItem": [
        {
          "candidateDocId": "GR001",
          "candidateItemId": "GR001_2",
          "isAdjustment": false,
          "allocatedAmount": 10,
          "allocatedQuantity": 1,
          "changeStatus": "UNCHANGED"
        },
        {
          "candidateDocId": "ADJ001",
          "candidateItemId": "ADJ001_1",
          "isAdjustment": true,
          "allocatedAmount": -0.02,
          "allocatedQuantity": null,
          "changeStatus": "ADDED"
        }
      ]
    }
  ]
}
两条普通候选各分完 10 元及 1 盒,调整行合计分完 −0.03 元。响应行序、候选序和单据 ID 顺序不保证与示例一致。

八、失败处理#

缺少必填参数、文件无数据、重复明细 ID、多张发票混传、数值非法、发票或普通候选数量金额均缺失、调整行金额缺失、is_adjustment 非法、旧结果结构非法等返回参数错误 2001。提交时已发现的错误直接返回;异步执行阶段的错误通过查询结果 status=FAILED 和 error 返回。
总额不同、调整后仍有差额、名称相似度低、旧候选不在本次集合中,不属于上述参数错误。完整分配是成功约束,不是正确率承诺。文件下载失败或服务异常仍按错误返回;无法形成或验证完整结果时不能以部分结果返回成功。
修改于 2026-10-15 03:30:59
上一页
三单匹配-init 初始化匹配场景
下一页
三单匹配-同步接口
Built with