Files
edr-platform/apps/edr-freight-api/src/modules/bookings/booking-payment.service.ts

44 lines
1.7 KiB
TypeScript

import { Injectable, NotFoundException } from '@nestjs/common';
import { Freight } from '@edr/types';
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 { BillingService } from '../billing/billing.service';
import { PaymentMethodTypeEnum } from '../payment/payments.dto';
export interface InAppPaymentReceipt extends InAppPaymentReceiptDto { }
@Injectable()
export class BookingPaymentService {
constructor(
private readonly bookingsRepository: BookingsRepository,
private readonly billing: BillingService,
) { }
/**
* Start payment for a booking. The booking never touches the payment gateway
* directly — it charges its invoice through billing, which resolves the amount
* and drives the provider. Returns the provider redirect URL (empty when none).
*/
async pay(bookingId: string): Promise<{ redirectUrl: string }> {
const booking = await this.requireBooking(bookingId);
assertBookingStatus(booking, ['FULLY_EXECUTED', 'SELECTED_FOR_BATCH', 'AWAITING_PAYMENT', '']);
const resp = await this.billing.payInvoice(Freight.InvoiceSource.Booking, bookingId, {
method: PaymentMethodTypeEnum.TELEBIRR,
platform: 'web',
});
const action = resp.clientAction as { type?: string; url?: string } | undefined;
return {
redirectUrl: action?.type === 'REDIRECT' ? (action.url ?? '') : '',
};
}
private async requireBooking(id: string): Promise<Booking> {
const booking = await this.bookingsRepository.findById(id);
if (!booking) throw new NotFoundException(`Booking ${id} not found`);
return booking;
}
}