infis on payment and subs
This commit is contained in:
parent
d8ad43a56a
commit
6ea3ece796
2
prisma/migrations/20251114124248_init/migration.sql
Normal file
2
prisma/migrations/20251114124248_init/migration.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "payments" ADD COLUMN "link" TEXT;
|
||||||
2
prisma/migrations/20251114125457_init/migration.sql
Normal file
2
prisma/migrations/20251114125457_init/migration.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "payments" ADD COLUMN "subscriptionId" INTEGER;
|
||||||
2
prisma/migrations/20251114130651_init/migration.sql
Normal file
2
prisma/migrations/20251114130651_init/migration.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "payments" ADD COLUMN "reference" TEXT;
|
||||||
@ -93,6 +93,7 @@ model ReversementRequest {
|
|||||||
model Payment {
|
model Payment {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
externalReference String?
|
externalReference String?
|
||||||
|
reference String?
|
||||||
type PaymentType
|
type PaymentType
|
||||||
status TransactionStatus
|
status TransactionStatus
|
||||||
merchantPartnerId Int
|
merchantPartnerId Int
|
||||||
@ -103,7 +104,9 @@ model Payment {
|
|||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
customerId Int
|
customerId Int
|
||||||
|
subscriptionId Int?
|
||||||
metadata Json?
|
metadata Json?
|
||||||
|
link String?
|
||||||
|
|
||||||
reversementRequests ReversementRequest[]
|
reversementRequests ReversementRequest[]
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { registerAs } from '@nestjs/config';
|
|||||||
export default registerAs('operators', () => ({
|
export default registerAs('operators', () => ({
|
||||||
ORANGE_CIV: {
|
ORANGE_CIV: {
|
||||||
name: 'Orange Côte d Ivoire',
|
name: 'Orange Côte d Ivoire',
|
||||||
baseUrl: process.env.ORANGE_CIV_BASE_URL || 'https://api.bizao.com',
|
baseUrl: process.env.ORANGE_CIV_BASE_URL || 'https://api.DCB-HUB.com',
|
||||||
authType: 'OTP',
|
authType: 'OTP',
|
||||||
endpoints: {
|
endpoints: {
|
||||||
auth: {
|
auth: {
|
||||||
@ -20,7 +20,7 @@ export default registerAs('operators', () => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
headers: {
|
headers: {
|
||||||
'X-OAPI-Application-Id': 'BIZAO',
|
'X-OAPI-Application-Id': 'DCB-HUB',
|
||||||
'X-Orange-MCO': 'OCI',
|
'X-Orange-MCO': 'OCI',
|
||||||
},
|
},
|
||||||
transformers: {
|
transformers: {
|
||||||
@ -30,7 +30,7 @@ export default registerAs('operators', () => ({
|
|||||||
},
|
},
|
||||||
ORANGE_SEN: {
|
ORANGE_SEN: {
|
||||||
name: 'Orange Sénégal',
|
name: 'Orange Sénégal',
|
||||||
baseUrl: process.env.ORANGE_SEN_BASE_URL || 'https://api.bizao.com',
|
baseUrl: process.env.ORANGE_SEN_BASE_URL || 'https://api.DCB-HUB.com',
|
||||||
authType: 'OTP',
|
authType: 'OTP',
|
||||||
endpoints: {
|
endpoints: {
|
||||||
auth: {
|
auth: {
|
||||||
@ -47,7 +47,7 @@ export default registerAs('operators', () => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
headers: {
|
headers: {
|
||||||
'X-OAPI-Application-Id': 'BIZAO',
|
'X-OAPI-Application-Id': 'DCB-HUB',
|
||||||
'X-Orange-MCO': 'OSN',
|
'X-Orange-MCO': 'OSN',
|
||||||
},
|
},
|
||||||
transformers: {
|
transformers: {
|
||||||
|
|||||||
@ -70,5 +70,6 @@ export interface ChargeResponse {
|
|||||||
status: 'SUCCESS' | 'FAILED' | 'PENDING';
|
status: 'SUCCESS' | 'FAILED' | 'PENDING';
|
||||||
operatorReference: string;
|
operatorReference: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
|
resourceURL: string;
|
||||||
currency: string;
|
currency: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ export class OrangeAdapter implements IOperatorAdapter {
|
|||||||
challenge: {
|
challenge: {
|
||||||
method: 'OTP-SMS-AUTH',
|
method: 'OTP-SMS-AUTH',
|
||||||
country: countryCode,
|
country: countryCode,
|
||||||
service: 'BIZAO',
|
service: 'DCB_HUB',
|
||||||
partnerId: 'PDKSUB',
|
partnerId: 'PDKSUB',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@ export class OrangeAdapter implements IOperatorAdapter {
|
|||||||
challenge: {
|
challenge: {
|
||||||
method: 'OTP-SMS-AUTH',
|
method: 'OTP-SMS-AUTH',
|
||||||
country: params.country,
|
country: params.country,
|
||||||
service: 'BIZAO',
|
service: 'DCB_HUB',
|
||||||
partnerId: 'PDKSUB',
|
partnerId: 'PDKSUB',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
@ -178,7 +178,7 @@ export class OrangeAdapter implements IOperatorAdapter {
|
|||||||
chargingMetaData: {
|
chargingMetaData: {
|
||||||
onBehalfOf: 'PaymentHub', //from config todo
|
onBehalfOf: 'PaymentHub', //from config todo
|
||||||
purchaseCategoryCode: 'Service', //todo from config
|
purchaseCategoryCode: 'Service', //todo from config
|
||||||
serviceId: 'BIZAO',
|
serviceId: 'DCB_HUB',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
transactionOperationStatus: 'Charged',
|
transactionOperationStatus: 'Charged',
|
||||||
@ -188,12 +188,17 @@ export class OrangeAdapter implements IOperatorAdapter {
|
|||||||
};
|
};
|
||||||
const token = await this.getAccessToken();
|
const token = await this.getAccessToken();
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`[requesting to ]: ${this.config.baseUrl}/payment/v1/acr%3AOrangeAPIToken/transactions/amount`,
|
`[requesting to ]: ${this.config.baseUrl}/payment/mea/v1/acr%3AX-Orange-ISE2/transactions/amount`,
|
||||||
|
|
||||||
|
);
|
||||||
|
this.logger.debug(
|
||||||
|
`[requesting token ]: ${token} `,
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await firstValueFrom(
|
const response = await firstValueFrom(
|
||||||
this.httpService.post(
|
this.httpService.post(
|
||||||
`${this.config.baseUrl}}/payment/v1/acr%3AOrangeAPIToken/transactions/amount`,
|
`${this.config.baseUrl}/payment/mea/v1/acr%3AX-Orange-ISE2/transactions/amount`,
|
||||||
hubRequest,
|
hubRequest,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@ -238,11 +243,11 @@ export class OrangeAdapter implements IOperatorAdapter {
|
|||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${this.accessToken}`,
|
Authorization: `Bearer ${this.accessToken}`,
|
||||||
'X-OAPI-Application-Id': 'BIZAO',
|
'X-OAPI-Application-Id': 'DCB_HUB',
|
||||||
'X-OAPI-Contact-Id': 'b2b-bizao-97b5878',
|
'X-OAPI-Contact-Id': 'b2b-DCB_HUB-97b5878',
|
||||||
'X-OAPI-Resource-Type': 'SMS_OSM',
|
'X-OAPI-Resource-Type': 'SMS_OSM',
|
||||||
'bizao-alias': params.userAlias,
|
'DCB_HUB-alias': params.userAlias,
|
||||||
'bizao-token': params.userToken,
|
'DCB_HUB-token': params.userToken,
|
||||||
'X-Orange-MCO': this.getMCO(params.country),
|
'X-Orange-MCO': this.getMCO(params.country),
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,29 +2,30 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OrangeTransformer {
|
export class OrangeTransformer {
|
||||||
transformChargeResponse(bizaoResponse: any): any {
|
transformChargeResponse(orangeResponse: any): any {
|
||||||
return {
|
return {
|
||||||
paymentId: bizaoResponse.amountTransaction?.serverReferenceCode,
|
paymentId: orangeResponse.amountTransaction?.serverReferenceCode,
|
||||||
status: this.mapStatus(
|
status: this.mapStatus(
|
||||||
bizaoResponse.amountTransaction?.transactionOperationStatus,
|
orangeResponse.amountTransaction?.transactionOperationStatus,
|
||||||
),
|
),
|
||||||
operatorReference: bizaoResponse.amountTransaction?.serverReferenceCode,
|
operatorReference: orangeResponse.amountTransaction?.serverReferenceCode,
|
||||||
amount: parseFloat(
|
amount: parseFloat(
|
||||||
bizaoResponse.amountTransaction?.paymentAmount?.totalAmountCharged,
|
orangeResponse.amountTransaction?.paymentAmount?.totalAmountCharged,
|
||||||
),
|
),
|
||||||
|
resourceURL: orangeResponse.amountTransaction?.resourceURL,
|
||||||
currency:
|
currency:
|
||||||
bizaoResponse.amountTransaction?.paymentAmount?.chargingInformation
|
orangeResponse.amountTransaction?.paymentAmount?.chargingInformation
|
||||||
?.currency,
|
?.currency,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private mapStatus(bizaoStatus: string): string {
|
private mapStatus(orangeStatus: string): string {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
Charged: 'SUCCESS',
|
Charged: 'SUCCESS',
|
||||||
Failed: 'FAILED',
|
Failed: 'FAILED',
|
||||||
Pending: 'PENDING',
|
Pending: 'PENDING',
|
||||||
};
|
};
|
||||||
return statusMap[bizaoStatus] || 'PENDING';
|
return statusMap[orangeStatus] || 'PENDING';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
Min,
|
Min,
|
||||||
IsEnum,
|
IsEnum,
|
||||||
IsDateString,
|
IsDateString,
|
||||||
|
isNumber,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
@ -35,7 +36,7 @@ export class ChargeDto {
|
|||||||
|
|
||||||
@ApiProperty({ required: false, description: 'Subscription ID if recurring' })
|
@ApiProperty({ required: false, description: 'Subscription ID if recurring' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsNumber()
|
||||||
subscriptionId?: number;
|
subscriptionId?: number;
|
||||||
|
|
||||||
@ApiProperty({ required: false, description: 'Callback URL for notifications' })
|
@ApiProperty({ required: false, description: 'Callback URL for notifications' })
|
||||||
@ -64,7 +65,7 @@ export class RefundDto {
|
|||||||
@ApiProperty({ required: false, description: 'Amount to refund (partial refund)' })
|
@ApiProperty({ required: false, description: 'Amount to refund (partial refund)' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Min(0)
|
@Min(1)
|
||||||
amount?: number;
|
amount?: number;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Reason for refund' })
|
@ApiProperty({ description: 'Reason for refund' })
|
||||||
@ -89,8 +90,8 @@ export class PaymentQueryDto {
|
|||||||
|
|
||||||
@ApiProperty({ required: false })
|
@ApiProperty({ required: false })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsNumber()
|
||||||
subscriptionId?: string;
|
subscriptionId?: number;
|
||||||
|
|
||||||
@ApiProperty({ required: false })
|
@ApiProperty({ required: false })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
|||||||
@ -89,7 +89,7 @@ export class PaymentsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get(':paymentId')
|
@Get(':paymentId')
|
||||||
@UseGuards(JwtAuthGuard)
|
//@UseGuards(JwtAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Get payment details' })
|
@ApiOperation({ summary: 'Get payment details' })
|
||||||
@ApiResponse({
|
@ApiResponse({
|
||||||
@ -98,8 +98,9 @@ export class PaymentsController {
|
|||||||
type: PaymentResponseDto,
|
type: PaymentResponseDto,
|
||||||
})
|
})
|
||||||
@ApiResponse({ status: 404, description: 'Payment not found' })
|
@ApiResponse({ status: 404, description: 'Payment not found' })
|
||||||
async getPayment(@Request() req, @Param('paymentId') paymentId: string) {
|
async getPayment(@Request() req, @Param('paymentId') paymentId: number) {
|
||||||
return this.paymentsService.getPayment(paymentId, req.user.partnerId);
|
console.log('Fetching payment with ID:', paymentId);
|
||||||
|
return this.paymentsService.getPayment(paymentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -118,11 +119,32 @@ export class PaymentsController {
|
|||||||
@Param('reference') reference: string,
|
@Param('reference') reference: string,
|
||||||
) {
|
) {
|
||||||
return this.paymentsService.getPaymentByReference(
|
return this.paymentsService.getPaymentByReference(
|
||||||
reference,
|
reference
|
||||||
req.user.partnerId,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Get('/')
|
||||||
|
@ApiOperation({ summary: 'Get payments list' })
|
||||||
|
async getAll(@Request() req) {
|
||||||
|
return this.paymentsService.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('merchant/:merchantId')
|
||||||
|
@ApiOperation({ summary: 'Get payments list by merchant' })
|
||||||
|
async getAllByPaymentByMerchant(@Request() req, @Param('merchantId', ParseIntPipe) merchantId: number) {
|
||||||
|
return this.paymentsService.findAllByMerchant(merchantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('merchant/:merchantId/subscription/:subscriptionId')
|
||||||
|
@ApiOperation({ summary: 'Get payments list by merchant' })
|
||||||
|
async getAllBySubscription(@Request() req,
|
||||||
|
@Param('merchantId', ParseIntPipe) merchantId: number,
|
||||||
|
@Param('subscriptionId', ParseIntPipe) subscriptionId: number) {
|
||||||
|
return this.paymentsService.findAllByMerchantSubscription(merchantId,subscriptionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Post(':paymentId/retry')
|
@Post(':paymentId/retry')
|
||||||
// @UseGuards(JwtAuthGuard)
|
// @UseGuards(JwtAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
|
|||||||
@ -9,15 +9,64 @@ import { PaymentType, TransactionStatus } from 'generated/prisma';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class PaymentsService {
|
export class PaymentsService {
|
||||||
private readonly logger = new Logger(PaymentsService.name);
|
private readonly logger = new Logger(PaymentsService.name);
|
||||||
handleWebhook(arg0: { partnerId: any; event: any; payload: any; signature: any; }) {
|
handleWebhook(arg0: {
|
||||||
|
partnerId: any;
|
||||||
|
event: any;
|
||||||
|
payload: any;
|
||||||
|
signature: any;
|
||||||
|
}) {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
getPaymentByReference(reference: string, partnerId: any) {
|
async getPaymentByReference(reference: string) {
|
||||||
throw new Error('Method not implemented.');
|
const plan = await this.prisma.payment.findFirst({
|
||||||
|
where: { reference: reference },
|
||||||
|
});
|
||||||
|
return plan
|
||||||
}
|
}
|
||||||
getPayment(paymentId: string, partnerId: any) {
|
async getPayment(id: number) {
|
||||||
throw new Error('Method not implemented.');
|
const data = await this.prisma.payment.findUnique({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async findAllByMerchant(merchantId: number): Promise<any[]> {
|
||||||
|
// Check if merchant exists
|
||||||
|
|
||||||
|
return this.prisma.payment.findMany({
|
||||||
|
where: { merchantPartnerId: merchantId },
|
||||||
|
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAllByMerchantSubscription(merchantId: number, subscriptionId: number): Promise<any[]> {
|
||||||
|
// Check if merchant exists
|
||||||
|
|
||||||
|
return this.prisma.payment.findMany({
|
||||||
|
where: { merchantPartnerId: merchantId, subscriptionId: subscriptionId },
|
||||||
|
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(): Promise<any[]> {
|
||||||
|
// Check if merchant exists
|
||||||
|
return this.prisma.payment.findMany({
|
||||||
|
// where: { merchantPartnerId: merchantId },
|
||||||
|
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
refundPayment(paymentId: string, partnerId: any, refundDto: RefundDto) {
|
refundPayment(paymentId: string, partnerId: any, refundDto: RefundDto) {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
@ -47,13 +96,14 @@ export class PaymentsService {
|
|||||||
|
|
||||||
// Créer la transaction dans la base
|
// Créer la transaction dans la base
|
||||||
const payment = await this.prisma.payment.create({
|
const payment = await this.prisma.payment.create({
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
|
subscriptionId: chargeDto.subscriptionId,
|
||||||
merchantPartnerId: chargeDto.partnerId, // À remplacer par le bon partnerId
|
merchantPartnerId: chargeDto.partnerId, // À remplacer par le bon partnerId
|
||||||
customerId: 1, // todo À remplacer par user.id
|
customerId: 1, // todo À remplacer par user.id
|
||||||
amount: chargeDto.amount,
|
amount: chargeDto.amount,
|
||||||
currency: chargeDto.currency,
|
currency: chargeDto.currency,
|
||||||
type: PaymentType.MM,
|
type: PaymentType.MM,
|
||||||
|
reference: chargeDto.reference || this.generateReference(),
|
||||||
//description: chargeDto.description,
|
//description: chargeDto.description,
|
||||||
//reference: chargeDto.reference || this.generateReference(),
|
//reference: chargeDto.reference || this.generateReference(),
|
||||||
status: TransactionStatus.PENDING,
|
status: TransactionStatus.PENDING,
|
||||||
@ -64,13 +114,16 @@ export class PaymentsService {
|
|||||||
try {
|
try {
|
||||||
// Router vers le bon opérateur
|
// Router vers le bon opérateur
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`[getting adaptator for ]: ${chargeDto.operator}_${chargeDto.country} `)
|
`[getting adaptator for ]: ${chargeDto.operator}_${chargeDto.country} `,
|
||||||
|
);
|
||||||
const adapter = this.operatorsService.getAdapter(
|
const adapter = this.operatorsService.getAdapter(
|
||||||
chargeDto.operator,
|
chargeDto.operator,
|
||||||
chargeDto.country,
|
chargeDto.country,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.debug(`Processing payment ${payment.id} through operator adapter ${adapter.constructor.name}`);
|
this.logger.debug(
|
||||||
|
`Processing payment ${payment.id} through operator adapter ${adapter.constructor.name}`,
|
||||||
|
);
|
||||||
|
|
||||||
const chargeParams = {
|
const chargeParams = {
|
||||||
userToken: chargeDto.userToken,
|
userToken: chargeDto.userToken,
|
||||||
@ -83,9 +136,9 @@ export class PaymentsService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const result = await adapter.charge(chargeParams);
|
const result = await adapter.charge(chargeParams);
|
||||||
this.logger.debug(`result frm adaptaor ${result} for payment ${payment.id}`);
|
this.logger.debug(
|
||||||
|
`result frm adaptaor ${result} for payment ${payment.id}`,
|
||||||
|
);
|
||||||
|
|
||||||
// Mettre à jour le paiement
|
// Mettre à jour le paiement
|
||||||
const updatedPayment = await this.prisma.payment.update({
|
const updatedPayment = await this.prisma.payment.update({
|
||||||
@ -95,7 +148,8 @@ export class PaymentsService {
|
|||||||
result.status === 'SUCCESS'
|
result.status === 'SUCCESS'
|
||||||
? TransactionStatus.SUCCESS
|
? TransactionStatus.SUCCESS
|
||||||
: TransactionStatus.FAILED,
|
: TransactionStatus.FAILED,
|
||||||
//operatorReference: result.operatorReference,
|
externalReference: result.operatorReference,
|
||||||
|
link: result.resourceURL,
|
||||||
completedAt: new Date(),
|
completedAt: new Date(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -113,6 +167,10 @@ export class PaymentsService {
|
|||||||
|
|
||||||
return updatedPayment;
|
return updatedPayment;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
this.logger.debug(
|
||||||
|
`error ${error.message} processing payment ${payment.id}`,
|
||||||
|
);
|
||||||
|
|
||||||
// En cas d'erreur, marquer comme échoué
|
// En cas d'erreur, marquer comme échoué
|
||||||
const resultFinal = await this.prisma.payment.update({
|
const resultFinal = await this.prisma.payment.update({
|
||||||
where: { id: payment.id },
|
where: { id: payment.id },
|
||||||
@ -174,7 +232,6 @@ async listPayments(filters: any) {
|
|||||||
skip,
|
skip,
|
||||||
take: limit,
|
take: limit,
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
|
|
||||||
}),
|
}),
|
||||||
this.prisma.payment.count({ where }),
|
this.prisma.payment.count({ where }),
|
||||||
]);
|
]);
|
||||||
@ -226,9 +283,8 @@ async getStatistics(params: {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const successRate = totalPayments > 0
|
const successRate =
|
||||||
? (successfulPayments / totalPayments) * 100
|
totalPayments > 0 ? (successfulPayments / totalPayments) * 100 : 0;
|
||||||
: 0;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalPayments,
|
totalPayments,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user