import { IsString, IsEnum, IsOptional, IsIn, IsBoolean, IsInt, } from "class-validator"; import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; import { PaymentIntentStatus } from "@prisma/client"; export enum PaymentRegionEnum { ETHIOPIA = "ETHIOPIA", DJIBOUTI = "DJIBOUTI", INTERNATIONAL = "INTERNATIONAL", GLOBAL = "GLOBAL", } export enum PaymentMethodTypeEnum { TELEBIRR = "TELEBIRR", // Ethiopia CBE_BIRR = "CBE_BIRR", // Ethiopia EBIRR = "EBIRR", // Ethiopia WAAFI = "WAAFI", DMONEY= "DMONEY",// Djibouti CARD = "CARD", // International WALLET = "WALLET", // Internal } export type PaymentPlatformDto = "web" | "mobile"; export class InitiatePaymentDto { @ApiProperty({ example: "booking-uuid" }) @IsString() bookingId: string; @ApiProperty({ enum: PaymentMethodTypeEnum, description: "Payment method: TELEBIRR/CBE_BIRR/EBIRR (Ethiopia), WAAFI (Djibouti), CARD (International), WALLET (Internal)", example: "TELEBIRR", }) @IsEnum(PaymentMethodTypeEnum) method: PaymentMethodTypeEnum; @ApiPropertyOptional({ description: "Saved payment method ID (optional)" }) @IsOptional() @IsString() paymentMethodId?: string; @ApiPropertyOptional({ enum: ["web", "mobile"], default: "web", description: "Payment platform (web or mobile)", }) @IsOptional() @IsIn(["web", "mobile"]) platform?: PaymentPlatformDto; } export class RefundDto { @ApiProperty() @IsString() bookingId: string; @ApiPropertyOptional() @IsOptional() @IsString() reason?: string; } export class AddPaymentMethodDto { @ApiProperty({ enum: PaymentMethodTypeEnum }) @IsEnum(PaymentMethodTypeEnum) type: PaymentMethodTypeEnum; @ApiProperty() @IsString() displayName: string; @ApiProperty({ enum: PaymentRegionEnum }) @IsEnum(PaymentRegionEnum) region: PaymentRegionEnum; @ApiPropertyOptional({ example: "ETB" }) @IsOptional() @IsString() currency?: string; @ApiPropertyOptional() @IsOptional() @IsString() providerId?: string; @ApiPropertyOptional({ default: true }) @IsOptional() @IsBoolean() enabled?: boolean; @ApiPropertyOptional({ default: 0 }) @IsOptional() @IsInt() sortOrder?: number; } export class SupportedPaymentMethodDto { @ApiProperty({ enum: PaymentMethodTypeEnum }) type: PaymentMethodTypeEnum; @ApiProperty({ example: "Telebirr" }) displayName: string; @ApiProperty({ enum: PaymentRegionEnum }) region: PaymentRegionEnum; @ApiProperty({ example: "ETB", description: "Settlement currency for this method", }) currency: string; @ApiProperty({ description: "Whether the platform currently accepts this method", }) enabled: boolean; } export class ClientActionDto { @ApiProperty({ enum: ["REDIRECT", "LAUNCH_APP", "COLLECT_OTP"] }) type: "REDIRECT" | "LAUNCH_APP" | "COLLECT_OTP"; @ApiPropertyOptional({ description: "Set when type=REDIRECT (web flow)" }) url?: string; @ApiPropertyOptional({ description: "Set when type=LAUNCH_APP (mobile flow)", }) prepayId?: string; @ApiPropertyOptional({ description: "Set when type=LAUNCH_APP (mobile flow)", }) receiveCode?: string; @ApiPropertyOptional({ description: "Set when type=LAUNCH_APP (mobile flow)", }) shortCode?: string; @ApiPropertyOptional({ description: "Set when type=COLLECT_OTP (e.g. CAC Bank)" }) providerOrderId?: string; @ApiPropertyOptional({ description: "Set when type=COLLECT_OTP" }) message?: string; } export class InitiateResponseDto { @ApiProperty() intentId: string; @ApiProperty({ enum: PaymentIntentStatus }) status: PaymentIntentStatus; @ApiPropertyOptional({ type: ClientActionDto }) clientAction?: ClientActionDto; @ApiPropertyOptional() merchantOrderId?: string; } export class IntentStatusDto { @ApiProperty() intentId: string; @ApiProperty({ enum: PaymentIntentStatus }) status: PaymentIntentStatus; @ApiPropertyOptional({ type: ClientActionDto }) clientAction?: ClientActionDto; @ApiPropertyOptional() merchantOrderId?: string; @ApiPropertyOptional() paidAt?: string; @ApiPropertyOptional() failureCode?: string; @ApiPropertyOptional() failureMessage?: string; } export class BookingAmountResponseDto { @ApiProperty({ example: 'booking-uuid' }) booking_id: string; @ApiProperty({ example: 'DJF', description: 'Currency of the returned amount' }) currency: string; @ApiProperty({ example: 162.5, description: 'Booking total converted to the requested currency (major units)' }) amount: number; } export class ForceConfirmDto { @ApiPropertyOptional({ description: 'External payment reference / transaction ID from the vendor', example: 'TXN-123456' }) @IsOptional() @IsString() paymentReference?: string; @ApiPropertyOptional({ enum: PaymentMethodTypeEnum, description: 'Payment method used externally', example: 'TELEBIRR' }) @IsOptional() @IsEnum(PaymentMethodTypeEnum) paymentMethod?: PaymentMethodTypeEnum; @ApiPropertyOptional({ description: 'Internal notes about why this was force-confirmed', example: 'Vendor confirmed via phone' }) @IsOptional() @IsString() notes?: string; }