import { Injectable, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Transaction, TransactionStatus } from './entities/transaction.entity';
import { StripeService } from './stripe.service';
import { PayPalService } from './paypal.service';
import { GooglePayService } from './google-pay.service';
import { GiftCardService } from './gift-card.service';
import { PayoutService } from './payout.service';
import { CreatePaymentIntentDto } from './dto/create-payment-intent.dto';
import { ProcessPaymentDto } from './dto/process-payment.dto';
import { RefundRequestDto } from './dto/refund-request.dto';
import { PayoutRequestDto } from './dto/payout-request.dto';
@Injectable()
export class PaymentsService {
constructor(
@InjectRepository(Transaction) private readonly transactionRepo: Repository<Transaction>,
private readonly stripeService: StripeService,
private readonly paypalService: PayPalService,
private readonly googlePayService: GooglePayService,
private readonly giftCardService: GiftCardService,
private readonly payoutService: PayoutService,
) {}
async createPaymentIntent(dto: CreatePaymentIntentDto & { userId: string }) {
const { userId, items, paymentMethod, currency, giftCardCode } = dto;
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const platformFee = subtotal * 0.05;
let totalAmount = subtotal;
let giftCardDiscount = 0;
if (giftCardCode) {
const giftCard = await this.giftCardService.validateAndRedeem(giftCardCode, userId);
giftCardDiscount = Math.min(giftCard.balance, totalAmount);
totalAmount -= giftCardDiscount;
}
const transaction = this.transactionRepo.create({
userId, items, subtotal, platformFee,
giftCardDiscount, totalAmount,
currency: currency || 'USD', status: TransactionStatus.PENDING, paymentMethod,
});
const saved = await this.transactionRepo.save(transaction);
switch (paymentMethod) {
case 'stripe': return this.stripeService.createCheckoutSession(saved, currency);
case 'paypal': return this.paypalService.createOrder(saved, currency);
case 'google_pay': return this.googlePayService.createPaymentRequest(saved);
case 'credit_card': return this.stripeService.createCardPayment(saved, currency);
default: throw new BadRequestException('Unsupported payment method');
}
}
async processPayment(userId: string, dto: ProcessPaymentDto) {
// Process confirmed payment
return { success: true, transactionId: dto.transactionId };
}
async processRefund(dto: RefundRequestDto) {
const transaction = await this.transactionRepo.findOne({ where: { id: dto.transactionId } });
if (!transaction) throw new BadRequestException('Transaction not found');
transaction.status = TransactionStatus.REFUNDED;
await this.transactionRepo.save(transaction);
return { success: true };
}
async requestPayout(userId: string, dto: PayoutRequestDto) {
return this.payoutService.createPayout(userId, dto.amount, dto.method);
}
async getPaymentMethods(userId: string) {
return [];
}
async handleWebhook(gateway: string, payload: any, headers: any) {
switch (gateway) {
case 'stripe': return this.stripeService.handleWebhook(payload, headers['stripe-signature']);
case 'paypal': return this.paypalService.handleWebhook(payload);
default: throw new BadRequestException('Unknown gateway');
}
}
}