优化提现流程,新增用户确认模式以支持待用户确认的转账,更新相关API和数据库结构以确保数据一致性。同时,调整小程序界面以展示待确认收款信息,提升用户体验。

This commit is contained in:
乘风
2026-02-06 19:45:24 +08:00
parent 2e65d68e1e
commit 8e67eb5d62
19 changed files with 649 additions and 95 deletions

View File

@@ -1,11 +1,12 @@
/**
* 微信支付 - 商家转账到零钱 结果通知
* 文档: 开发文档/提现功能完整技术文档.md
* 支持processing原批量转账、pending_confirm用户确认模式终态后更新为 success 并增加用户已提现
*/
import { NextRequest, NextResponse } from 'next/server'
import { decryptResource } from '@/lib/wechat-transfer'
import { query } from '@/lib/db'
import { prisma } from '@/lib/prisma'
const cfg = {
apiV3Key: process.env.WECHAT_API_V3_KEY || process.env.WECHAT_MCH_KEY || '',
@@ -34,29 +35,65 @@ export async function POST(request: NextRequest) {
if (!outBillNo) {
return NextResponse.json({ code: 'SUCCESS' })
}
const rows = await query('SELECT id, user_id, amount, status FROM withdrawals WHERE id = ?', [outBillNo]) as any[]
if (rows.length === 0) {
const w = await prisma.withdrawals.findUnique({
where: { id: outBillNo },
select: { id: true, user_id: true, amount: true, status: true },
})
if (!w) {
return NextResponse.json({ code: 'SUCCESS' })
}
const w = rows[0]
if (w.status !== 'processing') {
// 仅处理「处理中」或「待用户确认」的终态回调
if (w.status !== 'processing' && w.status !== 'pending_confirm') {
return NextResponse.json({ code: 'SUCCESS' })
}
const amount = Number(w.amount)
if (state === 'SUCCESS') {
await query(`
UPDATE withdrawals SET status = 'success', processed_at = NOW(), transaction_id = ? WHERE id = ?
`, [transferBillNo, outBillNo])
await query(`
UPDATE users SET withdrawn_earnings = withdrawn_earnings + ?, pending_earnings = GREATEST(0, pending_earnings - ?) WHERE id = ?
`, [w.amount, w.amount, w.user_id])
await prisma.$transaction(async (tx) => {
await tx.withdrawals.update({
where: { id: outBillNo },
data: {
status: 'success',
processed_at: new Date(),
transaction_id: transferBillNo,
},
})
const user = await tx.users.findUnique({
where: { id: w.user_id },
select: { withdrawn_earnings: true, pending_earnings: true },
})
const curWithdrawn = Number(user?.withdrawn_earnings ?? 0)
const curPending = Number(user?.pending_earnings ?? 0)
await tx.users.update({
where: { id: w.user_id },
data: {
withdrawn_earnings: curWithdrawn + amount,
pending_earnings: Math.max(0, curPending - amount),
},
})
})
} else {
await query(`
UPDATE withdrawals SET status = 'failed', processed_at = NOW(), error_message = ? WHERE id = ?
`, [state || '转账失败', outBillNo])
await query(`
UPDATE users SET pending_earnings = pending_earnings + ? WHERE id = ?
`, [w.amount, w.user_id])
await prisma.withdrawals.update({
where: { id: outBillNo },
data: {
status: 'failed',
processed_at: new Date(),
error_message: state || '转账失败',
},
})
const user = await prisma.users.findUnique({
where: { id: w.user_id },
select: { pending_earnings: true },
})
const curPending = Number(user?.pending_earnings ?? 0)
await prisma.users.update({
where: { id: w.user_id },
data: { pending_earnings: curPending + amount },
})
}
return NextResponse.json({ code: 'SUCCESS' })
} catch (e) {
console.error('[WechatTransferNotify]', e)