All files / src/features/donation/services payment.service.ts

100% Statements 23/23
82.6% Branches 19/23
100% Functions 8/8
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78                      15x 15x 15x       2x 2x         4x   4x       4x 4x   4x   4x   4x               2x 2x         1x 1x               2x   2x   2x   2x       2x       1x 1x      
import { Injectable } from '@nestjs/common'
import { IncomingHttpHeaders } from 'http'
import { StripeService } from './stripe.service'
import { PayPalService } from './paypal.service'
import { WhiteLabelingService } from '../../white-labeling/white-labeling.service'
 
import { PaymentConfig } from '../interfaces/payment-provider.interface'
 
@Injectable()
export class PaymentService {
    constructor(
        private readonly stripeService: StripeService,
        private readonly payPalService: PayPalService,
        private readonly whiteLabelingService: WhiteLabelingService,
    ) {}
 
    async getProvider() {
        const { provider } = await this.getPaymentContext()
        return provider
    }
 
    private async getPaymentContext() {
        // 1. Fetch Global Settings (Payment is always global-level)
        const settings = await this.whiteLabelingService.getGlobalSettings()
 
        return this.resolveContext(settings || {})
    }
 
    private resolveContext(settings: any) {
        const providerName = settings?.donation?.payment?.provider || 'stripe'
        const config = settings?.donation?.payment?.config || {}
 
        const providerConfig = (providerName === 'paypal' ? config.paypal : config.stripe) || {}
 
        const providerService = providerName === 'paypal' ? this.payPalService : this.stripeService
 
        return {
            provider: providerService,
            config: providerConfig as PaymentConfig,
            providerName,
        }
    }
 
    async getGlobalCurrency(): Promise<string> {
        const settings = await this.whiteLabelingService.getGlobalSettings()
        return settings.donation?.payment?.currency || 'usd'
    }
 
    // Facade methods
    async createPaymentIntent(amount: number, currency: string, metadata: any) {
        const { provider, config } = await this.getPaymentContext()
        return provider.createPaymentIntent(amount, currency, metadata, config)
    }
 
    async constructEventFromPayload(
        headers: IncomingHttpHeaders | string,
        payload: Buffer,
        providerName?: string,
    ) {
        const settings = await this.whiteLabelingService.getGlobalSettings()
        const resolvedProviderName =
            providerName || settings?.donation?.payment?.provider || 'stripe'
 
        const provider = resolvedProviderName === 'paypal' ? this.payPalService : this.stripeService
        const config =
            (resolvedProviderName === 'paypal'
                ? settings?.donation?.payment?.config?.paypal
                : settings?.donation?.payment?.config?.stripe) || {}
 
        return provider.constructEventFromPayload(headers, payload, config)
    }
 
    async refundDonation(transactionId: string) {
        const { provider, config } = await this.getPaymentContext()
        return provider.refundDonation(transactionId, config)
    }
}