银行供应链金融平台需求说明书解读:业务总线与接口设计蓝图
2026/9/17 11:28:08 网站建设 项目流程

简介:《XX银行供应链金融业务平台需求说明书(专业完整版)》是一份面向银行产品经理、需求分析师、金融IT架构师及供应链金融业务人员的完整需求文档,适合在平台规划、需求评审或系统设计前期作为对标参考。文档以该行供应链金融业务扩张为背景,先解释了传统手工台账在操作成本、风险控制及流程规范上的不足,再系统梳理预付款融资、动产质押授信、应收账款融资、国内保理等产品的全流程管理、风险预警、会计核算和数据信息管理要求,并说明了与核心系统T24、信贷风险管理信息系统CRMS的接口集成方式,以及未来通过网银实现B2B在线业务处理的演进路径。资源包内共1个PDF文件,整体大小109.49MB,属于专业完整版PDF,内容结构清晰、覆盖面广,可作为银行供应链金融平台项目规划、需求编写、系统设计或内部培训的参考蓝本;目录框架对技术选型与需求评审也具有一定借鉴意义。目前已有131人学习浏览,具备实践参考热度,适合银行金融科技相关从业者按需查阅。

1. 一份银行供应链金融需求说明书,为什么值得当系统架构文档读

某银行产品计划书里夹着一份《XX银行供应链金融业务平台需求说明书》,全文没有代码,却写清了平台必须解决的几件事:多产品、多环节、多系统耦合,以及手工台账无法承载的操作风险。不少项目把这类文档资料当成背景略过,最终做成了在线填单系统,而不是平台。

说明书把平台定位成“业务总线”,点名要接核心系统T24和信贷风险管理信息系统CRMS;业务范围覆盖出口/进口保理、预付款融资、动产质押授信、应收账款融资、贸易信用保险融资和国内保理。对银行科技人员、产品经理和后端集成工程师而言,值得拆成产品、接口、风控核算、验收联调四个层面来读。下面逐个展开。

2. SCF平台的产品矩阵:从五类业务到统一流程抽象

需求说明书中的产品清单乍看很散,但放在“采购—存货—销售”三个供应链环节里就清晰了:预付款融资发生在采购环节,动产质押授信发生在存货环节,应收账款融资和保理发生在销售环节。平台建设的第一步,是把这些产品的流程共性抽出来,而不是先做菜单和页面。

2.1 供应链金融产品对照:预付、存货、应收、信用保险与保理

先给一个粗略的产品分类地图,用来对齐业务视角和系统视角:

产品类别供应链环节授信依托典型风控抓手
预付款融资采购上游发货义务货权凭证、卖方回购
动产质押授信存货存货价值仓储监管、价格盯市
应收账款融资销售买方信用应收账款转让/质押登记
贸易信用保险融资销售保险赔付保险权益转让
出口/进口保理销售/采购买方/卖方信用应收账款催收、坏账担保

这五类产品的“授信依托”差别很大,但业务操作流程高度相似:客户申请、资料核验、额度审查、放款、贷后管理、还款或解除担保。需求说明书之所以提“功能完整、操作灵活”,就是因为产品多而流程共性大,不能每上线一个产品就重做一套流程。

我在实际项目中一般只建一张“融资申请主单据”,每类产品只是主单据上的产品类型字段不同。预付款融资和应收账款融资的差别,主要集中在额度占用时对应的“受托支付信息”和“回款路径”,流程引擎本身不需要换。这样新增产品时,只需要补充产品参数、科目映射和风控规则,平台主干不动。

2.2 从手工台账到状态机:单据流转才是平台的地基

手工台账的问题不在“没用Excel”,而是没有状态约束。业务人员可以直接改上次记录,审批链和审计线索也就失效了。平台要做的第一件事,是用有限状态机约束单据生命周期。下面是融资单状态定义的 Python 示例:

from enum import Enum, auto class OrderState(Enum): DRAFT = auto() # 草稿 SUBMITTED = auto() # 已提交 APPROVED = auto() # 审批通过 DISBURSED = auto() # 已放款 SETTLED = auto() # 已结清 REJECTED = auto() # 已拒绝 # key为当前状态,value为允许跳转的目标状态集合 TRANSITIONS = { OrderState.DRAFT: {OrderState.SUBMITTED, OrderState.REJECTED}, OrderState.SUBMITTED: {OrderState.APPROVED, OrderState.REJECTED}, OrderState.APPROVED: {OrderState.DISBURSED}, OrderState.DISBURSED: {OrderState.SETTLED}, } def can_transition(current: OrderState, target: OrderState) -> bool: return target in TRANSITIONS.get(current, set())

这里的核心不是代码本身,而是规则表达。任何写操作前先执行 can_transition,不满足就拒绝;数据库里同时保存上一状态和当前状态,审计时能重建操作链。比如审批通过后不能直接结清,必须经过放款;拒绝是终态,想继续融资只能重新发起申请。这些规则来自供应链金融的自偿逻辑,不是产品经理拍脑袋。

把状态机落到实现时,我建议状态值使用枚举或统一编码,不要用汉字“审批中”“已放款”。因为汉字在不同系统间容易出现“审批中”和“审批通过中”的不一致,统一编码后,下游报表、CRMS预警、T24记账才能直接关联。

2.3 业务总线模式:为什么不直接让T24和CRMS两两直连

需求说明书原文说“作为一个业务总线将核心系统(T24)、信贷风险管理信息系统(CRMS)串接起来,抽取相关信息,从而完成他们之间的耦合风险控制”。这里的“业务总线”不是一个浮夸词。如果让T24直接调CRMS,或者CRMS直接调T24,每增加一个系统就要改两头的接口;更麻烦的是,额度占用、账务流水、业务单据三份数据对不上时,根本说不清哪边先错。

SCF作为总线后,调用链变成这样:

# 模拟SCF总线发起放款:先占用额度,再通知T24记账 curl -X POST "$CRMS_URL/api/quota/preoccupy" \ -H "Content-Type: application/json" \ -d '{"req_id":"Q20231207001","contract_no":"HT001","amount":1000000}' curl -X POST "$T24_URL/api/disburse" \ -H "Content-Type: application/json" \ -d '{"req_id":"D20231207001","contract_no":"HT001","amount":1000000}'

两个 curl 命令只是为了说明总线对外暴露的入口,生产环境通常会走 MQ 或 ESB 适配器,但顺序很重要:先扣额度,再放款;如果放款失败,SCF 再释放额度。只要这个顺序不乱,额度与账务就不会明显偏离。总线模式的另一个收益是替换成本:未来如果 T24 换成新核心,SCF 只需要改适配器,业务侧接口保持稳定;反之,如果上下游两两直连,核心系统升级会变成全网改造。

要避免的误用是:把“总线”理解成所有业务逻辑都往 SCF 里塞,把 T24 的核算规则、CRMS 的评分卡都搬进来。总线做的是流程编排和数据抽取,不是领域逻辑的搬运工。需求说明书中写“抽取相关信息”,目的就在于此。

3. 落地集成:T24核心账务与CRMS额度预警的接口设计

流程抽象做得再好,也要通过接口落到系统上。银行系统集成讲究契约先行,先定报文、错误码和幂等策略,再写代码,否则联调阶段一定会被字段格式和超时问题拖住。

3.1 接口清单与数据流向

从需求说明书的目标能整理出最核心的五组接口:

接口名称方向触发方式关键字段
客户信息查询/同步SCF -> T24客户建立时客户号、证件号、开户行
放款记账SCF -> T24审批通过后合同号、金额、起息日
还款到账通知T24 -> SCF日终批量/实时账户、金额、原始交易流水
额度预占/释放SCF -> CRMS放款/结清客户号、额度协议号、金额
风险预警推送CRMS -> SCF事件触发预警级别、风险类型、建议动作

数据流向要分清:T24 是账务源头,SCF 要把业务单据翻译成 T24 能处理的记账交易;CRMS 是风险源头,SCF 要在放款动作前拿到额度判断和风险信号,并在动作后把结果回写。比如“还款到账通知”,T24 回传的只是一笔账户流水,SCF 要负责把它匹配到具体融资合同上;匹配不上的,要进异常池,不能直接给客户做结清。

3.2 T24放款与还款接口:字段映射与幂等设计

放款接口最容易踩坑的是“重复入账”。网络超时后重发指令,如果 T24 重复记账,资金就错了。解决办法是在报文中带一个幂等键,服务端用这个键做去重。下面是一份常见放款报文:

{ "req_id": "SCF20231207001", "biz_type": "PREPAYMENT_FIN", "contract_no": "HT20231207001", "customer_id": "C01020304", "currency": "CNY", "amount": "1000000.00", "value_date": "2023-12-07", "purpose": "PREPAYMENT_TO_SUPPLIER", "source_system": "SCF" }

字段说明:req_id 是幂等键,不要用随机 UUID,建议用“业务日期+产品码+流水号”生成,这样排查问题时能直接定位到业务;biz_type 决定 T24 走哪套核算科目,预付款融资和应收账款融资的放款科目不同;amount 用字符串而不是数字,银行金额必须精确到分,JSON 数字类型在 BigDecimal 转换时会引入精度噪音;value_date 是起息日,不传默认系统日会导致跨日账务错位。

光有报文还不够,调用方要有幂等重试逻辑。下面是基于 Redis 的幂等控制伪代码:

import redis cache = redis.Redis(host="scf-cache", port=6379, decode_responses=True) def disburse_with_idempotency(req_id: str, payload: dict) -> dict: # nx=True:只有键不存在时才能写入,实现并发去重 if cache.set(req_id, "RUNNING", nx=True, ex=1800): try: result = t24_client.disburse(payload) cache.set(req_id + ":RESULT", result) return result except Exception: cache.set(req_id + ":RESULT", "ERROR") raise finally: cache.delete(req_id) # 释放运行标记 return cache.get(req_id + ":RESULT") or {"status": "PROCESSING"}

逻辑说明:第一次请求进来时 set nx 返回 True,执行业务;并发重试请求进来时 nx 返回 False,说明该请求正在处理或已有结果,直接返回缓存结果。ex=1800 是锁的过期时间,防止业务方崩溃后锁永久占用。这里的 Redis 可以换成数据库唯一索引,核心是加一个唯一约束;但 Redis 的好处是可以同时缓存结果,避免重试请求在结果写库前打爆业务系统。

3.3 CRMS额度联动:预占、扣减与回滚

额度占用要严格按三步走:预占、实际占用、释放。

  1. 融资审批通过后,SCF 调 CRMS“额度预占接口”,传入客户号、授信协议号、金额,CRMS 返回预占编号。此时额度被冻结,其他渠道不能乱用。
  2. 放款记账成功后,SCF 调“额度实际占用接口”,把预占额度转成已用额度。
  3. 还款结清后,SCF 调“额度释放接口”,把额度归还给客户。

网络异常会让这三步卡住,所以还需要一张补偿表:

异常场景SCF 侧处理CRMS 侧处理
预占成功但放款失败发送释放指令释放预占额度
放款成功但占用通知丢失定时对账任务提供额度占用查询接口
还款成功但释放失败推送异常工单保留人工释放入口

注意,额度占用失败时,放款动作必须终止;如果先放款再预占,同一客户从多个渠道同时申请时,CRMS 额度会被透支。生产中我还会加一个定时任务,每 10 分钟核对 SCF 本地占用量与 CRMS 返回占用量,差异超过一分钱就告警,然后把差异单送到人工岗。这样即使接口异常,也有第二条线兜底。

4. 风控、会计分录与数据层:让SCF平台从“能用”到“可靠”

供应链金融平台只有流程和接口是不行的,还得让业务“敢用”。敢用意味着风控能闭环、账能对上、数据能追溯。这一章把三件事放在一起说,因为它们共用流程引擎产生的事件和数据。

4.1 闭环风控:回款专户、账期提醒与异常预警

供应链金融区别于普通流贷的核心是自偿性:还款来源不再依赖借款人还款意愿,而是销售回款或存货处置款。平台必须让每笔融资对应一条回款路径。具体落地有三个动作:放款时绑定或开立回款专户,T24 的账户流水进入 SCF 后自动匹配融资单;每天跑批扫描到期融资,提前 7 天、3 天产生提醒;对回款金额和应还款金额做差额比对,偏差超过阈值就推送 CRMS 和客户经理。

下面这个 SQL 可以直接用来生成“7天内到期但回款不足”的预警清单:

SELECT f.contract_no, f.customer_no, f.due_date, f.principal_balance, COALESCE(r.total_repay, 0) AS total_repay FROM scf.finance_order f LEFT JOIN ( SELECT contract_no, SUM(actual_repay_amount) AS total_repay FROM scf.repay_record WHERE biz_date = CURRENT_DATE GROUP BY contract_no ) r ON f.contract_no = r.contract_no WHERE f.state = 'DISBURSED' AND f.due_date < CURRENT_DATE + INTERVAL '7 DAY' AND f.principal_balance > COALESCE(r.total_repay, 0);

逻辑说明:left join 保证没有回款记录的单据也能查出来,COALESCE 把 NULL 转换成 0,避免金额比较失效。state 字段必须与第 2 章的状态机一致,如果库里既有“已放款”又有“DISBURSED”,这个 SQL 就会漏数据。due_date 判断的是“剩余期限不足 7 天”,适合日终批处理;贷前阶段则应该用应收账款的账龄分布来预警,不能只看到期日。

4.2 会计引擎:从业务事件到科目映射

需求说明书要求“自动完成各项金融交易的会计核算”,落到设计上就是一个由事件驱动的分录生成器。放款、还款、利息计提、额度释放都是事件,事件名称从流程引擎状态变化中产生,再根据映射表生成借贷分录。

业务事件借方科目贷方科目
预付款融资放款预付款融资—本金企业活期存款
应收账款融资放款应收账款融资—本金企业活期存款
还款(本金)企业活期存款XX融资—本金
还款(利息)企业活期存款利息收入—供应链金融

科目编码要抽象成配置,不要写死在代码里。以下是事件到科目映射的最小实现:

def entry_for(event: str, amount: float): mapping = { "PREPAY_DISBURSE": ("22100101", "20110001"), "RECEIVABLE_DISBURSE": ("22100201", "20110001"), "REPAY_PRINCIPAL": ("20110001", "22100101"), "REPAY_INTEREST": ("20110001", "60110101"), } debit, credit = mapping[event] return {"debit": debit, "credit": credit, "amount": "%.2f" % amount}

说明:这里科目码是示意,实际以银行科目表为准。关键在事件命名和科目映射一一对应,新增融资产品时只需要在 mapping 里补一行。金额用格式化字符串保留两位,避免浮点数尾巴。生产环境建议全程用 Decimal,Python 的 float 做金额加减会出现 0.001 的误差,对账时非常难查。分录生成后,先写 SCF 本地会计流水表,再打包送给 T24 总账,两端都用同一笔业务流水号,日终对账才有依据。

4.3 数据信息管理:把T24、CRMS和本地单据汇成一张可以分析的表

数据管理不能等到报表阶段再做。SCF 运行期就要把 T24 账务、CRMS 额度和本地单据按合同号关联,形成日快照。不要用 SCF 在线库直接做复杂报表,OLTP 表索引和锁机制扛不住统计分析;常见做法是搭一个轻量数据集市,每天跑批生成宽表。

CREATE TABLE dws_scf_finance_daily ( biz_date DATE, contract_no VARCHAR(32), customer_no VARCHAR(32), product_type VARCHAR(32), principal DECIMAL(20,2), quota_used DECIMAL(20,2), risk_level VARCHAR(8), state VARCHAR(16), PRIMARY KEY (biz_date, contract_no) );

这张表是典型的事实表,一行代表一张融资合同在某个业务日的快照。principal 是当日融资余额,quota_used 来自 CRMS 额度实际占用,risk_level 来自 CRMS 预警信号,state 是 SCF 单据状态。主键用 biz_date + contract_no 有两个作用:一是每天跑批可以覆盖插入,二是写分析 SQL 时不会因为多次跑批产生重复记录。金额字段必须 DECIMAL(20,2),不能用 FLOAT,否则累计汇总总会差几分钱。

除了解析报表,这张表还有一个作用:验证 T24 和 CRMS 的数据一致性。比如 principal 为 0 但 quota_used 仍大于 0,说明还款后额度没释放,平台要生成异常单据。

5. 从需求说明书到上线:需求追踪矩阵与接口联调清单

需求说明书是静态文档,但它要驱动的开发、测试、验收是一连串动态行为。我的习惯是先用“需求追踪矩阵”把每条功能目标翻译成可观察的验收用例,再针对T24、CRMS的接口边界做联调模拟。这两件事做好了,需求落地才不会被业务部门的“我感觉不对”推翻。

5.1 需求追踪矩阵:把文档资料变成可验收的用例

比如需求说明书说“替代现行的手工台账”,这句话没法直接测试。要拆成:创建一笔预付款融资单,单据状态可查询,审批日志完整,字段变更留痕。类似地,“自动完成会计核算”要拆成:放款事件发生后 1 分钟内生成借贷分录,且 T24 账户余额与 SCF 流水一致。用表格维护:

需求说明验收步骤判定标准
替代手工台账创建融资单并维护字段状态可查,操作日志完整
与T24对接调放款接口,模拟失败重发T24账户余额与SCF流水一致
风险预警注入不足额回款数据7天内生成预警记录

追踪矩阵的粒度要控制在“每张表一个用例”。流程引擎的每个状态迁移是一个用例,每条接口的每个错误码也是一个用例。这样需求说明书里“功能完整、操作灵活”的表述才会变成几百条可执行的验收项。

5.2 联调技巧:用模拟器注入超时和重复报文

T24和CRMS在联调环境里通常很“稳定”,很难真实触发网络超时或重复报文,但生产事故大多发生在这种场景。我一般会在SCF测试环境前面部署一个WireMock模拟器,用它代理T24/CRMS的接口,专门注入异常。

启动方式很简单:

java -jar wiremock-standalone.jar --port 8089 --global-templating

这个命令会在 8089 端口启动一个独立的模拟服务。然后配置一条“先超时,后成功”的放款响应:

curl -X POST http://localhost:8089/__admin/mappings \ -H "Content-Type: application/json" \ -d '{"request":{"method":"POST","url":"/api/disburse"},"response":{"status":200,"jsonBody":{"resp_code":"TIMEOUT"}}}'

设置完成后,SCF 调用 /api/disburse 会立刻拿到 TIMEOUT,触发幂等重试逻辑;重新配置 stub 返回成功,验证重试后不会重复入账。测试时重点观察 SCF 日志中的 req_id 是否一致,以及 T24 侧有没有过滤掉重复请求。把这两条用例跑通,接口联调才算真的结束。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询