@Service()
export class ProcessCardPaymentService {
@Inject(() => CardsRepo)
private cardsRepo: CardsRepo
@Inject(() => PaymentGatewayService)
private paymentGatewayService: PaymentGatewayService
@Inject(() => EmailService)
private emailService: EmailService
async execute(cardId: CardId, paymentDetails: PaymentDetails) {
// Get data directly from repository - no need for a dedicated service
const card = await this.cardsRepo.getCardById(cardId)
if (!card) {
throw new BadRequestError('cardNotFound')
}
if (card.status === 'paid') {
throw new BadRequestError('cardAlreadyPaid')
}
// Process payment through payment gateway
const paymentResult = await this.paymentGatewayService.processPayment({
amount: card.amount,
currency: card.currency,
...paymentDetails
})
if (paymentResult.status === 'success') {
await this.handleSuccessfulPayment(card, paymentResult, paymentDetails)
return {
success: true,
paymentId: paymentResult.paymentId,
receiptUrl: paymentResult.receiptUrl
}
} else {
throw new BadRequestError('paymentFailed', {
reason: paymentResult.reason
})
}
}
private async handleSuccessfulPayment(card: Card, paymentResult: PaymentResult, paymentDetails: PaymentDetails) {
await this.cardsRepo.updateCard(card._id, {
status: 'paid',
paymentId: paymentResult.paymentId,
paidAt: new Date()
})
await this.emailService.sendEmail({
to: paymentDetails.email,
subject: 'Payment Confirmation',
template: 'payment-confirmation',
data: {
cardName: card.name,
amount: card.amount,
currency: card.currency,
paymentId: paymentResult.paymentId
}
})
}
}