Files
gridpilot.gg/core/payments/application/use-cases/CreatePaymentUseCase.ts
2025-12-16 10:50:15 +01:00

79 lines
2.2 KiB
TypeScript

/**
* Application Use Case: CreatePaymentUseCase
*
* Creates a new payment.
*/
import type { IPaymentRepository } from '../../domain/repositories/IPaymentRepository';
import type { PaymentType, PayerType, PaymentStatus, Payment } from '../../domain/entities/Payment';
import type {
ICreatePaymentPresenter,
CreatePaymentResultDTO,
CreatePaymentViewModel,
} from '../presenters/ICreatePaymentPresenter';
import type { UseCase } from '@gridpilot/shared/application/UseCase';
const PLATFORM_FEE_RATE = 0.10;
export interface CreatePaymentInput {
type: PaymentType;
amount: number;
payerId: string;
payerType: PayerType;
leagueId: string;
seasonId?: string;
}
export class CreatePaymentUseCase
implements UseCase<CreatePaymentInput, CreatePaymentResultDTO, CreatePaymentViewModel, ICreatePaymentPresenter>
{
constructor(private readonly paymentRepository: IPaymentRepository) {}
async execute(
input: CreatePaymentInput,
presenter: ICreatePaymentPresenter,
): Promise<void> {
presenter.reset();
const { type, amount, payerId, payerType, leagueId, seasonId } = input;
const platformFee = amount * PLATFORM_FEE_RATE;
const netAmount = amount - platformFee;
const id = `payment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const payment: Payment = {
id,
type,
amount,
platformFee,
netAmount,
payerId,
payerType,
leagueId,
seasonId,
status: 'pending' as PaymentStatus,
createdAt: new Date(),
};
const createdPayment = await this.paymentRepository.create(payment);
const dto: CreatePaymentResultDTO = {
payment: {
id: createdPayment.id,
type: createdPayment.type,
amount: createdPayment.amount,
platformFee: createdPayment.platformFee,
netAmount: createdPayment.netAmount,
payerId: createdPayment.payerId,
payerType: createdPayment.payerType,
leagueId: createdPayment.leagueId,
seasonId: createdPayment.seasonId,
status: createdPayment.status,
createdAt: createdPayment.createdAt,
completedAt: createdPayment.completedAt,
},
};
presenter.present(dto);
}
}