71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { getStripe, getStripeConfig } from '@/lib/stripe'
|
|
import { prisma } from '@/lib/db'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const stripe = await getStripe()
|
|
const config = await getStripeConfig()
|
|
if (!stripe || !config) {
|
|
return NextResponse.json({ error: 'Stripe not configured' }, { status: 503 })
|
|
}
|
|
|
|
const body = await req.text()
|
|
const sig = req.headers.get('stripe-signature')
|
|
|
|
if (!sig) {
|
|
return NextResponse.json({ error: 'Missing signature' }, { status: 400 })
|
|
}
|
|
|
|
let event
|
|
try {
|
|
if (config.webhookSecret) {
|
|
event = stripe.webhooks.constructEvent(body, sig, config.webhookSecret)
|
|
} else {
|
|
// No webhook secret configured — parse event directly (not recommended for production)
|
|
event = JSON.parse(body)
|
|
}
|
|
} catch (err) {
|
|
console.error('Webhook signature verification failed:', err)
|
|
return NextResponse.json({ error: 'Invalid signature' }, { status: 400 })
|
|
}
|
|
|
|
if (event.type === 'checkout.session.completed') {
|
|
const session = event.data.object
|
|
const metadata = session.metadata || {}
|
|
|
|
if (metadata.type === 'donation') {
|
|
// Store donation record
|
|
try {
|
|
await (prisma as any).systemSetting.create({
|
|
data: {
|
|
key: `donation_${Date.now()}`,
|
|
value: JSON.stringify({
|
|
amount: (session.amount_total || 0) / 100,
|
|
currency: session.currency,
|
|
donor: metadata.donor_name || 'Anonym',
|
|
message: metadata.donor_message || '',
|
|
paymentId: session.payment_intent,
|
|
date: new Date().toISOString(),
|
|
}),
|
|
isSecret: false,
|
|
category: 'donations',
|
|
},
|
|
})
|
|
} catch (e) {
|
|
console.error('Failed to store donation record:', e)
|
|
}
|
|
|
|
console.log(`[Donation] CHF ${(session.amount_total || 0) / 100} from ${metadata.donor_name || 'Anonym'}`)
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({ received: true })
|
|
} catch (error) {
|
|
console.error('Webhook error:', error)
|
|
return NextResponse.json({ error: 'Webhook processing failed' }, { status: 500 })
|
|
}
|
|
}
|