Backend — routes/stripeWebhook.js
// routes/stripeWebhook.js
const express = require("express");
const Stripe = require("stripe");
const router = express.Router();

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: "2024-06-20",
});

router.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.headers["stripe-signature"];
  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
  } catch (err) {
    console.error("Webhook signature verification failed.", err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  (async () => {
    switch (event.type) {
      case "checkout.session.completed": {
        const session = event.data.object;
        const assetIds = (session.metadata?.assetIds || "").split(",").filter(Boolean);
        const userId = session.metadata?.userId || "anon";

        // TODO: mark each assetId as licensed for userId in your DB
        // await grantLicenses(userId, assetIds)

        console.log("✅ Checkout Complete:", { userId, assetIds });
        break;
      }
      case "customer.subscription.created":
      case "customer.subscription.updated":
      case "customer.subscription.deleted": {
        // TODO: sync subscription status to your DB
        // await upsertSubscription(event.data.object)
        console.log(`ℹ️ Subscription event: ${event.type}`);
        break;
      }
      case "payment_intent.succeeded": {
        // Additional safety hook if you want
        break;
      }
      default:
        break;
    }
  })()
    .then(() => res.json({ received: true }))
    .catch((e) => {
      console.error("Webhook handler error", e);
      res.status(500).send("Webhook handler failed");
    });
});

module.exports = router;


In your main server.js:

const checkoutRoutes = require("./routes/checkoutRoutes");
const stripeWebhook = require("./routes/stripeWebhook");

// BEFORE body-parser/json for webhook:
app.use("/api/stripe", stripeWebhook);

// Normal JSON after webhook route:
app.use(express.json());
app.use("/api/checkout", checkoutRoutes);
