mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-10 07:07:23 +00:00
Compare commits
4 Commits
d3057beb54
...
bea3ccfbbc
Author | SHA1 | Date | |
---|---|---|---|
bea3ccfbbc | |||
492e538eb8 | |||
19fa53c981 | |||
d2cc02fb60 |
@ -49,7 +49,7 @@ export class Oauth2Service {
|
||||
const payload = this.jwtService.verify(appleToken, {
|
||||
publicKey,
|
||||
algorithms: ['RS256'],
|
||||
audience: this.configService.getOrThrow('APPLE_CLIENT_ID'),
|
||||
audience: this.configService.getOrThrow('APPLE_CLIENT_ID').split(','),
|
||||
issuer: this.appleIssuer,
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -10,7 +10,8 @@
|
||||
"INVALID_BIOMETRIC": "البيانات البيومترية المقدمة غير صالحة. يرجى المحاولة مرة أخرى أو إعادة إعداد المصادقة البيومترية.",
|
||||
"PASSWORD_MISMATCH": "كلمات المرور التي أدخلتها غير متطابقة. يرجى إدخال كلمات المرور مرة أخرى.",
|
||||
"INVALID_PASSCODE": "رمز المرور الذي أدخلته غير صحيح. يرجى المحاولة مرة أخرى.",
|
||||
"PASSCODE_ALREADY_SET": "تم تعيين رمز المرور بالفعل."
|
||||
"PASSCODE_ALREADY_SET": "تم تعيين رمز المرور بالفعل.",
|
||||
"APPLE_RE-CONSENT_REQUIRED": "إعادة الموافقة على آبل مطلوبة. يرجى إلغاء تطبيقك من إعدادات معرف آبل الخاصة بك والمحاولة مرة أخرى."
|
||||
},
|
||||
|
||||
"USER": {
|
||||
|
@ -10,7 +10,8 @@
|
||||
"INVALID_BIOMETRIC": "The biometric data provided is invalid. Please try again or reconfigure your biometric settings.",
|
||||
"PASSWORD_MISMATCH": "The passwords you entered do not match. Please re-enter the passwords.",
|
||||
"INVALID_PASSCODE": "The passcode you entered is incorrect. Please try again.",
|
||||
"PASSCODE_ALREADY_SET": "The pass code has already been set."
|
||||
"PASSCODE_ALREADY_SET": "The pass code has already been set.",
|
||||
"APPLE_RE-CONSENT_REQUIRED": "Apple re-consent is required. Please revoke the app from your Apple ID settings and try again."
|
||||
},
|
||||
|
||||
"USER": {
|
||||
|
Reference in New Issue
Block a user