import { Router, Response } from 'express'; import { store } from '../services/Store'; import { paymentProvider } from '../services/PaymentProvider'; import { keyActivationProvider } from '../services/KeyActivationProvider'; import { encryptionService } from '../utils/encryption'; import { mockAuthMiddleware, requireSteamAuth } from '../middleware/auth'; import { config } from '../config'; import { CreateTransactionDto } from '../models'; const router = Router(); router.post('/', mockAuthMiddleware, async (req, res: Response) => { const { listingId } = req.body as CreateTransactionDto; if (!listingId) { return res.status(400).json({ success: false, error: 'listingId is required', }); } const listing = store.getListingById(listingId); if (!listing) { return res.status(404).json({ success: false, error: 'Listing not found' }); } if (listing.status !== 'ACTIVE') { return res.status(400).json({ success: false, error: 'Listing is not available', }); } if (listing.sellerId === req.userId) { return res.status(400).json({ success: false, error: 'Cannot buy your own listing', }); } const holdResult = await paymentProvider.createHold(listing.price, listing.currency); if (!holdResult.success) { return res.status(400).json({ success: false, error: holdResult.error || 'Payment failed', }); } const transaction = store.createTransaction({ listingId: listing.id, buyerId: req.userId!, sellerId: listing.sellerId, amount: listing.price, currency: listing.currency, escrowStatus: 'HELD', transactionStatus: 'PENDING', holdId: holdResult.holdId, keyDelivered: false, }); store.updateListing(listing.id, { status: 'SOLD' }); res.json({ success: true, data: { transaction: { id: transaction.id, listingId: transaction.listingId, amount: transaction.amount, currency: transaction.currency, escrowStatus: transaction.escrowStatus, transactionStatus: transaction.transactionStatus, }, }, }); }); router.get('/:id', mockAuthMiddleware, (req, res: Response) => { const transaction = store.getTransactionById(req.params.id); if (!transaction) { return res.status(404).json({ success: false, error: 'Transaction not found' }); } if (transaction.buyerId !== req.userId && transaction.sellerId !== req.userId) { return res.status(403).json({ success: false, error: 'Forbidden' }); } res.json({ success: true, data: { transaction }, }); }); router.get('/:id/key', mockAuthMiddleware, (req, res: Response) => { const transaction = store.getTransactionById(req.params.id); if (!transaction) { return res.status(404).json({ success: false, error: 'Transaction not found' }); } if (transaction.buyerId !== req.userId) { return res.status(403).json({ success: false, error: 'Forbidden' }); } if (transaction.escrowStatus !== 'HELD') { return res.status(400).json({ success: false, error: 'Key only available when payment is held in escrow', }); } if (transaction.keyDelivered) { return res.json({ success: true, data: { keyAlreadyDelivered: true, message: 'Key was already delivered in this transaction', }, }); } const listing = store.getListingById(transaction.listingId); if (!listing) { return res.status(404).json({ success: false, error: 'Listing not found' }); } const key = encryptionService.decrypt(listing.keyEncrypted); store.updateTransaction(transaction.id, { keyDelivered: true }); res.json({ success: true, data: { key }, }); }); router.post('/:id/confirm', requireSteamAuth, async (req, res: Response) => { const { status } = req.body; if (!status || !['SUCCESS', 'FAILED'].includes(status)) { return res.status(400).json({ success: false, error: 'status must be SUCCESS or FAILED', }); } const transaction = store.getTransactionById(req.params.id); if (!transaction) { return res.status(404).json({ success: false, error: 'Transaction not found' }); } if (transaction.buyerId !== req.userId) { return res.status(403).json({ success: false, error: 'Forbidden' }); } if (transaction.transactionStatus !== 'PENDING') { return res.status(400).json({ success: false, error: 'Transaction already confirmed or disputed', }); } if (status === 'SUCCESS') { if (transaction.holdId) { await paymentProvider.release(transaction.holdId); } store.updateTransaction(transaction.id, { escrowStatus: 'RELEASED', transactionStatus: 'COMPLETED', confirmedAt: new Date(), }); res.json({ success: true, data: { message: 'Key confirmed. Payment released to seller.', escrowStatus: 'RELEASED', }, }); } else { if (transaction.holdId) { await paymentProvider.refund(transaction.holdId); } store.updateTransaction(transaction.id, { escrowStatus: 'REFUNDED', transactionStatus: 'DISPUTED', confirmedAt: new Date(), }); res.json({ success: true, data: { message: 'Key marked as failed. Payment refunded to buyer.', escrowStatus: 'REFUNDED', transactionStatus: 'DISPUTED', }, }); } }); router.get('/buyer/me', mockAuthMiddleware, (req, res: Response) => { const transactions = store.getTransactionsByBuyer(req.userId!); res.json({ success: true, data: { transactions }, }); }); router.get('/seller/me', mockAuthMiddleware, (req, res: Response) => { const transactions = store.getTransactionsBySeller(req.userId!); res.json({ success: true, data: { transactions }, }); }); export default router;