feat(pay): 商家转账场景 1005 打通提现打款
- 转账场景报备信息按佣金报酬要求固定传「岗位类型/报酬说明」两段,否则微信参数校验拒绝 - 处理 WAIT_USER_CONFIRM(用户确认模式):推送「提现待你确认收款」,提示 24 小时内确认 - 提现申请增加单笔上限校验(finance_rules.maxWithdrawAmount,默认 200,对齐微信商家转账额度) - /api/posts 身份优先取服务端会话 token - 文档补充佣金报酬场景与用户确认模式说明(109 套件/722 用例全绿)
这个提交包含在:
@@ -3412,6 +3412,20 @@ app.post('/api/finance/withdrawals/:id/review', async (req: Request, res: Respon
|
||||
return res.json({ code: 20000, data: { ...r, transfer: bill }, message: '提现打款成功,款项已进入大神微信零钱' });
|
||||
}
|
||||
const r = await repo.markWithdrawalTransfer(wdId, billNo, '处理中', state);
|
||||
if (state === 'WAIT_USER_CONFIRM') {
|
||||
pushUserNotification(
|
||||
Number(wd.companion_id) || 0,
|
||||
'WITHDRAW',
|
||||
'提现待你确认收款',
|
||||
`提现金额 ¥${Number(wd.amount || 0).toFixed(2)} 已发起微信转账,请在微信「服务通知」中确认收款(24 小时内有效,逾期自动失效)。`,
|
||||
'/pages/user/withdraw-records'
|
||||
);
|
||||
return res.json({
|
||||
code: 20000,
|
||||
data: { ...r, transfer: bill },
|
||||
message: '已发起微信转账,待收款人在微信「服务通知」中确认收款(24 小时内有效)'
|
||||
});
|
||||
}
|
||||
return res.json({ code: 20000, data: { ...r, transfer: bill }, message: '提现打款已受理(微信处理中),到账以后端最终状态为准' });
|
||||
}
|
||||
|
||||
@@ -3898,6 +3912,18 @@ app.post('/api/users/:id/withdraw', rateLimit({ name: 'withdraw', windowMs: 60 *
|
||||
}
|
||||
await assertUserNotBanned(userId, '申请提现');
|
||||
|
||||
// 单笔上限:受微信商家转账额度约束(商户平台可调),默认 200 元,避免审核时被微信拒绝
|
||||
const financeCfg = await repo.getPlatformConfigByKey('finance_rules');
|
||||
const financeRules = (financeCfg && financeCfg.valueJson) || {};
|
||||
const maxWithdraw = Number(financeRules.maxWithdrawAmount) || 200;
|
||||
const requestAmount = Number(req.body?.amount);
|
||||
if (Number.isFinite(requestAmount) && requestAmount > maxWithdraw) {
|
||||
return res.status(400).json({
|
||||
code: 40000,
|
||||
message: `单笔提现不能超过 ¥${maxWithdraw}(微信商家转账单笔限额),请分多笔提现或联系平台调整额度`
|
||||
});
|
||||
}
|
||||
|
||||
const { amount, channel, account, realName, bankName } = req.body;
|
||||
const result = await repo.withdrawUserCommission(userId, Number(amount), channel, { account, realName, bankName });
|
||||
res.json({
|
||||
@@ -3943,7 +3969,9 @@ app.get('/api/users/:id/finance-records', async (req: Request, res: Response) =>
|
||||
app.get('/api/posts', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const category = req.query.category ? String(req.query.category) : undefined;
|
||||
const userId = Number(req.query.userId || req.headers['x-user-id']) || 1001;
|
||||
// 身份优先取服务端会话,客户端声明仅作匿名浏览时的兼容
|
||||
const tokenUid = resolveRequestUserId(req);
|
||||
const userId = tokenUid || Number(req.query.userId || req.headers['x-user-id']) || 1001;
|
||||
const posts = await repo.getPosts(category, undefined, '正常', userId);
|
||||
res.json({
|
||||
code: 20000,
|
||||
|
||||
在新工单中引用
屏蔽一个用户