优化提现流程,新增用户确认模式以支持待用户确认的转账,更新相关API和数据库结构以确保数据一致性。同时,调整小程序界面以展示待确认收款信息,提升用户体验。
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user