/** * 微信支付回调通知 API * 基于 Universal_Payment_Module v4.0 设计 * * POST /api/payment/wechat/notify */ import { type NextRequest, NextResponse } from "next/server" import { PaymentFactory, SignatureError } from "@/lib/payment" import { query } from "@/lib/db" // 确保网关已注册 import "@/lib/payment/wechat" export async function POST(request: NextRequest) { try { // 获取XML原始数据 const xmlData = await request.text() console.log("[Wechat Notify] 收到回调:", xmlData.slice(0, 200)) // 创建微信支付网关 const gateway = PaymentFactory.create("wechat_native") try { // 解析并验证回调数据 const notifyResult = gateway.parseNotify(xmlData) if (notifyResult.status === "paid") { console.log("[Wechat Notify] 支付成功:", { tradeSn: notifyResult.tradeSn, platformSn: notifyResult.platformSn, amount: notifyResult.payAmount / 100, // 转换为元 payTime: notifyResult.payTime, }) // === ✅ 1. 更新订单状态 === try { // 通过 transaction_id 查找订单 const orderRows = await query(` SELECT id, user_id, amount, product_type, product_id FROM orders WHERE transaction_id = ? AND status = 'created' LIMIT 1 `, [notifyResult.tradeSn]) as any[] if (orderRows.length === 0) { console.error('[Wechat Notify] ❌ 订单不存在或已处理:', notifyResult.tradeSn) } else { const order = orderRows[0] const orderId = order.id const userId = order.user_id const amount = parseFloat(order.amount) const productType = order.product_type const productId = order.product_id // 更新订单状态为已支付 await query(` UPDATE orders SET status = 'paid', pay_time = ?, updated_at = NOW() WHERE id = ? `, [notifyResult.payTime, orderId]) console.log('[Wechat Notify] ✅ 订单状态已更新:', { orderId, status: 'paid' }) // === ✅ 2. 解锁内容/开通权限 === if (productType === 'fullbook') { // 购买全书 await query('UPDATE users SET has_full_book = 1 WHERE id = ?', [userId]) console.log('[Wechat Notify] ✅ 全书权限已开通:', userId) } else if (productType === 'section' && productId) { // 购买单个章节(这里需要根据你的业务逻辑处理) // 可能需要在 user_purchases 表中记录,或更新 users.purchased_sections console.log('[Wechat Notify] ✅ 章节权限已开通:', { userId, sectionId: productId }) } // === ✅ 3. 分配佣金(如果有推荐人) === try { // 查询用户的推荐人(从 referral_bindings) const userRows = await query(` SELECT u.id, rb.referrer_id, rb.status FROM users u LEFT JOIN referral_bindings rb ON rb.referee_id = u.id AND rb.status = 'active' AND rb.expiry_date > NOW() WHERE u.id = ? LIMIT 1 `, [userId]) as any[] if (userRows.length > 0 && userRows[0].referrer_id) { const referrerId = userRows[0].referrer_id const commissionRate = 0.9 // 90% 佣金比例 const commissionAmount = parseFloat((amount * commissionRate).toFixed(2)) // 更新推荐人的 pending_earnings await query(` UPDATE users SET pending_earnings = pending_earnings + ? WHERE id = ? `, [commissionAmount, referrerId]) // 更新绑定状态为已转化 await query(` UPDATE referral_bindings SET status = 'converted', conversion_date = NOW(), commission_amount = ? WHERE referee_id = ? AND status = 'active' `, [commissionAmount, userId]) console.log('[Wechat Notify] ✅ 佣金已分配:', { referrerId, commissionAmount, orderId }) } else { console.log('[Wechat Notify] ℹ️ 该用户无推荐人,无需分配佣金') } } catch (commErr) { console.error('[Wechat Notify] ❌ 分配佣金失败:', commErr) // 不中断主流程 } } } catch (error) { console.error('[Wechat Notify] ❌ 订单处理失败:', error) // 不中断,继续返回成功响应给微信(避免重复回调) } } else { console.log("[Wechat Notify] 支付失败:", notifyResult) } // 返回成功响应 return new NextResponse(gateway.successResponse(), { headers: { "Content-Type": "application/xml" }, }) } catch (error) { if (error instanceof SignatureError) { console.error("[Wechat Notify] 签名验证失败") return new NextResponse(gateway.failResponse(), { headers: { "Content-Type": "application/xml" }, }) } throw error } } catch (error) { console.error("[Wechat Notify] 处理失败:", error) // 返回失败响应 const failXml = '' return new NextResponse(failXml, { headers: { "Content-Type": "application/xml" }, }) } }