Skip to content

Commit

Permalink
Merge pull request #49 from mojaloop/dev
Browse files Browse the repository at this point in the history
chore: improvements for core connector template
  • Loading branch information
elijah0kello authored Sep 25, 2024
2 parents 17ba8c2 + ad649fe commit d396ba4
Show file tree
Hide file tree
Showing 15 changed files with 507 additions and 84 deletions.
17 changes: 13 additions & 4 deletions core-connector-template/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ FSP_ID=testdfsp
CONNECTOR_NAME=TemplateCC

# CBS Config
EXAMPLE_BASE_URL=https://examplebank.com
EXAMPLE_USERNAME=user
EXAMPLE_PASSWORD=password
SUPPORTED_ID_TYPE=MSISDN
SUPPORTED_ID_TYPE=MSISDN
CBS_NAME=DFSP
DFSP_BASE_URL=https://examplebank.com
CLIENT_ID=2394934345
CLIENT_SECRET=password
GRANT_TYPE=client_credentials
X_COUNTRY=MW
X_CURRENCY=MWK
SUPPORTED_ID_TYPE=MSISDN
SENDING_SERVICE_CHARGE=1
RECEIVING_SERVICE_CHARGE=1
EXPIRATION_DURATION=3
AIRTEL_PIN=345445
72 changes: 72 additions & 0 deletions core-connector-template/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,78 @@ const config = Convict<IConfigSchema>({
default: null, // required
env: 'CBS_NAME',
},
DFSP_BASE_URL:{
doc: 'API Base URL',
format: String,
default: null, // required
env: 'DFSP_BASE_URL',
},
CLIENT_ID:{
doc: 'Client ID for api user',
format: String,
default: null, // required
env: 'CLIENT_ID',
},
CLIENT_SECRET:{
doc: 'Client Secret for api user',
format: String,
default: null, // required
env: 'CLIENT_SECRET',
},
GRANT_TYPE:{
doc: 'Airtel Grant Type',
format: String,
default: null, // required
env: 'GRANT_TYPE',
},
X_COUNTRY:{
doc: 'Country',
format: String,
default: null, // required
env: 'X_COUNTRY',
},
X_CURRENCY:{
doc: 'Currency',
format: String,
default: null, // required
env: 'X_CURRENCY',
},
SUPPORTED_ID_TYPE:{
doc: 'Supported Id Type',
format: String,
default: null, // required
env: 'SUPPORTED_ID_TYPE',
},
SENDING_SERVICE_CHARGE:{
doc: 'Charge for sending money to customer account',
format: String,
default: null, // required
env: 'SENDING_SERVICE_CHARGE',
},
RECEIVING_SERVICE_CHARGE:{
doc: 'Charge for collecting money from customer account',
format: String,
default: null, // required
env: 'RECEIVING_SERVICE_CHARGE',
},
EXPIRATION_DURATION:{
doc: 'Quote expiration duration',
format: String,
default: null, // required
env: 'EXPIRATION_DURATION',
},
AIRTEL_PIN:{
doc: 'Airtel disbursement PIN',
format: String,
default: null, // required
env: 'AIRTEL_PIN',
},
FSP_ID:{
doc: 'FSP Identifier',
format: String,
default: null, // required
env: 'FSP_ID',
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ optionally within square brackets <email>.
import { Request, ResponseToolkit, ServerRoute } from '@hapi/hapi';
import OpenAPIBackend, { Context } from 'openapi-backend';
import { CoreConnectorAggregate } from 'src/domain/coreConnectorAgg';
import { ILogger, TQuoteRequest, TtransferRequest } from '../domain';
import { ILogger, TQuoteRequest, TtransferPatchNotificationRequest, TtransferRequest } from '../domain';
import { BaseRoutes } from './BaseRoutes';
import config from '../config';

Expand All @@ -45,6 +45,7 @@ export class CoreConnectorRoutes extends BaseRoutes {
BackendPartiesGetByTypeAndID: this.getParties.bind(this),
BackendQuoteRequest: this.quoteRequests.bind(this),
BackendTransfersPost: this.transfers.bind(this),
BackendTransfersPut: this.transferNotification.bind(this),
validationFail: async (context: Context, req: Request, h: ResponseToolkit) => h.response({ error: context.validation.errors }).code(412),
notFound: async (context: Context, req: Request, h: ResponseToolkit) => h.response({ error: 'Not found' }).code(404),
};
Expand Down Expand Up @@ -105,7 +106,7 @@ export class CoreConnectorRoutes extends BaseRoutes {
const Id = params['ID'] as string;
const IdType = params['IdType'] as string;
const result = await this.aggregate.getParties(Id,IdType);
return this.handleResponse(result.data, h);
return this.handleResponse(result, h);
} catch (error) {
return this.handleError(error, h);
}
Expand All @@ -130,4 +131,16 @@ export class CoreConnectorRoutes extends BaseRoutes {
return this.handleError(error, h);
}
}

private async transferNotification(context: Context, request: Request, h: ResponseToolkit){
const transferNotificatioPayload = request.payload as TtransferPatchNotificationRequest;
const { params } = context.request;
const transferId = params['transferId'] as string;
try{
const result = await this.aggregate.updateTransfer(transferNotificatioPayload, transferId);
return this.handleResponse(result,h);
}catch(error: unknown){
return this.handleError(error,h);
}
}
}
10 changes: 5 additions & 5 deletions core-connector-template/src/domain/CBSClient/CBSClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class CBSClient implements ICbsClient{

async getKyc(deps: TGetKycArgs): Promise<TCbsKycResponse> {
this.logger.info("Getting KYC Information");
const res = await this.httpClient.get<TCbsKycResponse>(`https://${this.cbsConfig.AIRTEL_BASE_URL}${CBS_ROUTES.getKyc}${deps.msisdn}`, {
const res = await this.httpClient.get<TCbsKycResponse>(`https://${this.cbsConfig.DFSP_BASE_URL}${CBS_ROUTES.getKyc}${deps.msisdn}`, {
headers: {
...this.getDefaultHeader(),
'Authorization': `Bearer ${await this.getAuthHeader()}`
Expand All @@ -80,7 +80,7 @@ export class CBSClient implements ICbsClient{

async getToken(deps: TGetTokenArgs): Promise<TGetTokenResponse> {
this.logger.info("Getting Access Token from Airtel");
const url = `https://${this.cbsConfig.AIRTEL_BASE_URL}${CBS_ROUTES.getToken}`;
const url = `https://${this.cbsConfig.DFSP_BASE_URL}${CBS_ROUTES.getToken}`;
this.logger.info(url);
try {
const res = await this.httpClient.post<TGetTokenArgs, TGetTokenResponse>(url, deps, {
Expand All @@ -99,7 +99,7 @@ export class CBSClient implements ICbsClient{

async sendMoney(deps: TCbsDisbursementRequestBody): Promise<TCbsDisbursementResponse> {
this.logger.info("Sending Disbursement Body To Airtel");
const url = `https://${this.cbsConfig.AIRTEL_BASE_URL}${CBS_ROUTES.sendMoney}`;
const url = `https://${this.cbsConfig.DFSP_BASE_URL}${CBS_ROUTES.sendMoney}`;
try {
const res = await this.httpClient.post<TCbsDisbursementRequestBody, TCbsDisbursementResponse>(url, deps,
{
Expand All @@ -121,7 +121,7 @@ export class CBSClient implements ICbsClient{
}
async collectMoney(deps: TCbsCollectMoneyRequest): Promise<TCbsCollectMoneyResponse> {
this.logger.info("Collecting Money from Airtel");
const url = `https://${this.cbsConfig.AIRTEL_BASE_URL}${CBS_ROUTES.collectMoney}`;
const url = `https://${this.cbsConfig.DFSP_BASE_URL}${CBS_ROUTES.collectMoney}`;

try {
const res = await this.httpClient.post<TCbsCollectMoneyRequest, TCbsCollectMoneyResponse>(url, deps, {
Expand All @@ -143,7 +143,7 @@ export class CBSClient implements ICbsClient{

async refundMoney(deps: TCbsRefundMoneyRequest): Promise<TCbsRefundMoneyResponse> {
this.logger.info("Refunding Money to Customer in Airtel");
const url = `https://${this.cbsConfig.AIRTEL_BASE_URL}${CBS_ROUTES.refundMoney}`;
const url = `https://${this.cbsConfig.DFSP_BASE_URL}${CBS_ROUTES.refundMoney}`;

try{
const res = await this.httpClient.post<TCbsRefundMoneyRequest,TCbsRefundMoneyResponse>(url, deps,{
Expand Down
8 changes: 4 additions & 4 deletions core-connector-template/src/domain/CBSClient/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ export type TCBSClientFactoryDeps = {

export type TCBSConfig = {
CBS_NAME: string;
AIRTEL_BASE_URL: string;
DFSP_BASE_URL: string;
CLIENT_ID: string;
CLIENT_SECRET: string;
GRANT_TYPE: string;
X_COUNTRY: string;
X_CURRENCY: string;
X_CURRENCY: components["schemas"]["Currency"];
SUPPORTED_ID_TYPE: components["schemas"]["PartyIdType"];
SERVICE_CHARGE: string;
SENDING_SERVICE_CHARGE: number;
RECEIVING_SERVICE_CHARGE: number;
EXPIRATION_DURATION: string;
AIRTEL_PIN: string;
TRANSACTION_ENQUIRY_WAIT_TIME: number
FSP_ID:string
}

Expand Down
9 changes: 5 additions & 4 deletions core-connector-template/src/domain/SDKClient/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ import { BasicError, ErrorOptions } from '../interfaces';
export class SDKClientError extends BasicError {
// think, if it's better to have a separate class
static continueTransferError(message: string, options?: ErrorOptions) {
const {
httpCode = 500,
mlCode = httpCode === 504 ? '2004' : '2001'
} = options || {};
const { httpCode = 500, mlCode = httpCode === 504 ? '2004' : '2001' } = options || {};
return new SDKClientError(message, { mlCode, httpCode });
}

Expand All @@ -52,4 +49,8 @@ export class SDKClientError extends BasicError {
mlCode: '3200',
});
}

static genericQuoteValidationError(message: string, options?: ErrorOptions) {
return new SDKClientError(message, options);
}
}
Loading

0 comments on commit d396ba4

Please sign in to comment.