const express = require('express'); const { requireAuth } = require('../middleware/auth'); const { createCheckoutSession, handleWebhookEvent, createPortalSession, getSubscriptionStatus, constructWebhookEvent, } = require('../services/stripeService'); const router = express.Router(); // Checkout — creates Stripe checkout session router.post('/checkout', requireAuth, async (req, res) => { const { tier, founder_code } = req.body; if (!tier || !['analyst', 'desk'].includes(tier)) { return res.status(400).json({ error: 'tier must be "analyst" or "desk"' }); } try { const result = await createCheckoutSession(req.user.id, req.user.email, tier, founder_code); return res.json(result); } catch (err) { console.error('[VYNDR] Checkout error:', err.message); return res.status(503).json({ error: 'Checkout creation failed' }); } }); // Webhook — Stripe sends events here // IMPORTANT: This route needs raw body, not parsed JSON // Must be registered with express.raw() in app.js router.post('/webhook', async (req, res) => { const signature = req.headers['stripe-signature']; if (!signature) { return res.status(400).json({ error: 'Missing stripe-signature header' }); } let event; try { event = constructWebhookEvent(req.body, signature); } catch (err) { console.error('[VYNDR] Webhook signature failed:', err.message); return res.status(400).json({ error: 'Invalid signature' }); } try { await handleWebhookEvent(event); return res.json({ received: true }); } catch (err) { console.error('[VYNDR] Webhook handler error:', err.message); return res.status(500).json({ error: 'Webhook processing failed' }); } }); // Portal — subscription management router.post('/portal', requireAuth, async (req, res) => { if (!req.user.stripe_customer_id) { return res.status(400).json({ error: 'No active subscription' }); } try { const result = await createPortalSession(req.user.stripe_customer_id); return res.json(result); } catch (err) { console.error('[VYNDR] Portal error:', err.message); return res.status(503).json({ error: 'Portal creation failed' }); } }); // Status — current subscription info router.get('/status', requireAuth, async (req, res) => { try { let subStatus = { subscription_status: 'none', current_period_end: null, cancel_at_period_end: false }; if (req.user.stripe_customer_id) { subStatus = await getSubscriptionStatus(req.user.stripe_customer_id); } return res.json({ tier: req.user.tier, is_founder: req.user.founder_status, ...subStatus, }); } catch (err) { console.error('[VYNDR] Status error:', err.message); return res.status(503).json({ error: 'Status check failed' }); } }); module.exports = router;