const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const morgan = require('morgan'); const rateLimit = require('express-rate-limit'); require('dotenv').config(); const paymentRoutes = require('./routes/payment'); const webhookRoutes = require('./routes/webhook'); const app = express(); const PORT = process.env.PORT || 5000; // Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs }); // Middleware app.use(helmet()); app.use(limiter); app.use(morgan('combined')); // CORS configuration const corsOptions = { origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'], credentials: true, optionsSuccessStatus: 200 }; app.use(cors(corsOptions)); // Body parsing middleware app.use('/webhook', express.raw({ type: 'application/json' })); // Raw body for webhooks app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Routes app.use('/api/payment', paymentRoutes); app.use('/webhook', webhookRoutes); // Health check endpoint app.get('/api/health', (req, res) => { res.json({ status: 'OK', timestamp: new Date().toISOString(), environment: process.env.NODE_ENV || 'development' }); }); // Debug endpoint (only in development) app.get('/api/debug/env', (req, res) => { if (process.env.NODE_ENV === 'production') { return res.status(403).json({ error: 'Not available in production' }); } res.json({ NODE_ENV: process.env.NODE_ENV, PORT: process.env.PORT, FRONTEND_URL: process.env.FRONTEND_URL, SKIP_WOOCOMMERCE: process.env.SKIP_WOOCOMMERCE, SKIP_TOKEN_VALIDATION: process.env.SKIP_TOKEN_VALIDATION, PAYPAL_MODE: process.env.PAYPAL_MODE, HAS_PAYPAL_CLIENT_ID: !!process.env.PAYPAL_CLIENT_ID, HAS_PAYPAL_CLIENT_SECRET: !!process.env.PAYPAL_CLIENT_SECRET, HAS_JWT_SECRET: !!process.env.JWT_SECRET, JWT_SECRET_LENGTH: process.env.JWT_SECRET?.length || 0, HAS_WEBHOOK_SECRET: !!process.env.WEBHOOK_SECRET, HAS_WC_URL: !!process.env.WOOCOMMERCE_URL, HAS_WC_CONSUMER_KEY: !!process.env.WOOCOMMERCE_CONSUMER_KEY, HAS_WC_CONSUMER_SECRET: !!process.env.WOOCOMMERCE_CONSUMER_SECRET, ALLOWED_ORIGINS: process.env.ALLOWED_ORIGINS }); }); // Error handling middleware app.use((err, req, res, next) => { console.error('Error:', err); // Don't expose error details in production if (process.env.NODE_ENV === 'production') { res.status(500).json({ error: 'Internal server error', timestamp: new Date().toISOString() }); } else { res.status(500).json({ error: err.message, stack: err.stack, timestamp: new Date().toISOString() }); } }); // 404 handler app.use('*', (req, res) => { res.status(404).json({ error: 'Route not found', path: req.originalUrl, timestamp: new Date().toISOString() }); }); // Start server app.listen(PORT, () => { console.log(`🚀 Server running on port ${PORT}`); console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`); console.log(`💳 PayPal Mode: ${process.env.PAYPAL_MODE || 'sandbox'}`); console.log(`🌐 CORS Origins: ${process.env.ALLOWED_ORIGINS || 'http://localhost:3000'}`); }); module.exports = app;