UNPKG

nestjs-connectips

Version:

This is simple wrapper for ConnectIPS Payment @nestjs-connectips. Just ping us or open pull request and contribute :)

215 lines 11 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var ConnectIpsService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConnectIpsService = void 0; const common_1 = require("@nestjs/common"); const connectIps_interface_1 = require("./connectIps.interface"); const axios_1 = require("@nestjs/axios"); const crypto = __importStar(require("crypto")); const rxjs_1 = require("rxjs"); const fs = __importStar(require("node:fs")); const node_forge_1 = __importDefault(require("node-forge")); let ConnectIpsService = ConnectIpsService_1 = class ConnectIpsService { constructor(options, httpService) { this.options = options; this.httpService = httpService; this.paymentMode = null; this.paymentUrlTest = null; this.paymentUrl = null; this.validateUrlTest = null; this.validateUrl = null; this.merchantId = null; this.appId = null; this.appName = null; this.pfxPassword = null; this.pfxPath = null; this.basicAuthPassword = null; if (!options.merchantId) { throw new common_1.InternalServerErrorException("Merchant Id for connectips payment is missing"); } if (!options.appId) { throw new common_1.InternalServerErrorException("App Id Ket for connectips payment is missing"); } if (!options.appName) { throw new common_1.InternalServerErrorException("App Name for connectips payment is missing"); } if (!options.pfxPassword) { throw new common_1.InternalServerErrorException("PFX Password for connectips payment is missing"); } if (!options.pfxPath) { throw new common_1.InternalServerErrorException("PFX Path for connectips payment is missing"); } if (!options.basicAuthPassword) { throw new common_1.InternalServerErrorException("Basic Auth Password for connectips payment is missing"); } if (!fs.existsSync(options.pfxPath)) { throw new Error(`PFX file not found at path: ${options.pfxPath}`); } this.paymentMode = options.paymentMode || connectIps_interface_1.PaymentMode.TEST; this.paymentUrlTest = options.paymentUrlTest || connectIps_interface_1.CONNECT_IPS_PAYMENT_TEST_URL; this.paymentUrl = options.paymentUrl || connectIps_interface_1.CONNECT_IPS_PAYMENT_URL; this.validateUrlTest = options.validateUrlTest || connectIps_interface_1.CONNECT_IPS_VALIDATE_TEST_URL; this.validateUrl = options.validateUrl || connectIps_interface_1.CONNECT_IPS_VALIDATE_URL; this.merchantId = options.merchantId; this.appId = options.appId; this.appName = options.appName; this.pfxPassword = options.pfxPassword; this.pfxPath = options.pfxPath; this.basicAuthPassword = options.basicAuthPassword; } static getMessage(fieldNameList, data) { const keyValuePairs = fieldNameList.map(fieldName => `${fieldName}=${data[fieldName]}`); return keyValuePairs.join(','); } init(data) { let { transactionAmount, transactionId, transactionDate, transactionCurrency, referenceId, remarks, particulars } = data; if (!transactionAmount || !transactionId || !transactionDate || !transactionCurrency || !referenceId || !remarks || !particulars) { throw new common_1.BadRequestException("Data missing for initiating connectips payment"); } const connectIpsData = { MERCHANTID: this.merchantId, APPID: this.appId, APPNAME: this.appName, TXNID: transactionId, TXNDATE: transactionDate, TXNCRNCY: transactionCurrency, TXNAMT: transactionAmount, REFERENCEID: referenceId, REMARKS: remarks, PARTICULARS: particulars, TOKEN: 'TOKEN', PAYMENTURL: this.paymentMode.localeCompare(connectIps_interface_1.PaymentMode.TEST) == 0 ? this.paymentUrlTest : this.paymentUrl }; // STEP 1: Generate token string without the actual signature const fieldNameString = "MERCHANTID,APPID,APPNAME,TXNID,TXNDATE,TXNCRNCY,TXNAMT,REFERENCEID,REMARKS,PARTICULARS,TOKEN"; const message = ConnectIpsService_1.getMessage(fieldNameString.split(','), connectIpsData); connectIpsData.TOKEN = this.generateSignature(message); return connectIpsData; } async validate(data) { var _a, _b, _c; const { transactionAmount, referenceId } = data; if (!transactionAmount) { throw new common_1.BadRequestException('Transaction Amount is missing for validating connectips payment'); } if (!referenceId) { throw new common_1.BadRequestException('Reference Id is missing for validating connectips payment'); } const connectIpsDataForMessage = { "MERCHANTID": this.merchantId, "APPID": this.appId, "REFERENCEID": referenceId, "TXNAMT": transactionAmount }; const fieldNameString = "MERCHANTID,APPID,REFERENCEID,TXNAMT"; const message = ConnectIpsService_1.getMessage(fieldNameString.split(','), connectIpsDataForMessage); const serverSignature = this.generateSignature(message); const connectIpsValidateRequestDto = { merchantId: connectIpsDataForMessage.MERCHANTID, appId: connectIpsDataForMessage.APPID, referenceId: connectIpsDataForMessage.REFERENCEID, txnAmt: connectIpsDataForMessage.TXNAMT, token: serverSignature }; const basicAuth = 'Basic ' + Buffer.from(`${this.appId}:${this.basicAuthPassword}`).toString('base64'); const validateUrl = this.paymentMode.localeCompare('TEST') == 0 ? this.validateUrlTest : this.validateUrl; try { const response = await (0, rxjs_1.firstValueFrom)(this.httpService.post(validateUrl, connectIpsValidateRequestDto, { headers: { Authorization: basicAuth } })); if ((response === null || response === void 0 ? void 0 : response.status) == 200 && response.data) { return { referenceId: (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.referenceId, transactionAmount: (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.txnAmt, status: (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.status, }; } throw new common_1.InternalServerErrorException('Unexpected response from connectips verification endpoint.'); } catch (error) { throw new common_1.InternalServerErrorException(`Error in payment verification \n ${error === null || error === void 0 ? void 0 : error.message}`); } } generateSignature(message) { const pfxPassword = this.pfxPassword; const pfxBuffer = fs.readFileSync(this.pfxPath); const p12Asn1 = node_forge_1.default.asn1.fromDer(pfxBuffer.toString('binary')); const p12 = node_forge_1.default.pkcs12.pkcs12FromAsn1(p12Asn1, pfxPassword); let privateKey = null; for (const safeContent of p12.safeContents) { for (const safeBag of safeContent.safeBags) { if (safeBag.type === node_forge_1.default.pki.oids.keyBag || safeBag.type === node_forge_1.default.pki.oids.pkcs8ShroudedKeyBag) { privateKey = node_forge_1.default.pki.privateKeyToPem(safeBag.key); } } } if (!privateKey) { throw new common_1.InternalServerErrorException("Private key not found in PFX"); } const signer = crypto.createSign('RSA-SHA256'); signer.update(message); const signature = signer.sign(privateKey); return signature.toString('base64'); } }; exports.ConnectIpsService = ConnectIpsService; exports.ConnectIpsService = ConnectIpsService = ConnectIpsService_1 = __decorate([ (0, common_1.Injectable)(), __param(0, (0, common_1.Inject)(connectIps_interface_1.CONNECT_IPS_CONFIG_OPTIONS)), __metadata("design:paramtypes", [Object, axios_1.HttpService]) ], ConnectIpsService); //# sourceMappingURL=connectIps.service.js.map