Files
Ticket/history/票通对接业务流程说明.md
T
2026-05-07 10:25:02 +08:00

14 KiB
Raw Blame History

票通对接业务流程说明

本文基于以下资料整理:

1. 你的角色本质是什么

结论:是的,你本质上是“接入方平台 / 第三方平台 / 中台”,帮助甲方企业对接票通,以甲方企业的名义完成开票。

但这里不是简单的 HTTP 转发,还包括以下职责:

  • 维护“你的平台”和“开票企业”的绑定关系
  • 维护或选择甲方企业可用的数电账号
  • 组织开票报文并调用票通接口
  • 处理登录认证、风险认证
  • 接收票通推送或主动查询开票结果
  • 再把开票结果回写给你自己的业务系统

从票通文档看,这个角色被明确定义为:

  • 第三方平台 / 集团企业
  • 接入方系统

关键依据:

  • 对接指引说明“接入方系统开发完成后,由票通提供正式环境参数”
  • 直接开票场景中,系统接入方组织好待开票信息后,直接调用 2.9 开具蓝字数电发票
  • 企业通过接口注册后,会自动生成“平台和企业的绑定关系”;如果企业已在票通完成入驻,则需要联系票通侧建立“接入方平台和开票企业的绑定关系”

所以业务归属上:

  • 开票主体是甲方企业
  • 票通是开票服务平台
  • 你是中间接入平台

2. 票通是否提供测试接口

结论:提供。

2.1 测试环境说明

票通对接指引明确写了:

  • 测试环境和参数信息由票通对接人员提供
  • 包括平台编码、RSA 证书、3DES 密钥、测试税号
  • 正式上线前,再由票通提供正式环境参数

文档里的核心说明:

  • 测试环境参数:平台编码、RSA 签名验签证书、3DES 密钥、测试税号
  • 联调测试阶段,可直接使用票通对接人员提供的测试税号

2.2 测试地址风格

核心测试地址统一是:

http://fpkj.testnw.vpiaotong.cn/tp/openapi/...

正式地址统一是:

https://fpkj.vpiaotong.com/tp/openapi/...

2.3 你当前真正会用到的测试接口

  • register.pt
  • registerUser.pt
  • sendLoginSmsCode.pt
  • smsLogin.pt
  • getAuthenticationQrcode.pt
  • queryAuthQrcodeScanStatus.pt
  • getTaxBureauAccountAuthStatus.pt
  • listTaxBureauAccount.pt
  • invoiceBlue.pt
  • queryInvoice.pt
  • queryInvoiceInfo.pt
  • logoutEtax.pt
  • getEnterpriseInfo.pt
  • queryEnterpriseBankInfo.pt

注意:

  • 推送接口 2.13 / 2.14 / 2.48 没有票通固定测试地址,因为这是“票通调用你提供的接口地址”
  • 也就是说,回调 URL 不是你调用票通时传进去的,而是你提供给票通侧配置使用的

3. 开票结果“回写”到底分几层

这里要分清楚两层,不要混在一起。

3.1 第一层:票通把结果返回给你的平台

这是票通体系内的结果同步,主要有两种方式:

方式 A:票通推送

票通文档定义了:

  • 2.13 推送发票主要信息
  • 2.14 推送发票全票面信息

调用关系写得很明确:

  • 票通平台调用第三方平台
  • 接口地址:第三方平台提供

这就是我们说的“回调”。

方式 B:你的平台主动查询

票通文档定义了:

  • 2.11 查询发票主要信息
  • 2.12 查询发票全票面信息

也就是说,开票结果可以:

  • 等票通推送过来
  • 或者你主动轮询查询

最佳实践不是二选一,而是:

  • 主用推送
  • 查询作为补偿和兜底

3.2 第二层:你的平台再把结果写回你自己的业务系统

这个“开票结果回写接口”不是给票通用的。

它是你自己的业务系统接口,用来做这些事:

  • 把原始业务单据状态改成“开票成功/失败/处理中”
  • 回写发票号码、数电发票号码、开票日期
  • 回写失败原因
  • 记录票通流水号或发票请求流水号

所以:

  • 票通 -> 你的平台:票通文档里有
  • 你的平台 -> 你的业务系统:票通文档里没有,需要你自己定义

4. 回调是怎么和票通绑定的

从文档能确认两件事:

  1. 2.13 / 2.14 / 2.48 都是“票通平台调用第三方平台”
  2. 接口地址不是你在开票请求里传递,而是“第三方平台提供”

因此可以得出一个明确结论:

  • 回调地址不是按每张发票动态传的
  • 而是你先提供给票通,由票通侧事先配置

文档没有给出“通过某个接口动态设置回调地址”的描述,所以这里应按“线下配置 / 对接阶段配置”理解。

实际落地时通常就是:

  1. 你先准备一个公网可访问的回调地址
  2. 提供给票通对接人员
  3. 票通侧把这个地址配置成推送接收地址
  4. 票通后续在开票成功、失败、认证异常等场景调用你的回调接口

对你来说要注意:

  • 回调接口必须能公网访问
  • 必须按票通公共报文做验签和解密
  • 要做幂等,避免重复推送重复入库
  • 不能只靠回调,最好仍保留主动查询兜底

5. 开票结果样例怎么理解

这里也分两种。

5.1 票通推送/查询给你的样例

这个在票通文档里是有的。

最有代表性的就是:

  • 2.13 推送发票主要信息 样例
  • 2.11 查询发票主要信息 样例
  • 2.12 查询发票全票面信息 样例

例如 2.13 的成功推送报文会包含:

  • taxpayerNum
  • invoiceReqSerialNo
  • invoiceType
  • invoiceKind
  • code
  • msg
  • tradeNo
  • definedData
  • invoiceCode
  • invoiceNo
  • electronicInvoiceNo
  • invoiceDate
  • noTaxAmount
  • taxAmount
  • invoicePdf
  • invoiceXml
  • downloadUrl

其中:

  • code=0000 表示成功
  • code=3999 表示需要扫码或短信认证
  • code=9999 表示开票失败

5.2 你写回甲方业务系统的样例

这个在票通文档里没有,因为这是你自己的内部系统接口。

你至少需要自己约定一份这样的回写报文:

{
  "bizOrderNo": "CG202604290001",
  "companyId": "COMP_001",
  "invoiceReqSerialNo": "DEMO202604290001234567",
  "status": "SUCCESS",
  "ptCode": "0000",
  "ptMsg": "开具成功",
  "invoiceCode": "123456789012",
  "invoiceNo": "12345678",
  "electronicInvoiceNo": "12345678901212345678",
  "invoiceDate": "2026-04-29 14:20:31",
  "noTaxAmount": "90.50",
  "taxAmount": "11.50",
  "downloadUrl": "https://...",
  "definedData": "自定义数据"
}

失败样例建议至少保留:

{
  "bizOrderNo": "CG202604290001",
  "companyId": "COMP_001",
  "invoiceReqSerialNo": "DEMO202604290001234567",
  "status": "FAILED",
  "ptCode": "9999",
  "ptMsg": "开票失败,失败原因见票通返回",
  "failReason": "票通返回的失败描述"
}

6. 按业务流程顺序,你需要知道和会用到的接口

下面按实际开发顺序来列,不按文档章节号罗列。

6.1 安全机制和公共报文

所有接口调用前都要先满足:

  • 公共报文使用 RSA 签名
  • 业务报文使用 3DES 加密
  • 编码统一 UTF-8
  • 公共字段包括:
    • platformCode
    • signType
    • sign
    • format
    • timestamp
    • version
    • serialNo
    • content

注意事项:

  • content 里放的是除公共参数外的全部业务参数
  • RSA 签名结果要做 Base64 编码
  • 业务 JSON 编码统一 UTF-8

6.2 企业是否已入驻票通

你需要先确认开票企业是否已经具备票通开票资格。

可用接口:

  • 2.2 注册企业
  • 2.47 查询企业信息
  • 2.48 企业审核结果推送

使用顺序建议:

  1. 如果甲方企业尚未入驻,走 2.2 注册企业
  2. 注册后用 2.47 查询企业信息 看审核状态
  3. 如果票通侧支持,可接 2.48 企业审核结果推送

注意事项:

  • 企业必须先完成入驻才能开票
  • 如果企业不是通过接口注册,而是在票通侧已存在,需要和票通做“平台与企业绑定”
  • reviewStatus 要关注:
    • 0 待审核
    • 1 审核通过
    • 2 审核不通过
    • 3 审核中

6.3 数电账号准备

如果甲方企业已经入驻,下一步是准备可以用于开票的数电账号。

可用接口:

  • 2.3 数电账号登记
  • 2.45 查询数电账号列表
  • 2.8 查询数电账号认证状态
  • 2.46 退出电子税局登录

使用顺序建议:

  1. 先用 2.45 查询某税号下已经维护好的数电账号
  2. 如果你需要平台内维护账号,再用 2.3 登记
  3. 开票前用 2.8 检查认证状态
  4. 如存在异常登录状态,再视情况用 2.46 退出后重登

注意事项:

  • 2.3 的密码和身份密码要用票通要求的 3DES 加密
  • 2.45 / 2.8 会返回:
    • operationProposed
    • authStatus
    • switchable
    • wechatUserBindStatus
  • operationProposed 最重要:
    • 0 无需认证
    • 1 需扫码认证
    • 2 需扫码或短信认证
    • 3 需短信认证

6.4 开票前置检查

正式开票前,建议先做企业和票面数据检查。

建议用到:

  • 2.47 查询企业信息
  • 2.49 查询企业开户行及账号
  • 2.45 查询数电账号列表
  • 2.8 查询数电账号认证状态

注意事项:

  • 2.49 文档明确说明:可用于避免“企业没有维护开户行及账号导致开票失败”
  • 如果票通平台和电子税局都没有维护开户行及账号,需要先提醒企业维护
  • 查询电子税局开户行及账号时,要求数电账号已登录认证

6.5 发起开票

核心接口:

  • 2.9 开具蓝字数电发票

你的业务场景重点注意以下字段:

  • invoiceIssueKindCode
    • 农产品收购发票只能开数电普通票,建议按 82
  • specialInvoiceKind
    • 农产品收购发票必须传 02
  • invoiceReqSerialNo
    • 一张发票的唯一幂等号
  • account
    • 明确指定开票使用的数电账号
  • definedData
    • 建议传你自己的业务单号或关联标识,后续推送会原样带回
  • tradeNo
    • 可传业务订单号,不传时票通默认使用 invoiceReqSerialNo

农产品收购发票特别注意:

  • 文档写明:specialInvoiceKind=02 时,只能开具数电票(普通发票)
  • 文档还写明:购方信息代表实际的销方信息,销方信息是实际的购方
  • purchaseInvSellerIdType 开具农产品收购发票时必填
  • buyerTaxpayerNum 开具农产品收购发票时必填

注意事项:

  • invoiceReqSerialNo 对同一张票重试时不能变
  • 文档明确提示:如果变更同一张票的请求流水号,可能造成重开发票
  • 返回里的 qrCodePath / qrCode 可用于打开 H5 实时查看开票状态

6.6 如果开票遇到认证

如果开票返回 3999,不要直接判成普通失败。

可用接口:

  • 2.8 查询数电账号认证状态
  • 2.4 获取登录短信验证码
  • 2.5 短信登录
  • 2.6 获取实名认证二维码
  • 2.7 查询实名认证二维码扫码状态

短信认证路径:

  1. 2.8 看建议
  2. 如果允许短信认证,调 2.4
  3. 再调 2.5 完成登录

扫码认证路径:

  1. 2.6 获取二维码
  2. 展示二维码给用户
  3. 轮询 2.7 查询扫码状态
  4. 认证完成后,再继续原开票流程

注意事项:

  • 2.4 返回 6666 时,文档说“无需真正发送短信验证码,系统会自动登录成功”
  • 2.6 二维码一般 5 分钟左右过期
  • 2.7 文档特别提示:接口比较耗时,请调长超时时间
  • 2.7scanStatus
    • 1 未扫码
    • 2 已扫码
    • 3 二维码已过期

6.7 获取开票结果

结果同步建议两条线都做。

第一条:票通推送

  • 2.13 推送发票主要信息
  • 2.14 推送发票全票面信息

作用:

  • 票通开票成功、失败、需要认证时,主动通知你

注意事项:

  • 接口地址由你提供给票通配置
  • 你返回的业务结果码:
    • 0000 接收成功
    • 9999 接收失败

第二条:主动查询

  • 2.11 查询发票主要信息
  • 2.12 查询发票全票面信息

作用:

  • 回调没到时兜底
  • 开票中状态补偿查询
  • 手动刷新状态

关键状态码:

  • 0000 开票成功
  • 6666 未开票
  • 7777 开票中
  • 9999 开票失败
  • 3999 需要扫码或短信认证

6.8 结果落库并回写你自己的业务系统

这一段票通不会帮你做,需要你自己做。

建议你的平台在收到 2.13 推送或 2.11 / 2.12 查询结果后:

  1. 更新本地开票任务状态
  2. 保存发票号码、数电发票号码、开票时间、失败原因
  3. 再调用你自己的业务系统回写接口

建议你自己的回写接口至少要包含:

  • 业务单号
  • 公司标识
  • 发票请求流水号
  • 开票状态
  • 票通状态码
  • 票通状态描述
  • 发票号码 / 数电发票号码
  • 开票日期
  • 金额 / 税额
  • 下载地址或文件标识

7. 这份文档给你的最终结论

你现在最需要抓住的不是“票通有多少接口”,而是下面这条最小闭环:

  1. 确认企业已入驻且已与平台绑定
  2. 确认企业下有可用数电账号
  3. 开票前检查认证状态和企业基础信息
  4. 2.9 发起农产品收购发票开具
  5. 如遇 3999,走短信认证或扫码认证
  6. 2.13 / 2.14 收推送,同时用 2.11 / 2.12 做补偿查询
  7. 最后把结果回写到你自己的业务系统

如果只按开发优先级排序,你最先应该落的接口就是:

  • 2.45 查询数电账号列表
  • 2.8 查询数电账号认证状态
  • 2.9 开具蓝字数电发票
  • 2.11 查询发票主要信息
  • 2.13 推送发票主要信息
  • 2.4 / 2.5 / 2.6 / 2.7 认证链路

对你这个项目最容易踩坑的点有 4 个:

  • 农产品收购发票字段语义和普通蓝票不同,购销方字段有反转
  • invoiceReqSerialNo 必须稳定复用,不能重试就换
  • 回调地址不是请求里传的,而是提前配置给票通的
  • “开票结果回写接口”不是票通接口,而是你自己的业务系统接口