providers

This commit is contained in:
Eyosiyas
2026-06-06 11:32:14 +03:00
parent 06276764e0
commit b5f64bc9ad
8 changed files with 107 additions and 79 deletions

View File

@@ -3,45 +3,57 @@ 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';
export interface InAppPaymentReceipt extends InAppPaymentReceiptDto {}
export interface InAppPaymentReceipt extends InAppPaymentReceiptDto { }
@Injectable()
export class BookingPaymentService {
constructor(private readonly bookingsRepository: BookingsRepository) {}
constructor(private readonly bookingsRepository: BookingsRepository, private readonly paymentService: PaymentService) { }
async pay(
bookingId: string,
): Promise<{ booking: Booking; receipt: InAppPaymentReceipt }> {
): Promise<{ redirectUrl: string }> {
const booking = await this.requireBooking(bookingId);
assertBookingStatus(booking, ['FULLY_EXECUTED']);
const receipt = this.buildMockReceipt(booking);
// const receipt = this.buildMockReceipt(booking);
const updated = await this.bookingsRepository.update(bookingId, {
status: 'PAID',
paymentStatus: 'PAID',
} as never);
return { booking: updated!, receipt };
}
private buildMockReceipt(booking: Booking): InAppPaymentReceipt {
const timestamp = Date.now();
const isEtb = booking.paymentCurrency === 'ETB';
const prefix = isEtb ? 'TB' : 'CARD';
const provider = isEtb ? 'TELEBIRR' : 'CARD';
// const updated = await this.bookingsRepository.update(bookingId, {
// status: 'PAID',
// paymentStatus: 'PAID',
// } as never);
const resp = await this.paymentService.pay(booking.totalAmount, "ETB", "telebirr", "payment for booking", 'booking', (_) => {
return new Promise((resp, _) => {
resp({
id: booking.id,
type: "booking"
})
});
})
return {
success: true,
provider,
providerRef: `${prefix}-${booking.reference}-${timestamp}`,
amount: booking.totalAmount,
currency: booking.paymentCurrency,
paidAt: new Date().toISOString(),
};
redirectUrl: resp.clientAction.type == "REDIRECT" ? `http://localhost:3001/api/payments/telebirr/${booking.id}` : ""
}
}
// private buildMockReceipt(booking: Booking): InAppPaymentReceipt {
// const timestamp = Date.now();
// const isEtb = booking.paymentCurrency === 'ETB';
// const prefix = isEtb ? 'TB' : 'CARD';
// const provider = isEtb ? 'TELEBIRR' : 'CARD';
// return {
// success: true,
// provider,
// providerRef: `${prefix}-${booking.reference}-${timestamp}`,
// amount: booking.totalAmount,
// currency: booking.paymentCurrency,
// paidAt: new Date().toISOString(),
// };
// }
private async requireBooking(id: string): Promise<Booking> {
const booking = await this.bookingsRepository.findById(id);
if (!booking) throw new NotFoundException(`Booking ${id} not found`);

View File

@@ -28,6 +28,7 @@ import { ContractPricingScheduleBuilder } from '../../contracts/contract-pricing
import { ContractRendererService } from '../../contracts/contract-renderer.service';
import { ContractTemplateResolver } from '../../contracts/contract-template.resolver';
import { ContractViewModelBuilder } from '../../contracts/contract-view-model.builder';
import { PaymentModule } from '../payment/payment.module';
@Module({
imports: [
@@ -40,6 +41,7 @@ import { ContractViewModelBuilder } from '../../contracts/contract-view-model.bu
BookingReviewNote,
BookingContractSignature,
]),
PaymentModule,
FilesModule,
MinioModule,
CompaniesModule,

View File

@@ -2,10 +2,10 @@ import { Controller, Param, ParseUUIDPipe, Post } from '@nestjs/common';
import { ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { BookingPaymentService } from './booking-payment.service';
import { BookingTransitionService } from './booking-transition.service';
import { InAppPaymentReceiptDto } from './dto/pay-booking.dto';
import { Booking } from './entities/booking.entity';
import { BookingNextStep } from './booking-next-step.util';
// import { BookingTransitionService } from './booking-transition.service';
// import { InAppPaymentReceiptDto } from './dto/pay-booking.dto';
// import { Booking } from './entities/booking.entity';
// import { BookingNextStep } from './booking-next-step.util';
@ApiTags('payments')
@ApiBearerAuth()
@@ -13,22 +13,15 @@ import { BookingNextStep } from './booking-next-step.util';
export class PayController {
constructor(
private readonly paymentService: BookingPaymentService,
private readonly transitionService: BookingTransitionService,
) {}
// private readonly transitionService: BookingTransitionService,
) { }
@Post(':id/payment/pay')
@ApiOperation({ summary: 'Complete in-app payment (mock)' })
@ApiOkResponse({ description: 'Enriched booking with ephemeral payment receipt' })
async pay(@Param('id', ParseUUIDPipe) id: string): Promise<
Booking & {
latestChangeRequestNote?: string | null;
contractSummary?: string | null;
nextStep: BookingNextStep | null;
paymentReceipt: InAppPaymentReceiptDto;
}
> {
const { booking, receipt } = await this.paymentService.pay(id);
const abstract = await this.transitionService.enrichBookingResponse(booking);
return { ...abstract, paymentReceipt: receipt };
async pay(@Param('id', ParseUUIDPipe) id: string) {
return await this.paymentService.pay(id);
// const abstract = await this.transitionService.enrichBookingResponse(booking);
// return { ...abstract, paymentReceipt: receipt };
}
}