③ 借款(首借 / 复借)

产品定义:首借(快捷/试算/绑卡/合同)、复借(常规/还款并复借/试算/绑卡/合同)。首借 vs 复借同一套 loanApply/loanCalculate,靠 isFirstLoan 分支。图例与服务名映射见 00-总览
边界:本阶段终点是生成提现申请单(落 bns 本地表 applyStatus=C);建据与打钱见 04-放款。真实分支见下方「分支清单」(读 ApplyBusiness/LoanBusiness/BankBusiness 核实)。

时序

sequenceDiagram
    autonumber
    actor C as 客户
    participant App as 客户端 H5
    participant GW as 业务网关
    participant BNS as BNS 业务编排
    participant FCS as FCS 账务
    participant PFS as PFS 产品
    participant FDS as FDS 反欺诈
    participant IMS as IMS 绑卡
    participant EXT as 外部三方(支付通道)
    participant MISS as 大数据(注释·未接)

    Note over C,MISS: ① 试算(loanCalculate)
    C->>App: 选金额/期限
    App->>GW: POST /bns/apply/loanCalculate
    BNS->>FCS: IFcsNonfinancialClient.loanCalculate(费用/利息/到账/应还)

    Note over C,MISS: ② 绑卡(routeRedirect, bindCardType=API/H5)
    opt 需绑卡
        App->>GW: POST /bns/bank/routeRedirect
        BNS->>IMS: imsServiceClient.routeRedirect(cardType 卡/账户)
        IMS-->>BNS: bindCardType + redirectUrl
        alt bindCardType=H5
            Note over BNS: 落 BnsCardboundOrder(processLink=Plutus, status=pending)
            App->>EXT: 跳转 Plutus/IMS 托管页绑卡
        else bindCardType=API(默认)
            Note over App: 原生直绑(卡走 token, 账户走 Direct Debit+OTP)
        end
        EXT-->>IMS: 通道回调(paystackWebPayCallback 等)
        IMS->>BNS: POST /bns/bindCardCallBack(落卡/账户)
    end

    Note over C,MISS: ③ 提现申请(loanApply→loanApplyDeal)
    C->>App: 确认提交
    App->>GW: POST /bns/apply/loanApply
    BNS->>FDS: queryAccountIsFreeze(冻结校验) ✓
    BNS->>FCS: isFirstLoan 首借/复借判定
    opt 首借且 ischeckCard
        Note over BNS: checkCard:无有效卡→NOT_BANK_CARD,有效期<3月→NOT_THREE_MONTHS_BANK_CARD
    end
    BNS->>PFS: queryProductByProductFeeId(fixProductInfo)
    Note over BNS: checkLoanAmt 产品额度校验
    Note over BNS: Redisson 防重锁(LOAN_APPLY_PREFIX+custId)
    BNS->>FCS: fcsFinancialClient.checkLoanApply 提现校验
    Note over BNS: 账户类型分流 钱包(WALLET)/银行(BANK_ACCOUNT)
    BNS->>MISS: iBigdataClient.applyExclusionRule 大数据互斥
    Note over MISS: ✗ 整段注释禁用(含提额 extraAmount 逻辑), 互斥恒 0
    alt 互斥命中(mutuallyExclusive != -1)
        Note over BNS: 拦截返回(applyStatus=N)
    else 未命中(-1, 注释下恒此路)
        Note over BNS: genApplyLoan 落 BnsApplyMainLoan applyStatus=C
    end
    Note over BNS: sendKafka 通知 agg 算变量 ✗ 已注释

分支清单(穷举借款全部分支)

出处 ApplyBusiness / LoanBusiness / BankBusiness。状态 ✓活跃 / ✗注释 / △外部。

#分支触发条件处理出处状态
1试算-未登录/参数uid 无/参数无效NOT_LOGIN / PARAMETER_ERRApplyBusiness:307/311
2试算合法nonfinancialClient.loanCalculate(FCS):318
3绑卡-取地址需绑卡routeRedirect → IMS 返回 bindCardTypeBankBusiness:221
4绑卡-H5 类型bindCardType=H5落 BnsCardboundOrder(Plutus 托管页, pending)BankBusiness:252
5绑卡-API 类型bindCardType=API(默认)原生直绑BankBusiness:249
6卡 vs 账户cardType银行卡走 token / 银行账户走 Direct Debit+OTProuteRedirect:243
7绑卡回调通道完成bindCardCallBack 落卡/账户IInnerService
8提现-未登录/参数uid 无/参数账户校验NOT_LOGIN / PARAMETER_ERRApplyBusiness:257/263
9冻结校验loanApply 入口queryAccountIsFreeze, freeze→拦截:268
10首借/复借isFirstLoanfirstLoanFlag 分支:280
11首借卡校验ischeckCard && isFirstLoancheckCard:无卡 NOT_BANK_CARD / 有效期<3月 NOT_THREE_MONTHS_BANK_CARD:283、checkCard:329
12查产品fixProductInfo(queryProductByProductFeeId):289
13产品额度校验checkLoanAmt:291
14防重锁loanApplyDealRedisson tryLock(LOAN_APPLY_PREFIX+custId)LoanBusiness:74
15提现校验锁内fcsFinancialClient.checkLoanApply(FCS)LoanBusiness:79
16账户类型分流walletAccountNumber 有/无accountType=WALLET / BANK_ACCOUNTLoanBusiness:113
17大数据互斥applyExclusionRuleiBigdataClient.applyExclusionRule(含提额 extraAmount)LoanBusiness:133✗ 整段注释
18互斥结果分流mutuallyExclusive!= -1 拦截返回(N) / 注释下恒 0→applyStatus=CLoanBusiness:83/142✓(逻辑在, 互斥断)
19生成提现单通过genApplyLoan/saveApplyLoan 落 BnsApplyMainLoan(applyStatus=C)LoanBusiness:146/193
20通知 agg 变量sendKafkaLoanBusiness:87✗ 注释

接口落地

#业务步骤服务真实接口类型现状说明
1提现试算FCSIApplyService.loanCalculateIFcsNonfinancialClient.loanCalculate端点+下游FCS 内部算费用/利息/到账/应还
2取绑卡地址IMSIBankService.routeRedirectIImsServiceClient.routeRedirect端点+下游返回 bindCardType(API/H5) + redirectUrl;H5 类型落 Plutus 订单
3跳转完成绑定IMS 子系统/通道IMS tokenSave/accountInfoBind/accountOtpSend;通道回调 paystackWebPayCallback子系统绑卡实质在 IMS 托管页+通道侧;卡走 token,账户走 Direct Debit+OTP
4绑卡结果回调BNSIInnerService.bindCardCallBack端点IMS 回调 bns,落客户卡/账户
5冻结校验FDSqueryAccountIsFreezeIFdsServiceClient下游loanApply 入口校验
6首借/复借判定FCSIFcsNonfinancialClient.isFirstLoan下游决定首借卡校验等分支
7首借卡校验BNScheckCard(本地查 BnsCustBankInfo)内部无卡/有效期<3月 拦截(仅 BVN 客户)
8查产品/费用PFSIPfsServiceClient.queryProductByProductFeeId下游fixProductInfo
9产品额度校验BNScheckLoanAmt内部校验提现金额在产品额度内
10提现校验FCSIFcsFinancialClient.checkLoanApply下游Redisson 锁内调用
11大数据互斥/排除规则大数据IBigdataClient.applyExclusionRule下游LoanBusiness.applyExclusionRule 整段注释,互斥恒 0
12生成提现申请单BNSgenApplyLoansaveApplyLoan内部BnsApplyMainLoan(applyStatus=C)
13通知 agg 算变量(未发)sendKafka事件注释,借款不触发 agg 变量计算

缺口小结

  • 借款链路本地齐备:试算(FCS)、查产品(PFS)、产品额度校验、首借卡校验、提现校验(FCS)、冻结校验(FDS)、绑卡(IMS+通道)、防重锁、落申请单(bns)均可跑。
  • 绑卡两路 bindCardType=API/H5(13 早期版误标为”卡/账户”):H5 类型跳 Plutus 托管页并落 BnsCardboundOrder;卡/账户是另一维度 cardType(卡走 token,账户走 Direct Debit+OTP)。与前端 03-借款提现 的绑卡跳转一致。
  • 账户类型分流:钱包(WALLET) / 银行账户(BANK_ACCOUNT)——早期版未提。
  • applyStatus N/C 逻辑在但互斥已断:互斥命中应拦截(N),但 applyExclusionRule 整段注释(含提额 extraAmount 逻辑)→ 恒 0 → applyStatus=C。
  • 缺口仍在风控/变量:大数据互斥 applyExclusionRule 注释(不执行)、sendKafka 通知 agg 注释——与授信风控决策缺失一脉相承,指向 大数据/agg/res 未接通。
  • 终点是 bns 提现申请单(applyStatus=C),放款建据见 04-放款