一、项目概述
1.1 票据的核心概念
票据是依据法律规定形式制成的、载明支付金钱义务的凭证,广义上涵盖各类有价证券和凭证。在国际贸易中,汇票(BILL OF EXCHANGE) 是最核心的票据类型,它是一种无条件支付的委托,涉及三个关键当事人:
- 出票人:开立票据并承担付款保证责任的法人、组织或个人;
- 受票人(付款人):接受支付委托的主体,通常为银行或企业;
- 收款人:凭汇票请求支付的债权人,一般为交易中的卖方。
示例:A 公司(出票人)通过 C 银行(受票人)向 B 公司(收款人)签发汇票,三方盖章确认后,该凭证成为具有法律效力的有价证券,解决了国际贸易中 “付款怕收不到货、发货怕收不到款” 的信任难题。
1.2 传统汇票的痛点与系统升级背景
传统纸质汇票存在易遗失、易伪造、结算效率低等问题。为解决这些问题,2021 年 5 月上海票据交易所(以下简称 “票交所”)发布《新一代票据业务系统业务方案》,对原有电子商业汇票系统(ECDS)和中国票据交易系统进行全面升级,要求各金融机构通过系统对接实现票据全生命周期的电子化管理。
1.3 系统技术架构
票据系统采用微服务架构,分为三个核心模块:
- 票据业务服务:对接前端,负责业务展示与发起;
- 票据直连服务:处理交易流程、组装报文、实现复杂业务逻辑;
- 报文接入服务:对接票交所,负责报文的发送 / 接收、加解密及验签。
二、票据系统全流程:业务需求与技术实现
2.1 业务前准备:企业信息报备
业务需求
企业需先在票交所开立账户并报备信息,才能开展电子票据交易。报备信息包括企业基础信息(名称、统一社会信用代码)、结算账户信息等,经票交所审核通过后生效。
技术实现
- 信息录入与提交:
- 企业通过银行网银或财务公司系统录入信息,由柜面端提交至系统;
- 系统调用票据直连服务生成报备报文,通过报文接入服务发送至票交所。
- 状态跟踪:
- 报备状态实时更新(未报备→审核中→通过 / 驳回);
- 若审核失败,票交所返回包含拒绝原因的报文,系统解析后展示给用户。
- 数据校验:
- 本地系统先校验信息格式(如统一社会信用代码规则),减少票交所驳回概率。
2.2 票据签发:从申请到生效
业务需求
- 出票登记:出票企业录入票据信息(承兑人、收款人、金额、到期日等),提交申请;
- 提示承兑:承兑人(银行或财务公司)审核并确认承兑,票据生效;
- 提示收票:收款人确认接收票据,完成权利转移;
- 撤票:出票人可在收款人签收前撤销票据。
技术实现
- 数据存储与校验:
- 票据信息存入数据库,通过唯一索引(如票据编号)避免重复;
- 校验承兑人是否已在票交所报备,确保其具备承兑资格。
- 审批流程:
- 集成工作流引擎(如 Activiti),实现多级审批(经办人→部门经理→风控);
- 审批过程中使用Redis 分布式锁,防止多人同时审批同一票据。
- 报文交互:
- 出票申请通过后,票据直连服务生成《出票登记报文》,通过 MQ 通知报文接入服务发送至票交所;
- 票交所返回含
OriginMsgId的响应报文,系统关联本地业务 ID 与OriginMsgId,用于后续追踪。
- 状态同步:
- 接收票交所的承兑结果报文,更新本地票据状态(待承兑→已承兑 / 拒绝);
- 若承兑通过,自动触发《提示收票报文》发送,通知收款人。
- 撤票处理:
- 校验票据状态(未签收),生成《撤票申请报文》;
- 票交所确认后,更新票据状态为 “已撤销”,并通过 MQ 通知相关方(如收款人网银)。
2.3 票据流转:背书、质押与贴现
2.3.1 转让背书
业务需求
持票人可将票据权利转让给他人,需明确背书人、被背书人、金额等信息,被背书人需在票交所有账户才能接收。
技术实现
- 背书信息校验:
- 校验被背书人是否已报备,若未报备则拦截操作;
- 检查票据是否可转让(根据出票时的 “是否可转让” 标识)。
- 报文发送与状态更新:
- 生成《转让背书报文》,包含背书类型(记名 / 限制等),通过票交所转发至被背书人开户行;
- 被背书人签收后,票交所返回确认报文,系统更新票据持有人信息。
- 并发控制:
- 背书操作前锁定票据记录(
SELECT ... FOR UPDATE),防止同一票据同时被多次背书。
2.3.2 质押与贴现
业务需求
- 质押:持票人以票据为抵押申请贷款,到期还款后解除质押;
- 贴现:持票人将未到期票据转让给银行,银行扣除利息后支付现金;
- 回购式贴现:企业短期融资后,可在到期前赎回票据,减少利息损失。
技术实现
- 质押流程:
- 质押申请时,冻结票据(更新状态为 “已质押”),同时在贷款系统创建质押合同;
- 使用Seata 分布式事务(XA 模式),确保 “票据冻结” 与 “贷款发放” 要么同时成功,要么同时回滚。
- 贴现计算:
- 基于公式
贴现金额=票面金额-利息(票面金额×天数×利率),通过 Java 代码实现自动计算; - 利率根据央行基准实时调整,缓存于 Redis,避免频繁查询数据库。
- 报文处理:
- 贴现申请生成《贴现申请报文》,通过线程池批量发送(核心线程 5 个,最大 20 个),提高处理效率;
- 接收票交所确认报文后,更新票据状态为 “已贴现”,并触发账务系统记账(借:票据资产,贷:现金)。
2.4 票据到期:提示付款与追索
业务需求
- 提示付款:持票人在到期日(或提前)向承兑人请求付款;
- 兑付:承兑人足额付款,票据结清;
- 追索:若付款失败(如账户余额不足),持票人可向出票人或前手追索。
技术实现
- 自动提示付款:
- 定时任务(Quartz)每日扫描到期票据,自动生成《提示付款报文》;
- 若报文发送失败,通过 MQ 死信队列存储,由重试机制(每 30 分钟一次)重新发送。
- 对账机制:
- 每日凌晨通过定时任务比对本地交易记录与票交所《清算文件》,确保金额一致;
- 不一致时生成异常报表,通知运营人员处理。
- 追索处理:
- 记录追索链条(通过链表结构存储前手信息),生成《追索通知报文》;
- 追索过程中锁定相关账户资金,防止债务人转移资产。
2.5 票交所报文流转与加密
业务需求
所有票据交易需通过票交所流转,报文需加密传输,确保安全性。
技术实现
- 报文结构:
- 采用 XML 格式,包含固定字段(报文类型、发送方、接收方)和业务字段(票据信息、交易类型);
- 报文头部生成唯一
MsgId,用于追踪和去重。
- 加解密流程:
- 加密:使用SM4 对称算法加密报文内容,SM3 算法生成摘要,SM2 非对称算法加密 SM4 密钥;
- 解密:接收方用 SM2 私钥解密 SM4 密钥,再解密报文内容,验证 SM3 摘要确保未被篡改。
- 异常处理:
- 加密失败时,记录错误日志并触发告警(如短信通知开发人员);
- 接收报文解密失败,返回错误码,要求发送方重发。
三、技术难点与解决方案
3.1 分布式事务一致性
问题:票据签发涉及多模块操作(如冻结保证金、生成报文、更新状态),若某一步失败,需全部回滚。
解决方案:使用 Seata XA 模式,通过事务管理器协调各数据库分支事务,确保强一致性。
3.2 高并发下的报文发送
问题:高峰期(如月底)票据交易量大,直接调用票交所接口可能导致超时或失败。
解决方案:
- 引入 RabbitMQ 作为缓冲,业务系统发送消息后立即返回,报文服务异步消费并发送;
- 消息设置过期时间(如 24 小时),失败后进入死信队列,人工介入处理。
3.3 数据一致性校验
问题:票交所返回超时,但实际业务已处理,导致本地状态与票交所不一致。
解决方案:
- 发送业务请求前,先调用票交所查询接口,确认是否已处理;
- 每日定时对账,比对交易金额、状态,差异项自动生成工单。
四、总结
票据系统通过微服务架构实现了业务与技术的解耦,核心亮点包括:
- 全流程电子化:替代纸质票据,解决易遗失、伪造问题;
- 安全可靠:基于国密算法加密和分布式锁,保障交易安全;
- 高效协同:通过 MQ、线程池和分布式事务,支撑高并发场景。
系统不仅满足了企业间票据交易需求,更通过与票交所的实时对接,实现了国际贸易中资金与货物的安全流转,为跨境结算提供了坚实的技术支撑。