// 支付管理路由:/api/payment/*(查询授信额度/发起支付)+ /api/payment-management/*(查询支付记录/详情)。 import express from 'express' import { paymentRecords } from '../db/seedPayment.js' import { balances, walletAccounts } from '../db/seedWallet.js' import { nextId } from '../utils/id.js' import { paginate } from '../utils/pagination.js' import { sendOk, sendFail } from '../utils/response.js' import { requireAuth } from '../middleware/requireAuth.js' const router = express.Router() router.use(requireAuth) function nowStr() { return new Date().toISOString().slice(0, 19).replace('T', ' ') } // ---------------- 查询授信额度(响应结构未文档化,mock 自行假设) ---------------- router.post('/payment/query-credit-quota', (req, res) => { const { accountNo } = req.body || {} if (!accountNo) return sendFail(res, '钱包账号不能为空', 400) // mock 自行假设的响应结构:{accountNo, creditLimit, usedAmount, availableAmount} sendOk(res, { accountNo, creditLimit: '1500000.00', usedAmount: '150000.00', availableAmount: '1350000.00' }) }) // ---------------- 发起支付 ---------------- router.post('/payment/order-pay', (req, res) => { const body = req.body || {} if (!body.walletAccountId) return sendFail(res, '付款钱包账户不能为空', 400) if (!body.paymentMethod) return sendFail(res, '支付方式不能为空', 400) if (!body.payeeInfo?.payeeName || !body.payeeInfo?.payeeAccountNo) return sendFail(res, '收款方信息不能为空', 400) const account = walletAccounts.find((a) => a.id === body.walletAccountId) if (!account) return sendFail(res, '付款钱包账户不存在', 404) const balanceAmount = Number(body.balanceAmount || 0) if (body.paymentMethod === 'BALANCE' || body.paymentMethod === 'COMBINED') { const currentBalance = Number(balances[account.accountNo] || 0) if (balanceAmount > currentBalance) return sendFail(res, '余额支付金额超出可用余额', 400) balances[account.accountNo] = (currentBalance - balanceAmount).toFixed(2) } const id = nextId('paymentRecord') const entity = { id, walletAccountId: body.walletAccountId, loanApplyId: body.loanApplyId, paymentMethod: body.paymentMethod, payeeInfo: body.payeeInfo, totalAmount: body.totalAmount, balanceAmount: body.balanceAmount, financeAmount: body.financeAmount, status: 'PENDING_VERIFICATION', frchainSerialNo: '', paidAt: '', failedReason: '', remark: body.remark || '', detailList: (body.paymentDetailBtoList || []).map((item) => ({ id: nextId('paymentDetail'), fundChannel: item.fundChannel, channelAmount: item.channelAmount, remark: '' })) } paymentRecords.push(entity) // 模拟异步状态流转:待验证 -> 支付成功(3秒后) setTimeout(() => { entity.status = 'SUCCESS' entity.frchainSerialNo = `FR${nowStr().replace(/[-: ]/g, '')}${String(id).padStart(4, '0')}` entity.paidAt = nowStr() }, 3000) sendOk(res, { id }, '支付请求已提交') }) // ---------------- 支付记录查询/详情 ---------------- router.post('/payment-management/query-payment-record', (req, res) => { const { walletAccountIdIs, paymentMethodList, statusList, paidAtStart, paidAtEnd, page, pageSize } = req.body || {} let list = paymentRecords if (walletAccountIdIs) list = list.filter((p) => p.walletAccountId === walletAccountIdIs) if (paymentMethodList?.length) list = list.filter((p) => paymentMethodList.includes(p.paymentMethod)) if (statusList?.length) list = list.filter((p) => statusList.includes(p.status)) if (paidAtStart) list = list.filter((p) => p.paidAt && p.paidAt >= paidAtStart) if (paidAtEnd) list = list.filter((p) => p.paidAt && p.paidAt <= paidAtEnd) list = [...list].sort((a, b) => (a.id < b.id ? 1 : -1)) sendOk(res, paginate(list, page, pageSize)) }) router.post('/payment-management/query-payment-detail', (req, res) => { const { id } = req.body || {} const record = paymentRecords.find((p) => p.id === id) if (!record) return sendFail(res, '支付记录不存在', 404) sendOk(res, record) }) export default router