node-paytmpg 7.0.1 → 7.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -176,9 +176,17 @@ Common:
176
176
  Gateway-specific:
177
177
 
178
178
  - Paytm: `paytm_url`, `MID`, `WEBSITE`, `CHANNEL_ID`, `INDUSTRY_TYPE_ID`
179
+ - Sandbox: https://securegw-stage.paytm.in
180
+ - Prod: https://securegw.paytm.in
179
181
  - Razorpay: `razor_url`, `KEY`, `SECRET`
182
+ - Sandbox: https://api.razorpay.com/
183
+ - Prod: https://api.razorpay.com/
180
184
  - PayU: `payu_url`, `KEY`, `SECRET`
185
+ - Sandbox: https://test.payu.in/_payment
186
+ - Prod: https://secure.payu.in/_payment
181
187
  - Open Money: `open_money_url`, `KEY`, `SECRET`
188
+ - Sandbox: https://sandbox-icp-api.bankopen.co/api
189
+ - Prod: https://icp-api.bankopen.co/api
182
190
 
183
191
  UI / behavior:
184
192
 
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -7,10 +40,9 @@ exports.PaymentController = void 0;
7
40
  const package_json_1 = __importDefault(require("../../package.json"));
8
41
  const checksum_1 = __importDefault(require("./checksum/checksum"));
9
42
  const PaytmChecksum_1 = __importDefault(require("./checksum/PaytmChecksum"));
43
+ const crypto = __importStar(require("crypto"));
10
44
  const path_1 = __importDefault(require("path"));
11
45
  const axios_1 = __importDefault(require("axios"));
12
- //@ts-ignore
13
- const nodejs_base64_converter_1 = __importDefault(require("nodejs-base64-converter"));
14
46
  const razorpay_1 = __importDefault(require("razorpay"));
15
47
  const open_money_1 = __importDefault(require("./adapters/open_money"));
16
48
  const payu_1 = __importDefault(require("./adapters/payu"));
@@ -40,6 +72,66 @@ class PaymentController {
40
72
  this.useController = new user_controller_1.NPUserController(this.db, this.tableNames.USER);
41
73
  this.configure(config);
42
74
  }
75
+ encodeTxnDataForUrl(txnDataJson) {
76
+ // Accept either an object or a JSON string.
77
+ const payloadStr = typeof txnDataJson === 'string' ? txnDataJson : JSON.stringify(txnDataJson);
78
+ // Derive a 32-byte key from config.SECRET (fallback to config.KEY).
79
+ const secret = String(this.config.SECRET || this.config.KEY || '');
80
+ if (!secret) {
81
+ // No secret available — fallback to url-safe base64 (not secure).
82
+ return Buffer.from(payloadStr, 'utf8').toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
83
+ }
84
+ const key = crypto.createHash('sha256').update(secret).digest(); // 32 bytes
85
+ const iv = crypto.randomBytes(12); // 12 bytes recommended for GCM
86
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
87
+ const encrypted = Buffer.concat([cipher.update(payloadStr, 'utf8'), cipher.final()]);
88
+ const tag = cipher.getAuthTag();
89
+ // Store as: iv (12) | tag (16) | ciphertext — then URL-safe base64
90
+ const out = Buffer.concat([iv, tag, encrypted]).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
91
+ return out;
92
+ }
93
+ decodeTxnDataFromUrl(encodedStr) {
94
+ if (!encodedStr)
95
+ return '';
96
+ // Convert back to standard base64 and pad
97
+ let b64 = encodedStr.replace(/-/g, '+').replace(/_/g, '/');
98
+ const pad = b64.length % 4;
99
+ if (pad)
100
+ b64 += '='.repeat(4 - pad);
101
+ const raw = Buffer.from(b64, 'base64');
102
+ // If too short to contain iv+tag, treat as plain base64 payload
103
+ if (raw.length < 12 + 16 + 1) {
104
+ try {
105
+ return raw.toString('utf8');
106
+ }
107
+ catch (e) {
108
+ return '';
109
+ }
110
+ }
111
+ try {
112
+ const iv = raw.slice(0, 12);
113
+ const tag = raw.slice(12, 28);
114
+ const ciphertext = raw.slice(28);
115
+ const secret = String(this.config.SECRET || this.config.KEY || '');
116
+ if (!secret)
117
+ return raw.toString('utf8');
118
+ const key = crypto.createHash('sha256').update(secret).digest();
119
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
120
+ decipher.setAuthTag(tag);
121
+ const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
122
+ return decrypted;
123
+ }
124
+ catch (err) {
125
+ // Fallback: return plain base64-decoded string (best-effort)
126
+ try {
127
+ return Buffer.from(b64, 'base64').toString('utf8');
128
+ }
129
+ catch (e) {
130
+ console.log('decodeTxnDataFromUrl error', e);
131
+ return '';
132
+ }
133
+ }
134
+ }
43
135
  configure(config) {
44
136
  const viewRoot = config.templateDir
45
137
  ? config.templateDir
@@ -95,7 +187,7 @@ class PaymentController {
95
187
  const vp = this.viewPath;
96
188
  const razorPayInstance = this.razorPayInstance;
97
189
  if (!req.body.ORDER_ID && !req.body.EMAIL && ((_a = req.query) === null || _a === void 0 ? void 0 : _a.to)) {
98
- let toData = JSON.parse(nodejs_base64_converter_1.default.decode(req.query.to));
190
+ let toData = JSON.parse(this.decodeTxnDataFromUrl(req.query.to));
99
191
  req.body.NAME = toData.NAME;
100
192
  req.body.EMAIL = toData.EMAIL;
101
193
  req.body.TXN_AMOUNT = toData.TXN_AMOUNT;
@@ -377,7 +469,8 @@ class PaymentController {
377
469
  pname: req.body.PRODUCT_NAME,
378
470
  extra: '',
379
471
  returnUrl: req.body.RETURN_URL || '',
380
- webhookUrl: req.body.WEBHOOK_URL || ''
472
+ webhookUrl: req.body.WEBHOOK_URL || '',
473
+ clientId: req.body.CLIENT_ID || ''
381
474
  };
382
475
  try {
383
476
  const txn = await this.insertTransactionInDb(txnTask);
@@ -548,6 +641,15 @@ class PaymentController {
548
641
  callbacks.onFinish(req.body.ORDERID, objForUpdate);
549
642
  }
550
643
  objForUpdate.readonly = "readonly";
644
+ if (webhookUrl) {
645
+ try {
646
+ await axios_1.default.post(webhookUrl, objForUpdate);
647
+ console.log("Sent webhook to ", webhookUrl, 'orderId:', req.body.ORDERID, 'txnId:', req.body.TXNID);
648
+ }
649
+ catch (e) {
650
+ console.log("Error sending webhook to ", webhookUrl, (e === null || e === void 0 ? void 0 : e.message) || e, 'orderId:', req.body.ORDERID, 'txnId:', req.body.TXNID);
651
+ }
652
+ }
551
653
  if (returnUrl) {
552
654
  const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
553
655
  return res.redirect(`${returnUrl}${separator}status=${objForUpdate.status}&ORDERID=${objForUpdate.orderId}&TXNID=${objForUpdate.txnId}`);
@@ -753,10 +855,11 @@ class PaymentController {
753
855
  pname: req.body.PRODUCT_NAME,
754
856
  returnUrl: req.body.RETURN_URL || '',
755
857
  webhookUrl: req.body.WEBHOOK_URL || '',
756
- extra: (req.body.EXTRA || '')
858
+ extra: (req.body.EXTRA || ''),
859
+ clientId: req.body.CLIENT_ID || ''
757
860
  };
758
861
  const txn = await this.insertTransactionInDb(txnTask);
759
- const urlData64 = nodejs_base64_converter_1.default.encode(JSON.stringify({
862
+ const urlData64 = this.encodeTxnDataForUrl(JSON.stringify({
760
863
  NAME: txn.name,
761
864
  EMAIL: txn.email,
762
865
  MOBILE_NO: txn.phone,
@@ -764,7 +867,8 @@ class PaymentController {
764
867
  RETURN_URL: txn.returnUrl,
765
868
  WEBHOOK_URL: txn.webhookUrl,
766
869
  TXN_AMOUNT: txn.amount,
767
- PRODUCT_NAME: txn.pname
870
+ PRODUCT_NAME: txn.pname,
871
+ clientId: txn.clientId
768
872
  }));
769
873
  txn.payurl = config.host_url + '/' + config.path_prefix + '/init?to=' + urlData64;
770
874
  res.send(txn);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-paytmpg",
3
- "version": "7.0.1",
3
+ "version": "7.1.2",
4
4
  "description": "Payment Gateway Integration using NodeJS",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-paytmpg",
3
- "version": "7.0.1",
3
+ "version": "7.1.2",
4
4
  "description": "Payment Gateway Integration using NodeJS",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {