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"] }) type: | "REDIRECT" | "LAUNCH_APP"; @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; } 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; }