feat: send request via gateway

This commit is contained in:
Abdalhamid Alhamad
2025-07-06 16:44:23 +03:00
parent d3057beb54
commit 492e538eb8
3 changed files with 19 additions and 29 deletions

View File

@ -7,8 +7,9 @@ import { CardTransactionWebhookRequest } from '../dtos/requests';
@ApiTags('Neoleap Webhooks')
export class NeoLeapWebhooksController {
constructor(private readonly transactionService: TransactionService) {}
@Post('account-transaction')
async handleAccountTransactionWebhook(@Body() body: CardTransactionWebhookRequest) {
await this.transactionService.createCardTransaction(body);
@Post('card-transaction')
async handleCardTransactionWebhook(@Body() body: CardTransactionWebhookRequest) {
return this.transactionService.createCardTransaction(body);
}
}

View File

@ -30,7 +30,7 @@ export class NeoTestController {
@ApiDataResponse(CreateApplicationResponse)
async createApplication() {
const customer = await this.customerService.findCustomerById(
this.configService.get<string>('MOCK_CUSTOMER_ID', '0778c431-f604-4b91-af53-49c33849b5ff'),
this.configService.get<string>('MOCK_CUSTOMER_ID', 'ff462af1-1e0c-4216-8865-738e5b525ac1'),
);
const data = await this.neoleapService.createApplication(customer as Customer);
await this.cardService.createCard(customer.id, data);

View File

@ -2,10 +2,7 @@ import { HttpService } from '@nestjs/axios';
import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ClassConstructor, plainToInstance } from 'class-transformer';
import { readFileSync } from 'fs';
import { Agent } from 'https';
import moment from 'moment';
import path from 'path';
import { v4 as uuid } from 'uuid';
import { CountriesNumericISO } from '~/common/constants';
import { Customer } from '~/customer/entities';
@ -17,22 +14,22 @@ import { ICreateApplicationRequest, IInquireApplicationRequest, INeoleapHeaderRe
export class NeoLeapService {
private readonly baseUrl: string;
private readonly apiKey: string;
private readonly useMock: boolean;
private readonly useGateway: boolean;
private readonly institutionCode = '1100';
useLocalCert: boolean;
constructor(private readonly httpService: HttpService, private readonly configService: ConfigService) {
this.baseUrl = this.configService.getOrThrow<string>('NEOLEAP_BASE_URL');
this.apiKey = this.configService.getOrThrow<string>('NEOLEAP_API_KEY');
this.useMock = [true, 'true'].includes(this.configService.get<boolean>('USE_MOCK', false));
this.baseUrl = this.configService.getOrThrow<string>('GATEWAY_URL');
this.apiKey = this.configService.getOrThrow<string>('GATEWAY_API_KEY');
this.useGateway = [true, 'true'].includes(this.configService.get<boolean>('USE_GATEWAY', false));
this.useLocalCert = this.configService.get<boolean>('USE_LOCAL_CERT', false);
}
async createApplication(customer: Customer) {
const responseKey = 'CreateNewApplicationResponseDetails';
if (customer.cards.length > 0) {
throw new BadRequestException('CUSTOMER.ALREADY_HAS_CARD');
}
if (this.useMock) {
// if (customer.cards.length > 0) {
// throw new BadRequestException('CUSTOMER.ALREADY_HAS_CARD');
// }
if (!this.useGateway) {
return plainToInstance(CreateApplicationResponse, CREATE_APPLICATION_MOCK[responseKey], {
excludeExtraneousValues: true,
});
@ -42,7 +39,7 @@ export class NeoLeapService {
CreateNewApplicationRequestDetails: {
ApplicationRequestDetails: {
InstitutionCode: this.institutionCode,
ExternalApplicationNumber: (customer.waitingNumber * 64).toString(),
ExternalApplicationNumber: customer.waitingNumber.toString(),
ApplicationType: '01',
Product: '1101',
ApplicationDate: moment().format('YYYY-MM-DD'),
@ -105,7 +102,7 @@ export class NeoLeapService {
async inquireApplication(externalApplicationNumber: string) {
const responseKey = 'InquireApplicationResponseDetails';
if (this.useMock) {
if (!this.useGateway) {
return plainToInstance(InquireApplicationResponse, INQUIRE_APPLICATION_MOCK[responseKey], {
excludeExtraneousValues: true,
});
@ -152,29 +149,21 @@ export class NeoLeapService {
responseClass: ClassConstructor<R>,
): Promise<R> {
try {
const response = await this.httpService.axiosRef.post(`${this.baseUrl}/${endpoint}`, payload, {
const { data } = await this.httpService.axiosRef.post(`${this.baseUrl}/${endpoint}`, payload, {
headers: {
'Content-Type': 'application/json',
Authorization: `${this.apiKey}`,
Host: 'apigw-uat.neoleap.com.sa',
},
httpsAgent: new Agent({
rejectUnauthorized: false, // Disable SSL verification for development purposes
ca: this.useLocalCert ? readFileSync(path.join(__dirname, '../zod-certs/My_CA_Bundle.ca-bundle')) : undefined,
cert: this.useLocalCert
? readFileSync(path.join(__dirname, '../zod-certs/gw-dev_zodwallet_com.crt'))
: undefined,
key: this.useLocalCert ? readFileSync(path.join(__dirname, '../zod-certs/server.key')) : undefined,
}),
});
if (response.data?.ResponseHeader.ResponseCode !== '000' || !response.data[responseKey]) {
if (data.data?.ResponseHeader?.ResponseCode !== '000' || !data.data[responseKey]) {
throw new BadRequestException(
response.data.ResponseHeader.ResponseDescription || 'Unexpected Error from Service Provider',
data.data.ResponseHeader.ResponseDescription || 'Unexpected Error from Service Provider',
);
}
return plainToInstance(responseClass, response.data[responseKey], {
return plainToInstance(responseClass, data.data[responseKey], {
excludeExtraneousValues: true,
});
} catch (error: any) {