更新.gitignore以排除部署配置文件,删除不再使用的一键部署脚本,优化小程序部署流程,增强文档说明。
This commit is contained in:
65
app/api/payment/wechat/transfer/notify/route.ts
Normal file
65
app/api/payment/wechat/transfer/notify/route.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 微信支付 - 商家转账到零钱 结果通知
|
||||
* 文档: 开发文档/提现功能完整技术文档.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 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user