import { Injectable, NotFoundException } from '@nestjs/common'; import { BookingsRepository } from './bookings.repository'; import { Booking } from './entities/booking.entity'; import { assertBookingStatus } from './booking-status.util'; import { InAppPaymentReceiptDto } from './dto/pay-booking.dto'; import { PaymentService } from '../payment/payment.service'; import { PaymentStatus } from '../payment/entities/payment.entity'; export interface InAppPaymentReceipt extends InAppPaymentReceiptDto { } const NON_TERMINAL_STATUSES: PaymentStatus[] = [ "action-required", "processing", "success", ]; @Injectable() export class BookingPaymentService { constructor( private readonly bookingsRepository: BookingsRepository, private readonly paymentService: PaymentService, ) { } async pay(bookingId: string): Promise<{ redirectUrl: string }> { const booking = await this.requireBooking(bookingId); assertBookingStatus(booking, ['FULLY_EXECUTED', 'AWAITING_PAYMENT', '']); const existing = await this.paymentService.findBookingById(bookingId); if (existing && NON_TERMINAL_STATUSES.includes(existing.status)) { if (existing.clientAction) { const action = existing.clientAction as { type?: string; url?: string }; if (action.type === "REDIRECT" && action.url) { return { redirectUrl: action.url }; } } } const resp = await this.paymentService.initBookingTelebirr(bookingId, "web"); return { redirectUrl: resp.redirectUrl ?? "", }; } private async requireBooking(id: string): Promise { const booking = await this.bookingsRepository.findById(id); if (!booking) throw new NotFoundException(`Booking ${id} not found`); return booking; } }