/** * 微信支付 - 商家转账到零钱 结果通知 * 文档: 开发文档/提现功能完整技术文档.md */ import { NextRequest, NextResponse } from 'next/server' import { decryptResource } from '@/lib/wechat-transfer' import { query } from '@/lib/db' const cfg = { apiV3Key: process.env.WECHAT_API_V3_KEY || process.env.WECHAT_MCH_KEY || '', } export async function POST(request: NextRequest) { try { const rawBody = await request.text() const data = JSON.parse(rawBody) as { event_type?: string resource?: { ciphertext: string; nonce: string; associated_data: string } } if (data.event_type !== 'MCHTRANSFER.BILL.FINISHED' || !data.resource) { return NextResponse.json({ code: 'SUCCESS' }) } const { ciphertext, nonce, associated_data } = data.resource const decrypted = decryptResource( ciphertext, nonce, associated_data, cfg.apiV3Key ) as { out_bill_no?: string; state?: string; transfer_bill_no?: string } const outBillNo = decrypted.out_bill_no const state = decrypted.state const transferBillNo = decrypted.transfer_bill_no || '' 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) { return NextResponse.json({ code: 'SUCCESS' }) } const w = rows[0] if (w.status !== 'processing') { return NextResponse.json({ code: 'SUCCESS' }) } 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]) } 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]) } return NextResponse.json({ code: 'SUCCESS' }) } catch (e) { console.error('[WechatTransferNotify]', e) return NextResponse.json({ code: 'FAIL', message: '处理失败' }, { status: 500 }) } }