import { NextRequest, NextResponse } from "next/server"; import Stripe from "stripe"; import nodemailer from "nodemailer"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); const mailer = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, auth: { user: process.env.SMTP_USER, // nolankovacs@verimundsolutions.com Gmail address pass: process.env.SMTP_PASS, // Gmail App Password }, }); // Tier → expiry days (null = lifetime) const TIER_EXPIRY: Record = { Weekly: 7, Monthly: 30, Annual: 365, Lifetime: null, }; async function generateLicense(tier: string, email: string): Promise { const res = await fetch(`${process.env.API_URL}/admin/generate-license`, { method: "POST", headers: { "Content-Type": "application/json", "X-Admin-Key": process.env.ADMIN_KEY!, }, body: JSON.stringify({ tier: tier.toLowerCase(), email, days_valid: TIER_EXPIRY[tier], channel: "stable", source: "stripe", }), }); if (!res.ok) throw new Error(`License generation failed: ${res.status}`); const data = await res.json(); return data.license_key; } async function sendLicenseEmail(email: string, tier: string, licenseKey: string) { const expiryText = TIER_EXPIRY[tier] === null ? "Your license never expires." : `Your license is valid for ${TIER_EXPIRY[tier]} days from today.`; await mailer.sendMail({ from: `"Verimund Solutions" `, to: email, subject: `Your UIT ${tier} License Key`, html: `

Verimund Solutions

Your license key is ready.

Thank you for purchasing UIT ${tier}. ${expiryText}

License Key

${licenseKey}

To activate, open UIT and enter this key when prompted. The license will bind to your machine on first use.

If you need to transfer your license to a new machine, contact us at support@verimundsolutions.com.


© ${new Date().getFullYear()} Verimund Solutions. This email was sent to ${email} because you purchased a UIT license.

`, }); } export async function POST(req: NextRequest) { const body = await req.text(); const sig = req.headers.get("stripe-signature")!; let event: Stripe.Event; try { event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!); } catch { return NextResponse.json({ error: "Invalid signature" }, { status: 400 }); } if (event.type === "checkout.session.completed") { const session = event.data.object as Stripe.Checkout.Session; const email = session.customer_details?.email; const tier = session.metadata?.tier; if (!email || !tier) { console.error("[WEBHOOK] Missing email or tier", { email, tier }); return NextResponse.json({ error: "Missing data" }, { status: 400 }); } try { const licenseKey = await generateLicense(tier, email); await sendLicenseEmail(email, tier, licenseKey); console.log(`[WEBHOOK] License issued: ${tier} → ${email}`); } catch (err) { console.error("[WEBHOOK] Failed to issue license:", err); // Return 200 so Stripe doesn't retry — log the failure for manual follow-up // TODO: add to a failed_deliveries table for retry } } return NextResponse.json({ received: true }); }