Initial commit: Lageplan v1.0 - Next.js 15.5, React 19
This commit is contained in:
70
src/app/api/donate/webhook/route.ts
Normal file
70
src/app/api/donate/webhook/route.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
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 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user