import { Router } from 'express'; import Stripe from 'stripe'; import { authMiddleware } from '../auth.js'; import { query } from '../db.js'; const router = Router(); const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', { apiVersion: '2024-06-20' }); const STRIPE_MIN_HUF = 175; const MIN_DEPOSIT = Math.max(Number(process.env.MIN_DEPOSIT || STRIPE_MIN_HUF), STRIPE_MIN_HUF); const MAX_DEPOSIT = Number(process.env.MAX_DEPOSIT || 1000); function ensureStripeConfigured(res) { if (!process.env.STRIPE_SECRET_KEY) { res.status(500).json({ error: 'Stripe nincs beallitva.' }); return false; } return true; } async function getPromoCode(code) { const rows = await query( 'SELECT id, code, bonus_type, bonus_value, max_uses, expires_at, active FROM promo_codes WHERE code = ? AND active = 1 AND (expires_at IS NULL OR expires_at > NOW())', [code] ); return rows[0]; } function calcBonusAmount(amount, promo) { if (!promo) { return 0; } if (promo.bonus_type === 'percent') { return Math.max(0, Math.floor(amount * Number(promo.bonus_value) / 100)); } if (promo.bonus_type === 'fixed') { return Math.max(0, Number(promo.bonus_value)); } return 0; } router.post('/api/wallet/deposit-intent', authMiddleware, async (req, res) => { try { if (!ensureStripeConfigured(res)) { return; } const rawAmount = req.body.amount; const amount = Math.round(Number(rawAmount)); const stripeAmount = Math.round(amount * 100); if (process.env.NODE_ENV !== 'production') { console.log('Stripe deposit request:', { rawAmount, amount, stripeAmount, min: MIN_DEPOSIT, max: MAX_DEPOSIT }); } if (!Number.isFinite(amount) || amount < MIN_DEPOSIT || amount > MAX_DEPOSIT) { return res.status(400).json({ error: `A feltoltes ${MIN_DEPOSIT} es ${MAX_DEPOSIT} Ft kozott lehet.` }); } const promoInput = req.body.promoCode?.toString().trim().toUpperCase(); let promo = null; let bonusAmount = 0; let promoCodeId = null; if (promoInput) { promo = await getPromoCode(promoInput); if (!promo) { return res.status(400).json({ error: 'Ervenytelen promo kod.' }); } const redeemed = await query( 'SELECT id FROM promo_redemptions WHERE user_id = ? AND promo_code_id = ? LIMIT 1', [req.userId, promo.id] ); if (redeemed.length > 0) { return res.status(400).json({ error: 'A promo kod mar felhasznalva.' }); } if (promo.max_uses) { const usage = await query( 'SELECT COUNT(*) AS count FROM promo_redemptions WHERE promo_code_id = ?', [promo.id] ); if ((usage[0]?.count ?? 0) >= promo.max_uses) { return res.status(400).json({ error: 'A promo kod mar elfogyott.' }); } } bonusAmount = calcBonusAmount(amount, promo); promoCodeId = promo.id; } const paymentIntent = await stripe.paymentIntents.create({ amount: stripeAmount, currency: 'huf', automatic_payment_methods: { enabled: true }, metadata: { userId: String(req.userId) } }); await query( 'INSERT INTO deposits (user_id, amount, bonus_amount, promo_code_id, stripe_payment_intent_id, status) VALUES (?, ?, ?, ?, ?, ?)', [req.userId, amount, bonusAmount, promoCodeId, paymentIntent.id, 'created'] ); return res.json({ clientSecret: paymentIntent.client_secret, paymentIntentId: paymentIntent.id }); } catch (err) { console.error('Stripe fizetes hiba:', err); if (process.env.NODE_ENV !== 'production') { return res.status(500).json({ error: err.message || 'Nem sikerult letrehozni a fizetest.' }); } return res.status(500).json({ error: 'Nem sikerult letrehozni a fizetest.' }); } }); router.post('/api/wallet/confirm', authMiddleware, async (req, res) => { try { if (!ensureStripeConfigured(res)) { return; } const paymentIntentId = req.body.paymentIntentId?.toString(); if (!paymentIntentId) { return res.status(400).json({ error: 'Hianyzo paymentIntentId.' }); } const rows = await query( 'SELECT id, status, amount, bonus_amount, promo_code_id FROM deposits WHERE user_id = ? AND stripe_payment_intent_id = ?', [req.userId, paymentIntentId] ); const deposit = rows[0]; if (!deposit) { return res.status(404).json({ error: 'Ismeretlen befizetes.' }); } const intent = await stripe.paymentIntents.retrieve(paymentIntentId); if (intent.status !== 'succeeded') { return res.json({ status: intent.status }); } if (deposit.status !== 'succeeded') { await query( 'UPDATE deposits SET status = ? WHERE id = ?', ['succeeded', deposit.id] ); const totalCredit = Number(deposit.amount) + Number(deposit.bonus_amount || 0); await query('UPDATE users SET balance = balance + ? WHERE id = ?', [totalCredit, req.userId]); if (deposit.promo_code_id) { const already = await query( 'SELECT id FROM promo_redemptions WHERE user_id = ? AND promo_code_id = ? LIMIT 1', [req.userId, deposit.promo_code_id] ); if (already.length === 0) { await query( 'INSERT INTO promo_redemptions (user_id, promo_code_id, deposit_id) VALUES (?, ?, ?)', [req.userId, deposit.promo_code_id, deposit.id] ); } } } const balanceRows = await query('SELECT balance FROM users WHERE id = ?', [req.userId]); const balance = balanceRows[0]?.balance ?? 0; return res.json({ status: 'succeeded', balance }); } catch (err) { console.error('Stripe confirm hiba:', err); if (process.env.NODE_ENV !== 'production') { return res.status(500).json({ error: err.message || 'Nem sikerult a befizetes ellenorzese.' }); } return res.status(500).json({ error: 'Nem sikerult a befizetes ellenorzese.' }); } }); export default router;