mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
refactor: payment services to nestjs
This commit is contained in:
@@ -15,9 +15,12 @@ import {
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { PaymentServicesApplication } from './PaymentServicesApplication';
|
||||
import { PublicRoute } from '../Auth/Jwt.guard';
|
||||
import { EditPaymentMethodDTO } from './types';
|
||||
|
||||
@ApiTags('PaymentServices')
|
||||
@Controller('payment-services')
|
||||
@PublicRoute()
|
||||
export class PaymentServicesController {
|
||||
constructor(
|
||||
private readonly paymentServicesApp: PaymentServicesApplication,
|
||||
@@ -53,13 +56,10 @@ export class PaymentServicesController {
|
||||
}
|
||||
|
||||
@Post('/:paymentMethodId')
|
||||
@UsePipes(new ValidationPipe({ whitelist: true }))
|
||||
async updatePaymentMethod(
|
||||
@Param('paymentMethodId') paymentMethodId: number,
|
||||
@Body() updatePaymentMethodDTO: any,
|
||||
@Req() req: Request,
|
||||
@Body() updatePaymentMethodDTO: EditPaymentMethodDTO,
|
||||
@Res() res: Response,
|
||||
@Next() next: NextFunction,
|
||||
) {
|
||||
await this.paymentServicesApp.editPaymentMethod(
|
||||
paymentMethodId,
|
||||
|
||||
@@ -6,8 +6,19 @@ import { GetPaymentServicesSpecificInvoice } from './queries/GetPaymentServicesS
|
||||
import { GetPaymentMethodsStateService } from './queries/GetPaymentMethodsState';
|
||||
import { PaymentServicesApplication } from './PaymentServicesApplication';
|
||||
import { PaymentServicesController } from './PaymentServices.controller';
|
||||
import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module';
|
||||
import { PaymentIntegration } from './models/PaymentIntegration.model';
|
||||
import { TransactionPaymentServiceEntry } from './models/TransactionPaymentServiceEntry.model';
|
||||
import { StripePaymentModule } from '../StripePayment/StripePayment.module';
|
||||
|
||||
const models = [
|
||||
RegisterTenancyModel(PaymentIntegration),
|
||||
RegisterTenancyModel(TransactionPaymentServiceEntry),
|
||||
];
|
||||
|
||||
@Module({
|
||||
imports: [...models, StripePaymentModule],
|
||||
exports: [...models],
|
||||
providers: [
|
||||
DeletePaymentMethodService,
|
||||
EditPaymentMethodService,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { GetPaymentServicesSpecificInvoice } from './queries/GetPaymentServicesSpecificInvoice';
|
||||
import { DeletePaymentMethodService } from './commands/DeletePaymentMethodService';
|
||||
import { EditPaymentMethodService } from './commands/EditPaymentMethodService';
|
||||
import { EditPaymentMethodDTO, GetPaymentMethodsPOJO } from './types';
|
||||
import { GetPaymentMethodsStateService } from './queries/GetPaymentMethodsState';
|
||||
import { GetPaymentMethodService } from './queries/GetPaymentService';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Service()
|
||||
@Injectable()
|
||||
export class PaymentServicesApplication {
|
||||
constructor(
|
||||
private readonly getPaymentServicesSpecificInvoice: GetPaymentServicesSpecificInvoice,
|
||||
@@ -22,9 +22,7 @@ export class PaymentServicesApplication {
|
||||
* @returns {Promise<any>} The payment services for the specified invoice.
|
||||
*/
|
||||
public async getPaymentServicesForInvoice(): Promise<any> {
|
||||
return this.getPaymentServicesSpecificInvoice.getPaymentServicesInvoice(
|
||||
tenantId,
|
||||
);
|
||||
return this.getPaymentServicesSpecificInvoice.getPaymentServicesInvoice();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +35,7 @@ export class PaymentServicesApplication {
|
||||
|
||||
/**
|
||||
* Deletes the given payment method.
|
||||
* @param {number} paymentIntegrationId
|
||||
* @param {number} paymentIntegrationId - Payment integration id.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async deletePaymentMethod(
|
||||
@@ -50,8 +48,8 @@ export class PaymentServicesApplication {
|
||||
|
||||
/**
|
||||
* Edits the given payment method.
|
||||
* @param {number} paymentIntegrationId
|
||||
* @param {EditPaymentMethodDTO} editPaymentMethodDTO
|
||||
* @param {number} paymentIntegrationId - Payment integration id.
|
||||
* @param {EditPaymentMethodDTO} editPaymentMethodDTO - Edit payment method DTO.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async editPaymentMethod(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import { EditPaymentMethodDTO } from '../types';
|
||||
import { TransactionPaymentServiceEntry } from '../models/TransactionPaymentServiceEntry.model';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
import { PaymentIntegration } from '../models/PaymentIntegration.model';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
@@ -18,11 +17,6 @@ export class EditPaymentMethodService {
|
||||
private readonly paymentIntegrationModel: TenantModelProxy<
|
||||
typeof PaymentIntegration
|
||||
>,
|
||||
|
||||
@Inject(TransactionPaymentServiceEntry.name)
|
||||
private readonly transactionPaymentServiceEntryModel: TenantModelProxy<
|
||||
typeof TransactionPaymentServiceEntry
|
||||
>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { BaseModel } from "@/models/Model";
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
export class PaymentIntegration extends BaseModel {
|
||||
readonly name!: string;
|
||||
readonly service!: string;
|
||||
readonly paymentEnabled!: boolean;
|
||||
readonly payoutEnabled!: boolean;
|
||||
readonly accountId!: string;
|
||||
readonly options!: Record<string, any>;
|
||||
|
||||
static get tableName() {
|
||||
return 'payment_integrations';
|
||||
@@ -27,7 +29,7 @@ export class PaymentIntegration extends BaseModel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { GetPaymentMethodsPOJO } from '../types';
|
||||
import { isStripePaymentConfigured } from '../utils';
|
||||
import { GetStripeAuthorizationLinkService } from '../../StripePayment/GetStripeAuthorizationLink';
|
||||
import { PaymentIntegration } from '../models/PaymentIntegration.model';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
@@ -23,8 +22,7 @@ export class GetPaymentMethodsStateService {
|
||||
* @param {number} tenantId
|
||||
* @returns {Promise<GetPaymentMethodsPOJO>}
|
||||
*/
|
||||
public async getPaymentMethodsState(
|
||||
): Promise<GetPaymentMethodsPOJO> {
|
||||
public async getPaymentMethodsState(): Promise<GetPaymentMethodsPOJO> {
|
||||
const stripePayment = await this.paymentIntegrationModel()
|
||||
.query()
|
||||
.orderBy('createdAt', 'ASC')
|
||||
@@ -43,7 +41,7 @@ export class GetPaymentMethodsStateService {
|
||||
);
|
||||
const stripeCurrencies = ['USD', 'EUR'];
|
||||
const stripeRedirectUrl = 'https://your-stripe-redirect-url.com';
|
||||
const isStripeServerConfigured = isStripePaymentConfigured();
|
||||
const isStripeServerConfigured = this.isStripePaymentConfigured();
|
||||
const stripeAuthLink =
|
||||
this.getStripeAuthorizationLinkService.getStripeAuthLink();
|
||||
|
||||
@@ -64,4 +62,16 @@ export class GetPaymentMethodsStateService {
|
||||
};
|
||||
return paymentMethodPOJO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if Stripe payment is configured.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isStripePaymentConfigured() {
|
||||
return (
|
||||
this.configService.get('stripePayment.secretKey') &&
|
||||
this.configService.get('stripePayment.publishableKey') &&
|
||||
this.configService.get('stripePayment.webhooksSecret')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
import { GetPaymentMethodsPOJO } from '../types';
|
||||
import { PaymentIntegration } from '../models/PaymentIntegration.model';
|
||||
import { ModelObject } from 'objection';
|
||||
|
||||
@Injectable()
|
||||
export class GetPaymentMethodService {
|
||||
@@ -18,7 +19,7 @@ export class GetPaymentMethodService {
|
||||
*/
|
||||
public async getPaymentMethod(
|
||||
paymentServiceId: number,
|
||||
): Promise<GetPaymentMethodsPOJO> {
|
||||
): Promise<ModelObject<PaymentIntegration>> {
|
||||
const stripePayment = await this.paymentIntegrationModel()
|
||||
.query()
|
||||
.findById(paymentServiceId)
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||
import { GetPaymentServicesSpecificInvoiceTransformer } from './GetPaymentServicesSpecificInvoiceTransformer';
|
||||
import { PaymentIntegration } from '../models/PaymentIntegration.model';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Service()
|
||||
@Injectable()
|
||||
export class GetPaymentServicesSpecificInvoice {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
constructor(
|
||||
private readonly transform: TransformerInjectable,
|
||||
|
||||
@Inject()
|
||||
private transform: TransformerInjectable;
|
||||
@Inject(PaymentIntegration.name)
|
||||
private readonly paymentIntegrationModel: TenantModelProxy<
|
||||
typeof PaymentIntegration
|
||||
>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieves the payment services of the given invoice.
|
||||
* @param {number} tenantId
|
||||
* @param {number} invoiceId
|
||||
* @returns
|
||||
*/
|
||||
async getPaymentServicesInvoice(tenantId: number) {
|
||||
const { PaymentIntegration } = this.tenancy.models(tenantId);
|
||||
|
||||
const paymentGateways = await PaymentIntegration.query()
|
||||
async getPaymentServicesInvoice() {
|
||||
const paymentGateways = await this.paymentIntegrationModel()
|
||||
.query()
|
||||
.modify('fullEnabled')
|
||||
.orderBy('name', 'ASC');
|
||||
|
||||
return this.transform.transform(
|
||||
tenantId,
|
||||
paymentGateways,
|
||||
new GetPaymentServicesSpecificInvoiceTransformer()
|
||||
new GetPaymentServicesSpecificInvoiceTransformer(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,64 @@
|
||||
export interface EditPaymentMethodDTO {
|
||||
name?: string;
|
||||
options?: {
|
||||
bankAccountId?: number; // bank account.
|
||||
clearningAccountId?: number; // current liability.
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from 'class-validator';
|
||||
|
||||
showVisa?: boolean;
|
||||
showMasterCard?: boolean;
|
||||
showDiscover?: boolean;
|
||||
showAmer?: boolean;
|
||||
showJcb?: boolean;
|
||||
showDiners?: boolean;
|
||||
};
|
||||
class EditPaymentMethodOptionsDto {
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
bankAccountId?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
clearningAccountId?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showVisa?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showMasterCard?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showDiscover?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showAmer?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showJcb?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showDiners?: boolean;
|
||||
}
|
||||
|
||||
export class EditPaymentMethodDTO {
|
||||
@IsOptional()
|
||||
@ValidateNested()
|
||||
@Type(() => EditPaymentMethodOptionsDto)
|
||||
@ApiPropertyOptional({
|
||||
type: () => EditPaymentMethodOptionsDto,
|
||||
description: 'Edit payment method options',
|
||||
})
|
||||
options?: EditPaymentMethodOptionsDto;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiPropertyOptional({
|
||||
type: String,
|
||||
description: 'Payment method name',
|
||||
})
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface GetPaymentMethodsPOJO {
|
||||
@@ -22,7 +70,7 @@ export interface GetPaymentMethodsPOJO {
|
||||
isStripeEnabled: boolean;
|
||||
|
||||
isStripeServerConfigured: boolean;
|
||||
|
||||
|
||||
stripeAccountId: string | null;
|
||||
stripePaymentMethodId: number | null;
|
||||
stripePublishableKey: string | null;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import config from '@/config';
|
||||
|
||||
export const isStripePaymentConfigured = () => {
|
||||
return (
|
||||
config.stripePayment.secretKey &&
|
||||
config.stripePayment.publishableKey &&
|
||||
config.stripePayment.webhooksSecret
|
||||
);
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ const models = [InjectSystemModel(PaymentIntegration)];
|
||||
StripeWebhooksSubscriber,
|
||||
TenancyContext,
|
||||
],
|
||||
exports: [StripePaymentService],
|
||||
exports: [StripePaymentService, GetStripeAuthorizationLinkService],
|
||||
controllers: [StripeIntegrationController],
|
||||
})
|
||||
export class StripePaymentModule {}
|
||||
|
||||
Reference in New Issue
Block a user