资金流水接口 /flow/nts/flowList:POST
根据交易单编号查实收和实收拆分表
遍历处理每一笔流水和对应的流水拆分
如果是托管,按照协议编号聚合流水,并对协议编号打上是否解除的标志;
协议编号:flow.protocolCode
如果不是托管,判断是否需要过滤
如果流水状态不是退款,进一步判断
如果流水的付款方不是买卖方,进一步判断
如果是输出到可视化的话,如果流水的收款方是买卖方,不需要过滤,否则需要过滤
根据协议编号合并托管流水
遍历处理协议的每笔流水
如果是输出到可视化,且流水的业务类型是托管-解冻 && 存管方式不是担保支付(金服平台产品)
否则,判断如果流水的业务类型是401托管-入金或者403托管-解除
如果此协议的流水不是解除,直接结束;否则,接着处理入金流水
重新处理这部分入金流水
首先过滤出来退款和托管-解除的流水,从入金流水中删除这两部分
扣除解除流水
先对入金流水排序
流水的状态都是到账,比较到账时间(arrivalTime)
流水的状态都是付款,再比较付款时间(payTime)
双重遍历入金流水和解除流水这两个集合
入金流水大于0的,根据入金流水的资金项和存管方式找到匹配的解除流水
有匹配到的,比较入金金额和解除金额;直到入金金额抵扣到0或者内层的解除流水遍历结束
入金金额 > 解除金额:用解除金额抵扣入金流水,并重新设置入金的每笔流水
入金金额 <= 解除金额:入金的每笔流水设置金额为0,并从解除金额上扣掉这部分金额
不论是哪种情况,都重新设置下入金流水和解除流水的金额
如果入金流水的存管方式不是担保支付(金服平台产品)&& 业务类型不是托管-利息入金
根据交易单编号查询订单表 select * FROM fund_order WHERE business_code = xx AND business_type = 3;
根据 order_id 还会关联查询 fund_order_variable,用于设置如存管银行、存管时间、解冻时间等字段
用请求的资金项参数+应收+实收+实收原始流水+线下存管整合得到最终的输出结构
处理应收
逻辑比较简单:请求的资金项用于过滤,请求什么资金项返回什么资金项 + 对应的字段set上即可
处理实收
线上
过滤掉不在请求参数中的资金项以及NTS线下确认的业务类型
如果有flow_split,按照flow_split粒度输出
设置金额、资金项、存管方式、支付时间、银行编码、业务类型、流水来源等等;
其中,银行编码是根据存管方式与银行编码之间的映射来找的。根据是否是北京取的枚举中的编码还不一致,详见枚举类 DepositoryMethodDetail
线下
请求的资金项用于过滤,请求什么资金项返回什么资金项 + 对应的字段set上即可
businessType字段特殊处理
如果存管方式是4(线下自行支付)8(担保支付(非金服平台产品))9(担保支付(金服平台产品)),businessType 设置为301 NTS线下确认-C2C
存管方式是其他,businessType 设置为302 NTS线下确认-入金
对线上和线下流水汇总,并按照资金项和时间升序的顺序排序输出
存管流水提交 /order/nts/confirm:POST
转换请求参数,如交易单编号 存管金额 存管银行 存管银行名称 存管方式 存管事件 资金项类型等等
可能有两个字段需要特别关注下:fileIds、lockStatus
添加存管
存管3.0的参数校验逻辑
根据交易单编号+资金项查询应收 fund_receive,不存在抛出异常
如果存管方式不属于线下存管,抛出异常
银行存管(线下) 担保支付(非金服平台产品) 政府监管 居间方代管 线下自行支付
构造 fund_order:根据请求参数做相应赋值,如交易单编号 存管金额 资金项 业务类型等等
如果 payStatus=2
且存管方式=线下自行支付,设置order的status=5 已到账
且存管方式不是线下自行支付,设置order的status=3 支付成功
OrderStatus 的枚举:0未定义 1支付中 2支付完成 3支付成功 4支付失败 5已到账
Status 的枚举:0未付款 1付款 2到账 3退款
否则的话,设置order的status=0 0表示undefined
构造 fund_order_variable
设置 businessType = 3 表示nts线下确认
如果存管方式不等于【政府监管或担保支付或居间方线下确认】且有存管银行信息的话,加到 fund_order_variables
如果有存管时间的话,加到 fund_order_variables
如果有监管账户类型的话,加到 fund_order_variables
fund_order、fund_order_customer、fund_order_variable 表数据落库
fund_order表中的 serial_code 的生成逻辑:
com.ke.jiaoyi.funding.order.domain.util.IdSequenceUtils#nextOrderSerialCode
发布事件:fundOrderStatusEventPublisher.publish(fundOrder);
添加新线下确认订单成功后,会返回fund_order表中的serialCode
存管流水删除 /order/nts/delete:POST
根据请求参数中的 serialCode 查询 fund_order
如果订单不等于null且订单的存管方式不等于线下自行支付且订单的状态等于已到账,抛出异常“已解冻不可删除”
如果订单不等于null且订单的 businessType=3,删除
发布事件:fundOrderStatusEventPublisher.publishWithEventType(fundOrder, OrderLifeCycleEventType.NTS_OFFLINE_CONFIRM_DELETE);
线下解冻 /order/nts/offlineConfirmJd:POST
根据请求参数中的 serialCode 查询 fund_order
更新 fund_order 的 status 为已到账状态、更新 updateTime
fund_order_variable 表新增解冻时间的记录:jdTime
发布事件:fundOrderStatusEventPublisher.publish(oldStatus, fundOrder);
获取操作记录 /flow/nts/getOpLogs:POST
获取流水详情 /order/nts/offlineConfirmDetail:POST
根据请求参数中的 serialCode 查询 fund_order
如果查询结果为null直接返回,否则包装返回结果
包装返回结果
设置对应的字段,如资金项、金额、存管方式、状态等等
设置 payStatus
如果 order.status=支付成功或者已到账,设置payStatus=2 到账;
否则的话,设置payStatus=0 未付款
还会根据 order_id 查询 fund_order_variable,设置银行编码、银行名称、存管时间、解冻时间、监管账户等等
流水更新 /order/nts/updateConfirm:POST
根据请求参数中的 serialCode 查询 fund_order
如果存管方式为空或者存管金额为空或者为0或者属于线下存管,不做处理
根据交易单编号+fundType 校验是否存在对应资金项的应收,不存在的话直接抛出异常
如果订单的状态为已到账且锁定状态为已锁定且存管方式不等于线下自行支付,不允许再修改
构造 fund_order 和 fund_order_variable
新增或者删除 fund_order_variable
发布事件:fundOrderStatusEventPublisher.publish(oldFundOrder.getStatus(), fundOrder);
获取解冻列表 /order/nts/getOfflineConfirmList:POST
根据请求参数中的 businessCode、fundType、businessType=3 查询 fund_order
鲁班解锁线下确认订单 /order/nts/unlock:POST