|
|
import { Request, Response } from 'express'; |
|
|
import { AppDataSource } from '../config/database'; |
|
|
import { Agent, AgentStatus } from '../entities/Agent'; |
|
|
import { Subscription, SubscriptionStatus } from '../entities/Subscription'; |
|
|
import { User } from '../entities/User'; |
|
|
import crypto from 'crypto'; |
|
|
|
|
|
const agentRepository = AppDataSource.getRepository(Agent); |
|
|
const subscriptionRepository = AppDataSource.getRepository(Subscription); |
|
|
const userRepository = AppDataSource.getRepository(User); |
|
|
|
|
|
export class SubscriptionController { |
|
|
|
|
|
|
|
|
|
|
|
async createSubscription(req: Request, res: Response) { |
|
|
try { |
|
|
const { agentId } = req.params; |
|
|
const userId = (req as any).user.id; |
|
|
|
|
|
|
|
|
const agent = await agentRepository.findOne({ |
|
|
where: { id: agentId, status: AgentStatus.APPROVED }, |
|
|
}); |
|
|
|
|
|
if (!agent) { |
|
|
return res.status(404).json({ error: 'Agent not found or not approved' }); |
|
|
} |
|
|
|
|
|
|
|
|
const existing = await subscriptionRepository.findOne({ |
|
|
where: { |
|
|
userId, |
|
|
agentId, |
|
|
status: SubscriptionStatus.ACTIVE, |
|
|
}, |
|
|
}); |
|
|
|
|
|
if (existing) { |
|
|
return res.status(400).json({ |
|
|
error: 'You already have an active subscription to this agent', |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
const expiresAt = agent.isSubscription |
|
|
? new Date( |
|
|
Date.now() + (agent.subscriptionDuration || 30) * 24 * 60 * 60 * 1000 |
|
|
) |
|
|
: new Date('2099-12-31'); |
|
|
|
|
|
|
|
|
const subscription = subscriptionRepository.create({ |
|
|
userId, |
|
|
agentId, |
|
|
expiresAt, |
|
|
status: SubscriptionStatus.ACTIVE, |
|
|
isPaymentVerified: false, |
|
|
}); |
|
|
|
|
|
const savedSubscription = await subscriptionRepository.save(subscription); |
|
|
|
|
|
|
|
|
const paymentReference = `sub_${savedSubscription.id}_${Date.now()}`; |
|
|
savedSubscription.paymentReference = paymentReference; |
|
|
await subscriptionRepository.save(savedSubscription); |
|
|
|
|
|
res.status(201).json({ |
|
|
subscription: savedSubscription, |
|
|
payment: { |
|
|
reference: paymentReference, |
|
|
amount: agent.price, |
|
|
currency: 'NGN', |
|
|
}, |
|
|
}); |
|
|
} catch (error) { |
|
|
console.error('Create subscription error:', error); |
|
|
res.status(500).json({ error: 'Failed to create subscription' }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getMySubscriptions(req: Request, res: Response) { |
|
|
try { |
|
|
const userId = (req as any).user.id; |
|
|
const subscriptions = await subscriptionRepository.find({ |
|
|
where: { userId }, |
|
|
relations: ['agent'], |
|
|
order: { createdAt: 'DESC' }, |
|
|
}); |
|
|
|
|
|
res.json(subscriptions); |
|
|
} catch (error) { |
|
|
console.error('Get subscriptions error:', error); |
|
|
res.status(500).json({ error: 'Failed to get subscriptions' }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async cancelSubscription(req: Request, res: Response) { |
|
|
try { |
|
|
const { id } = req.params; |
|
|
const userId = (req as any).user.id; |
|
|
|
|
|
const subscription = await subscriptionRepository.findOne({ |
|
|
where: { id, userId }, |
|
|
}); |
|
|
|
|
|
if (!subscription) { |
|
|
return res.status(404).json({ error: 'Subscription not found' }); |
|
|
} |
|
|
|
|
|
subscription.status = SubscriptionStatus.CANCELLED; |
|
|
await subscriptionRepository.save(subscription); |
|
|
|
|
|
res.json({ message: 'Subscription cancelled', subscription }); |
|
|
} catch (error) { |
|
|
console.error('Cancel subscription error:', error); |
|
|
res.status(500).json({ error: 'Failed to cancel subscription' }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async verifyPayment(req: Request, res: Response) { |
|
|
try { |
|
|
const secret = process.env.PAYSTACK_SECRET; |
|
|
if (!secret) { |
|
|
throw new Error('Paystack secret not configured'); |
|
|
} |
|
|
|
|
|
const hash = crypto |
|
|
.createHmac('sha512', secret) |
|
|
.update(JSON.stringify(req.body)) |
|
|
.digest('hex'); |
|
|
|
|
|
if (hash !== req.headers['x-paystack-signature']) { |
|
|
return res.status(401).json({ error: 'Invalid signature' }); |
|
|
} |
|
|
|
|
|
const event = req.body; |
|
|
|
|
|
if (event.event === 'charge.success') { |
|
|
const { reference, metadata } = event.data; |
|
|
|
|
|
|
|
|
const subscription = await subscriptionRepository.findOne({ |
|
|
where: { paymentReference: reference }, |
|
|
}); |
|
|
|
|
|
if (subscription) { |
|
|
subscription.isPaymentVerified = true; |
|
|
subscription.status = SubscriptionStatus.ACTIVE; |
|
|
await subscriptionRepository.save(subscription); |
|
|
} |
|
|
} |
|
|
|
|
|
res.json({ received: true }); |
|
|
} catch (error) { |
|
|
console.error('Payment verification error:', error); |
|
|
res.status(500).json({ error: 'Payment verification failed' }); |
|
|
} |
|
|
} |
|
|
} |
|
|
|