62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
/**
|
|
* Application Use Case: CreatePaymentUseCase
|
|
*
|
|
* Creates a new payment.
|
|
*/
|
|
|
|
import type { UseCase } from '@core/shared/application/UseCase';
|
|
import { Result } from '@core/shared/domain/Result';
|
|
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
import type { PayerType, Payment, PaymentType } from '../../domain/entities/Payment';
|
|
import { PaymentStatus } from '../../domain/entities/Payment';
|
|
import type { PaymentRepository } from '../../domain/repositories/PaymentRepository';
|
|
|
|
export interface CreatePaymentInput {
|
|
type: PaymentType;
|
|
amount: number;
|
|
payerId: string;
|
|
payerType: PayerType;
|
|
leagueId: string;
|
|
seasonId?: string;
|
|
}
|
|
|
|
export interface CreatePaymentResult {
|
|
payment: Payment;
|
|
}
|
|
|
|
export type CreatePaymentErrorCode = never;
|
|
|
|
export class CreatePaymentUseCase
|
|
implements UseCase<CreatePaymentInput, CreatePaymentResult, CreatePaymentErrorCode>
|
|
{
|
|
constructor(
|
|
private readonly paymentRepository: PaymentRepository,
|
|
) {}
|
|
|
|
async execute(input: CreatePaymentInput): Promise<Result<CreatePaymentResult, ApplicationErrorCode<CreatePaymentErrorCode>>> {
|
|
const { type, amount, payerId, payerType, leagueId, seasonId } = input;
|
|
|
|
// Calculate platform fee (assume 5% for now)
|
|
const platformFee = Math.round(amount * 0.05 * 100) / 100;
|
|
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,
|
|
status: PaymentStatus.PENDING,
|
|
createdAt: new Date(),
|
|
...(seasonId !== undefined ? { seasonId } : {}),
|
|
};
|
|
|
|
const createdPayment = await this.paymentRepository.create(payment);
|
|
|
|
return Result.ok({ payment: createdPayment });
|
|
}
|
|
} |