node-paytmpg 6.4.7 → 7.1.1

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.
Files changed (58) hide show
  1. package/README.MD +132 -182
  2. package/app/views/layouts/index.hbs +7 -7
  3. package/app/views/result.hbs +1 -1
  4. package/dist/app/controllers/adapters/open_money.js +400 -0
  5. package/dist/app/controllers/adapters/paytm.js +34 -0
  6. package/{app → dist/app}/controllers/adapters/payu.js +208 -239
  7. package/dist/app/controllers/checksum/PaytmChecksum.js +118 -0
  8. package/dist/app/controllers/checksum/checksum.js +158 -0
  9. package/dist/app/controllers/checksum/crypt.js +117 -0
  10. package/dist/app/controllers/checksum/server.js +130 -0
  11. package/dist/app/controllers/payment.controller.js +1089 -0
  12. package/dist/app/controllers/static/loadingsvg.js +54 -0
  13. package/dist/app/controllers/user.controller.js +53 -0
  14. package/dist/app/models/index.js +2 -0
  15. package/dist/app/routes/payment_route.js +46 -0
  16. package/dist/app/utils/buildConfig.js +210 -0
  17. package/dist/app/utils/utils.js +20 -0
  18. package/dist/app/views/home.hbs +22 -0
  19. package/dist/app/views/init.hbs +98 -0
  20. package/dist/app/views/layouts/index.hbs +53 -0
  21. package/dist/app/views/result.hbs +33 -0
  22. package/dist/index.js +119 -0
  23. package/dist/package.json +67 -0
  24. package/dist/public/css/style.css +455 -0
  25. package/dist/public/js/index.js +283 -0
  26. package/dist/public/layer_checkout.js +38 -0
  27. package/dist/public/pay.png +0 -0
  28. package/dist/public/start.png +0 -0
  29. package/dist/public/start2.png +0 -0
  30. package/dist/public/stat.png +0 -0
  31. package/dist/public/test.html +24 -0
  32. package/dist/public/test.html~ +24 -0
  33. package/package.json +29 -6
  34. package/public/test.html~ +24 -0
  35. package/.github/workflows/codeql-analysis.yml +0 -71
  36. package/.github/workflows/nodejs.yml +0 -24
  37. package/.github/workflows/npm-publish.yml +0 -23
  38. package/Dockerfile +0 -9
  39. package/app/controllers/adapters/open_money.js +0 -515
  40. package/app/controllers/checksum/PaytmChecksum.js +0 -94
  41. package/app/controllers/checksum/checksum.js +0 -154
  42. package/app/controllers/checksum/crypt.js +0 -98
  43. package/app/controllers/checksum/server.js +0 -132
  44. package/app/controllers/np_user.controller.js +0 -89
  45. package/app/controllers/payment_controller.js +0 -1295
  46. package/app/models/np_multidbplugin.js +0 -111
  47. package/app/models/np_transaction.model.js +0 -16
  48. package/app/models/np_user.model.js +0 -12
  49. package/app/routes/payment_route.js +0 -73
  50. package/app.yaml +0 -18
  51. package/example.js +0 -34
  52. package/index.js +0 -90
  53. package/lib/config/buildConfig.js +0 -113
  54. package/lib/config/defaults.js +0 -37
  55. package/lib/config/validator.js +0 -103
  56. package/lib/services/database.service.js +0 -153
  57. package/lib/utils/id-generator.js +0 -30
  58. package/lib/utils/sanitizer.js +0 -25
@@ -0,0 +1,1089 @@
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
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PaymentController = void 0;
40
+ const package_json_1 = __importDefault(require("../../package.json"));
41
+ const checksum_1 = __importDefault(require("./checksum/checksum"));
42
+ const PaytmChecksum_1 = __importDefault(require("./checksum/PaytmChecksum"));
43
+ const crypto = __importStar(require("crypto"));
44
+ const path_1 = __importDefault(require("path"));
45
+ const axios_1 = __importDefault(require("axios"));
46
+ const razorpay_1 = __importDefault(require("razorpay"));
47
+ const open_money_1 = __importDefault(require("./adapters/open_money"));
48
+ const payu_1 = __importDefault(require("./adapters/payu"));
49
+ const user_controller_1 = require("./user.controller");
50
+ const utils_1 = require("../utils/utils");
51
+ const loadingsvg_1 = require("./static/loadingsvg");
52
+ const paytm_1 = require("./adapters/paytm");
53
+ const IDLEN = 14;
54
+ function makeid(length) {
55
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
56
+ let result = '';
57
+ for (let i = 0; i < length; i++) {
58
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
59
+ }
60
+ return result;
61
+ }
62
+ class PaymentController {
63
+ constructor(config, db, callbacks, tableNames) {
64
+ this.tableNames = { USER: 'npusers', TRANSACTION: 'nptransactions' };
65
+ this.viewPath = '';
66
+ this.config = config;
67
+ this.callbacks = callbacks;
68
+ this.db = db;
69
+ if (tableNames) {
70
+ this.tableNames = tableNames;
71
+ }
72
+ this.useController = new user_controller_1.NPUserController(this.db, this.tableNames.USER);
73
+ this.configure(config);
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
+ }
135
+ configure(config) {
136
+ const viewRoot = config.templateDir
137
+ ? config.templateDir
138
+ : path_1.default.join(__dirname, '..', 'views');
139
+ this.viewPath = viewRoot.endsWith(path_1.default.sep) ? viewRoot : viewRoot + path_1.default.sep;
140
+ if (config.payu_url)
141
+ this.payuInstance = new payu_1.default(config);
142
+ if (config.open_money_url)
143
+ this.openMoneyInstance = new open_money_1.default(config);
144
+ if (config.razor_url) {
145
+ this.razorPayInstance = new razorpay_1.default({ key_id: config.KEY, key_secret: config.SECRET });
146
+ }
147
+ const sample = {
148
+ orderId: "string",
149
+ cusId: "string",
150
+ time: 1770051201752,
151
+ timeStamp: 1770051201752,
152
+ status: "string",
153
+ name: "string",
154
+ email: "string",
155
+ phone: "12345678",
156
+ amount: 1,
157
+ pname: "string",
158
+ extra: "stringlarge",
159
+ TXNID: "27118670199",
160
+ returnUrl: "string"
161
+ };
162
+ this.db.create(this.tableNames.TRANSACTION, sample).catch(() => { });
163
+ }
164
+ async insertTransactionInDb(txnData) {
165
+ await this.db.insert(this.tableNames.TRANSACTION, txnData);
166
+ return txnData;
167
+ }
168
+ async generateChecksum(params) {
169
+ return await new Promise((resolve, reject) => {
170
+ checksum_1.default.genchecksum(params, this.config.KEY, (err, cs) => {
171
+ if (err || !cs) {
172
+ reject(err || new Error('Error generating checksum'));
173
+ return;
174
+ }
175
+ resolve(cs);
176
+ });
177
+ });
178
+ }
179
+ home(req, res) {
180
+ package_json_1.default.repository.url = package_json_1.default.repository.url.replace('git+', '');
181
+ res.render(this.viewPath + "home.hbs", package_json_1.default);
182
+ }
183
+ async init(req, res) {
184
+ var _a;
185
+ const config = this.config;
186
+ const callbacks = this.callbacks;
187
+ const vp = this.viewPath;
188
+ const razorPayInstance = this.razorPayInstance;
189
+ if (!req.body.ORDER_ID && !req.body.EMAIL && ((_a = req.query) === null || _a === void 0 ? void 0 : _a.to)) {
190
+ let toData = JSON.parse(this.decodeTxnDataFromUrl(req.query.to));
191
+ req.body.NAME = toData.NAME;
192
+ req.body.EMAIL = toData.EMAIL;
193
+ req.body.TXN_AMOUNT = toData.TXN_AMOUNT;
194
+ req.body.MOBILE_NO = toData.MOBILE_NO;
195
+ req.body.ORDER_ID = toData.ORDER_ID || toData.ORDERID;
196
+ req.body.PRODUCT_NAME = toData.PRODUCT_NAME;
197
+ req.body.RETURN_URL = toData.RETURN_URL;
198
+ }
199
+ utils_1.Utils.sanitizeRequest(req.body);
200
+ let gotAllParams = true;
201
+ let checkedFields = ['TXN_AMOUNT', 'PRODUCT_NAME', 'MOBILE_NO', 'NAME', 'EMAIL'];
202
+ if (req.body !== undefined) {
203
+ for (var i = 0; i < checkedFields.length; i++) {
204
+ if (req.body[checkedFields[i]] === undefined) {
205
+ gotAllParams = false;
206
+ break;
207
+ }
208
+ }
209
+ }
210
+ else {
211
+ gotAllParams = false;
212
+ }
213
+ // console.log(req.body)
214
+ if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)
215
+ &&
216
+ (req.body.CUST_ID !== undefined && req.body.CUST_ID.length > 2)) {
217
+ // console.log('redirect')
218
+ // console.log(req.body)
219
+ var params = {
220
+ TXN_AMOUNT: req.body.TXN_AMOUNT,
221
+ };
222
+ params['MID'] = req.body.MID;
223
+ params['WEBSITE'] = req.body.WEBSITE;
224
+ params['CHANNEL_ID'] = req.body.CHANNEL_ID;
225
+ params['INDUSTRY_TYPE_ID'] = req.body.INDUSTRY_TYPE_ID;
226
+ params['ORDER_ID'] = req.body.ORDER_ID || req.body.ORDERID;
227
+ params['CUST_ID'] = req.body.CUST_ID;
228
+ params['TXN_AMOUNT'] = req.body.TXN_AMOUNT;
229
+ params['CALLBACK_URL'] = req.body.CALLBACK_URL + "?order_id=" + req.body.ORDER_ID;
230
+ params['EMAIL'] = req.body.EMAIL;
231
+ params['MOBILE_NO'] = req.body.MOBILE_NO;
232
+ params['PRODUCT_NAME'] = req.body.PRODUCT_NAME;
233
+ params['NAME'] = req.body.NAME;
234
+ if (this.config.paytm_url) {
235
+ let initTxnbody = {
236
+ "requestType": "Payment",
237
+ "mid": params['MID'],
238
+ "websiteName": params['WEBSITE'],
239
+ "orderId": params['ORDER_ID'],
240
+ "callbackUrl": params['CALLBACK_URL'],
241
+ "txnAmount": {
242
+ "value": params['TXN_AMOUNT'],
243
+ "currency": params['CURRENCY'] || "INR",
244
+ },
245
+ "userInfo": {
246
+ "custId": params['CUST_ID'],
247
+ "mobile": params['MOBILE_NO'],
248
+ "firstName": params['NAME'],
249
+ "email": params['EMAIL']
250
+ }
251
+ };
252
+ if (this.config.mode) {
253
+ initTxnbody["enablePaymentMode"] = JSON.parse(this.config.mode);
254
+ }
255
+ let checksum = await PaytmChecksum_1.default.generateSignature(JSON.stringify(initTxnbody), this.config.KEY);
256
+ let initTxnUrl = this.config.paytm_url + `/theia/api/v1/initiateTransaction?mid=${params['MID']}&orderId=${params['ORDER_ID']}`;
257
+ try {
258
+ const resp = await axios_1.default.post(initTxnUrl, {
259
+ body: initTxnbody,
260
+ head: {
261
+ signature: checksum,
262
+ channelId: params['CHANNEL_ID']
263
+ }
264
+ });
265
+ const body = resp.data;
266
+ if (resp.status === 200 && body && body.body && body.body.resultInfo && body.body.resultInfo.resultStatus === 'S') {
267
+ let paytmJsToken = {};
268
+ paytmJsToken.CALLBACK_URL = params['CALLBACK_URL'];
269
+ paytmJsToken.ORDERID = params['ORDER_ID'];
270
+ paytmJsToken.ORDER_ID = params['ORDER_ID'];
271
+ paytmJsToken.CANCELLED = 'cancelled';
272
+ paytmJsToken.TOKEN = body.body.txnToken;
273
+ paytmJsToken.TXN_AMOUNT = params['TXN_AMOUNT'];
274
+ paytmJsToken.MID = params['MID'];
275
+ paytmJsToken.CALLBACK_URL = params['CALLBACK_URL'];
276
+ return res.send((0, paytm_1.createPaytmJsCheckoutHtml)(paytmJsToken, this.config));
277
+ }
278
+ else {
279
+ console.log('ERROR:::', resp.status, '\n', body);
280
+ res.status(500);
281
+ var form_fields = '';
282
+ let errorResp = {
283
+ TXNID: 'na',
284
+ STATUS: 'TXN_FAILURE',
285
+ CANCELLED: 'cancelled',
286
+ ORDERID: params['ORDER_ID']
287
+ };
288
+ for (var x in errorResp) {
289
+ form_fields += "<input type='hidden' name='" + x + "' value='" + errorResp[x] + "' >";
290
+ }
291
+ form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + checksum + "' >";
292
+ res.writeHead(200, { 'Content-Type': 'text/html' });
293
+ res.write(`<html>
294
+
295
+ <head>
296
+ <title>Merchant Checkout Error</title>
297
+ </head>
298
+
299
+ <body>
300
+ <center>
301
+ <h1>Something went wrong. Please wait you will be redirected automatically...</h1>
302
+ </center>
303
+ <form method="post" action="${params['CALLBACK_URL']}" name="f1">${form_fields}</form>
304
+ <script type="text/javascript">document.f1.submit();</script>
305
+ </body>
306
+
307
+ </html>`);
308
+ res.end();
309
+ }
310
+ }
311
+ catch (err) {
312
+ console.log('ERROR:::', err);
313
+ res.status(500);
314
+ var form_fields = '';
315
+ let errorResp = {
316
+ TXNID: 'na',
317
+ STATUS: 'TXN_FAILURE',
318
+ CANCELLED: 'cancelled',
319
+ ORDERID: params['ORDER_ID']
320
+ };
321
+ for (var x in errorResp) {
322
+ form_fields += "<input type='hidden' name='" + x + "' value='" + errorResp[x] + "' >";
323
+ }
324
+ form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + checksum + "' >";
325
+ res.writeHead(200, { 'Content-Type': 'text/html' });
326
+ res.write(`<html>
327
+
328
+ <head>
329
+ <title>Merchant Checkout Error</title>
330
+ </head>
331
+
332
+ <body>
333
+ <center>
334
+ <h1>Something went wrong. Please wait you will be redirected automatically...</h1>
335
+ </center>
336
+ <form method="post" action="${params['CALLBACK_URL']}" name="f1">${form_fields}</form>
337
+ <script type="text/javascript">document.f1.submit();</script>
338
+ </body>
339
+
340
+ </html>`);
341
+ res.end();
342
+ }
343
+ }
344
+ else if (this.config.razor_url) {
345
+ let fail = `<div style="display:none">
346
+
347
+ <form method="post" action="${params['CALLBACK_URL']}" id="fail">
348
+ <input name="razorpay_order_id" value="${params['ORDER_ID']}" hidden="true"/>
349
+ </form>
350
+ </div>`;
351
+ let html = `
352
+ <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
353
+ <script>
354
+ var options = {
355
+ "key": "${this.config.KEY}",
356
+ "amount": "${parseFloat(params['TXN_AMOUNT']) * 100}",
357
+ "currency": "INR",
358
+ "name": "${params['PRODUCT_NAME']}",
359
+ "description": "Order # ${params['ORDER_ID']}",
360
+ "image": "${this.config.logo}",
361
+ "order_id": "${params['ORDER_ID']}",
362
+ "callback_url": "${params['CALLBACK_URL']}",
363
+ "prefill": {
364
+ "name": "${params['NAME']}",
365
+ "email": "${params['EMAIL']}",
366
+ "contact": "${params['MOBILE_NO']}"
367
+ },
368
+ "theme": {
369
+ "color": "${this.config.theme_color}"
370
+ },
371
+ "modal": {
372
+ "ondismiss": function(){
373
+ document.getElementById("fail").submit()
374
+ }
375
+ }
376
+ };
377
+ var rzp1 = new Razorpay(options);
378
+
379
+ rzp1.open();
380
+ </script>`;
381
+ res.writeHead(200, { 'Content-Type': 'text/html' });
382
+ res.write(`<html><head><title>Merchant Checkout Page</title></head><body><center><h1>Processing ! Please do not refresh this page...</h1><br>${html}<br>${fail}<br>${loadingsvg_1.LoadingSVG}</center></body></html>`);
383
+ res.end();
384
+ }
385
+ else if (this.config.payu_url) {
386
+ const payuRequest = this.payuInstance.generatePaymentRequest(params);
387
+ this.payuInstance.renderProcessingPage(params, payuRequest, res, loadingsvg_1.LoadingSVG);
388
+ }
389
+ else if (this.config.open_money_url) {
390
+ try {
391
+ let pmttoken = await this.openMoneyInstance.generatePaymentToken(params);
392
+ this.openMoneyInstance.renderProcessingPage(params, pmttoken, res, loadingsvg_1.LoadingSVG);
393
+ var myquery = { orderId: params['ORDER_ID'] };
394
+ const objForUpdate = await this.db.getOne(this.tableNames.TRANSACTION, myquery);
395
+ if (objForUpdate) {
396
+ objForUpdate.extra = JSON.stringify({
397
+ layer_pay_token_id: pmttoken.tokenid
398
+ });
399
+ await this.db.update(this.tableNames.TRANSACTION, myquery, objForUpdate);
400
+ }
401
+ }
402
+ catch (e) {
403
+ this.openMoneyInstance.renderError(params, e, res);
404
+ }
405
+ }
406
+ if (this.callbacks && typeof this.callbacks.onStart === 'function') {
407
+ this.callbacks.onStart(params['ORDER_ID'], params);
408
+ }
409
+ }
410
+ else if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2) || gotAllParams) {
411
+ let user = await this.useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO });
412
+ //console.log(user)
413
+ const onTxn = async (txnData) => {
414
+ //console.log(txnData)
415
+ const params = {};
416
+ params['MID'] = config.MID;
417
+ params['WEBSITE'] = config.WEBSITE;
418
+ params['CHANNEL_ID'] = config.CHANNEL_ID;
419
+ params['INDUSTRY_TYPE_ID'] = config.INDUSTRY_TYPE_ID;
420
+ params['ORDER_ID'] = txnData.orderId;
421
+ params['CUST_ID'] = txnData.cusId;
422
+ params['TXN_AMOUNT'] = JSON.stringify(txnData.amount);
423
+ params['CALLBACK_URL'] = config.host_url + '/' + config.path_prefix + '/callback';
424
+ params['EMAIL'] = txnData.email;
425
+ params['MOBILE_NO'] = txnData.phone;
426
+ params['NAME'] = txnData.name;
427
+ params['PRODUCT_NAME'] = txnData.pname;
428
+ const showConfirmation = (checksum = '') => {
429
+ res.render(vp + "init.hbs", {
430
+ path_prefix: config.path_prefix,
431
+ action: "/" + config.path_prefix + "/init",
432
+ readonly: 'readonly',
433
+ BUTTON: 'Pay',
434
+ NAME: params['NAME'],
435
+ EMAIL: params['EMAIL'],
436
+ MOBILE_NO: params['MOBILE_NO'],
437
+ PRODUCT_NAME: params['PRODUCT_NAME'],
438
+ TXN_AMOUNT: params['TXN_AMOUNT'],
439
+ MID: params['MID'],
440
+ WEBSITE: params['WEBSITE'],
441
+ ORDER_ID: params['ORDER_ID'],
442
+ CUST_ID: params['CUST_ID'],
443
+ INDUSTRY_TYPE_ID: params['INDUSTRY_TYPE_ID'],
444
+ CHANNEL_ID: params['CHANNEL_ID'],
445
+ CALLBACK_URL: params['CALLBACK_URL'],
446
+ CHECKSUMHASH: checksum
447
+ });
448
+ };
449
+ if (config.paytm_url) {
450
+ const checksum = await this.generateChecksum(params);
451
+ showConfirmation(checksum);
452
+ }
453
+ else if (config.razor_url || config.payu_url || config.open_money_url) {
454
+ showConfirmation();
455
+ }
456
+ };
457
+ const onOrder = async (orderId) => {
458
+ const txnTask = {
459
+ id: orderId,
460
+ orderId: orderId,
461
+ cusId: user.id,
462
+ time: Date.now(),
463
+ timeStamp: Date.now(),
464
+ status: 'INITIATED',
465
+ name: user.name,
466
+ email: user.email,
467
+ phone: user.phone,
468
+ amount: req.body.TXN_AMOUNT,
469
+ pname: req.body.PRODUCT_NAME,
470
+ extra: '',
471
+ returnUrl: req.body.RETURN_URL || '',
472
+ webhookUrl: req.body.WEBHOOK_URL || '',
473
+ clientId: req.body.CLIENT_ID || ''
474
+ };
475
+ try {
476
+ const txn = await this.insertTransactionInDb(txnTask);
477
+ await onTxn(txn);
478
+ }
479
+ catch (err) {
480
+ console.log(err);
481
+ if (req.body.RETURN_URL) {
482
+ res.redirect(req.body.RETURN_URL + "?status=failed");
483
+ return;
484
+ }
485
+ res.redirect('');
486
+ }
487
+ };
488
+ if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)) {
489
+ const myquery = { orderId: req.body.ORDER_ID };
490
+ const orderData = await this.db.getOne(this.tableNames.TRANSACTION, myquery).catch(() => null);
491
+ if (!orderData) {
492
+ if (gotAllParams) {
493
+ console.log("Creating new order for ", req.body.ORDER_ID);
494
+ await onOrder(req.body.ORDER_ID);
495
+ }
496
+ else {
497
+ res.send({ message: "Order Not Found or missing required data: " + checkedFields.join(", "), ORDERID: req.body.ORDER_ID });
498
+ }
499
+ }
500
+ else {
501
+ await onTxn(orderData);
502
+ }
503
+ }
504
+ else {
505
+ let orderId;
506
+ if (config.paytm_url) {
507
+ orderId = "pay_" + makeid(config.id_length || IDLEN);
508
+ await onOrder(orderId);
509
+ }
510
+ else if (config.razor_url) {
511
+ const options = {
512
+ amount: req.body.TXN_AMOUNT * 100,
513
+ currency: "INR",
514
+ receipt: user.id + '_' + Date.now()
515
+ };
516
+ try {
517
+ const order = await razorPayInstance.orders.create(options);
518
+ orderId = order.id;
519
+ await onOrder(orderId);
520
+ }
521
+ catch (err) {
522
+ res.send({ message: "An error occurred ! " + ((err === null || err === void 0 ? void 0 : err.description) || (err === null || err === void 0 ? void 0 : err.message) || 'unknown_error') });
523
+ }
524
+ }
525
+ else if (config.open_money_url) {
526
+ orderId = "pay_" + makeid(config.id_length || IDLEN);
527
+ await onOrder(orderId);
528
+ }
529
+ else if (config.payu_url) {
530
+ orderId = "payu_" + makeid(config.id_length || IDLEN);
531
+ await onOrder(orderId);
532
+ }
533
+ }
534
+ }
535
+ else {
536
+ res.render(this.viewPath + "init.hbs", {
537
+ path_prefix: this.config.path_prefix,
538
+ action: "/" + this.config.path_prefix + "/init",
539
+ readonly: '',
540
+ check: true,
541
+ BUTTON: 'Submit',
542
+ NAME: (req.body.NAME === undefined ? '' : req.body.NAME),
543
+ EMAIL: (req.body.EMAIL === undefined ? '' : req.body.EMAIL),
544
+ MOBILE_NO: (req.body.MOBILE_NO === undefined ? '' : req.body.MOBILE_NO),
545
+ PRODUCT_NAME: (req.body.PRODUCT_NAME === undefined ? '' : req.body.PRODUCT_NAME),
546
+ TXN_AMOUNT: (req.body.TXN_AMOUNT === undefined ? '' : req.body.TXN_AMOUNT),
547
+ MID: config.MID,
548
+ WEBSITE: config.WEBSITE,
549
+ ORDER_ID: '',
550
+ CUST_ID: '',
551
+ INDUSTRY_TYPE_ID: config.INDUSTRY_TYPE_ID,
552
+ CHANNEL_ID: config.CHANNEL_ID,
553
+ CALLBACK_URL: config.CALLBACK_URL,
554
+ CHECKSUMHASH: ''
555
+ });
556
+ }
557
+ }
558
+ async updateTransaction(req, res) {
559
+ const config = this.config;
560
+ const vp = this.viewPath;
561
+ const callbacks = this.callbacks;
562
+ const orderToFind = req.body.ORDERID || req.body.ORDER_ID || req.body.ORDERId || (req.query && req.query.order_id) || req.body.ORDER_ID;
563
+ const myquery = { orderId: orderToFind };
564
+ let objForUpdate = null;
565
+ try {
566
+ objForUpdate = await this.db.getOne(this.tableNames.TRANSACTION, myquery).catch(() => null);
567
+ if (!objForUpdate)
568
+ objForUpdate = await this.db.getOne(this.tableNames.TRANSACTION, { id: orderToFind }).catch(() => null);
569
+ if (!objForUpdate)
570
+ objForUpdate = await this.db.getOne(this.tableNames.TRANSACTION, { ORDERID: orderToFind }).catch(() => null);
571
+ }
572
+ catch {
573
+ objForUpdate = objForUpdate || null;
574
+ }
575
+ let returnUrl = objForUpdate ? objForUpdate.returnUrl : null;
576
+ let webhookUrl = objForUpdate ? objForUpdate.webhookUrl : null;
577
+ if (webhookUrl === 'undefined')
578
+ webhookUrl = null;
579
+ if (returnUrl === 'undefined')
580
+ returnUrl = null;
581
+ if (!objForUpdate) {
582
+ if (webhookUrl) {
583
+ try {
584
+ await axios_1.default.post(webhookUrl, {
585
+ status: 'FAILED',
586
+ message: 'Transaction Not Found',
587
+ ORDERID: req.body.ORDERID,
588
+ TXNID: req.body.TXNID
589
+ });
590
+ console.log("Sent webhook to ", webhookUrl, 'orderId:', req.body.ORDERID, 'txnId:', req.body.TXNID);
591
+ }
592
+ catch (e) {
593
+ 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);
594
+ }
595
+ }
596
+ if (returnUrl) {
597
+ const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
598
+ return res.redirect(`${returnUrl}${separator}status=FAILED&message=txn_not_found&ORDERID=${req.body.ORDERID}`);
599
+ }
600
+ res.send({ message: "Transaction Not Found !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID });
601
+ return;
602
+ }
603
+ if (!["INITIATED", "TXN_PENDING", "PENDING"].includes(String(objForUpdate.status))) {
604
+ objForUpdate.readonly = "readonly";
605
+ if (webhookUrl) {
606
+ try {
607
+ await axios_1.default.post(webhookUrl, objForUpdate);
608
+ console.log("Sent webhook to ", webhookUrl, 'orderId:', req.body.ORDERID, 'txnId:', req.body.TXNID);
609
+ }
610
+ catch (e) {
611
+ 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);
612
+ }
613
+ }
614
+ if (returnUrl) {
615
+ const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
616
+ return res.redirect(`${returnUrl}${separator}status=${objForUpdate.status}&ORDERID=${objForUpdate.orderId}&TXNID=${objForUpdate.txnId}`);
617
+ }
618
+ res.render(vp + "result.hbs", {
619
+ path_prefix: config.path_prefix,
620
+ ...objForUpdate
621
+ });
622
+ return;
623
+ }
624
+ if (req.body.status === "paid" && !req.body.STATUS)
625
+ req.body.STATUS = "TXN_SUCCESS";
626
+ objForUpdate.status = req.body.STATUS;
627
+ objForUpdate.txnId = req.body.TXNID;
628
+ objForUpdate.extra = JSON.stringify(req.body);
629
+ try {
630
+ await this.db.update(this.tableNames.TRANSACTION, myquery, objForUpdate);
631
+ }
632
+ catch {
633
+ if (returnUrl) {
634
+ const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
635
+ return res.redirect(`${returnUrl}${separator}status=FAILED&message=update_error&ORDERID=${req.body.ORDERID}`);
636
+ }
637
+ res.send({ message: "Error Occured !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID });
638
+ return;
639
+ }
640
+ if (callbacks && typeof callbacks.onFinish === 'function') {
641
+ callbacks.onFinish(req.body.ORDERID, objForUpdate);
642
+ }
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
+ }
653
+ if (returnUrl) {
654
+ const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
655
+ return res.redirect(`${returnUrl}${separator}status=${objForUpdate.status}&ORDERID=${objForUpdate.orderId}&TXNID=${objForUpdate.txnId}`);
656
+ }
657
+ res.render(vp + "result.hbs", {
658
+ path_prefix: config.path_prefix,
659
+ ...objForUpdate
660
+ });
661
+ }
662
+ async callback(req, res) {
663
+ const config = this.config;
664
+ const payuInstance = this.payuInstance;
665
+ const openMoneyInstance = this.openMoneyInstance;
666
+ console.log("request_data ", req.originalUrl, JSON.stringify(req.body));
667
+ // Normalize common order id and txn id field names (support ORDER_ID, ORDERID, etc.)
668
+ try {
669
+ if ((!req.body.ORDERID || req.body.ORDERID === '') && req.body.ORDER_ID) {
670
+ req.body.ORDERID = req.body.ORDER_ID;
671
+ }
672
+ if ((!req.body.TXNID || req.body.TXNID === '') && req.body.TXN_ID) {
673
+ req.body.TXNID = req.body.TXN_ID;
674
+ }
675
+ if ((!req.body.ORDERID || req.body.ORDERID === '') && req.query && req.query.order_id) {
676
+ req.body.ORDERID = req.query.order_id;
677
+ }
678
+ }
679
+ catch {
680
+ // ignore
681
+ }
682
+ let result = false;
683
+ let isCancelled = false;
684
+ if (config.paytm_url) {
685
+ const checksumhash = req.body.CHECKSUMHASH;
686
+ if (checksumhash) {
687
+ result = await checksum_1.default.verifychecksum(req.body, config.KEY, checksumhash);
688
+ }
689
+ else {
690
+ const liveStatus = await this.getStatusFromPaytm({ MID: config.MID, ORDERID: req.body.ORDERID }, req.body.ORDERID);
691
+ // Merge important fields when live status is available
692
+ if (liveStatus && typeof liveStatus === 'object') {
693
+ req.body.STATUS = liveStatus.STATUS || req.body.STATUS;
694
+ req.body.TXNID = liveStatus.TXNID || req.body.TXNID;
695
+ }
696
+ result = liveStatus && liveStatus.STATUS == req.body.STATUS;
697
+ }
698
+ if (req.body.STATUS === 'TXN_FAILURE' && req.body.CANCELLED === "cancelled" && req.body.TXNID) {
699
+ isCancelled = true;
700
+ }
701
+ }
702
+ else if (config.razor_url) {
703
+ if (req.body.razorpay_payment_id) {
704
+ result = checksum_1.default.checkRazorSignature(req.body.razorpay_order_id, req.body.razorpay_payment_id, config.SECRET, req.body.razorpay_signature);
705
+ if (result) {
706
+ req.body.STATUS = 'TXN_SUCCESS';
707
+ req.body.ORDERID = req.body.razorpay_order_id;
708
+ req.body.TXNID = req.body.razorpay_payment_id;
709
+ }
710
+ }
711
+ else {
712
+ if (req.body.error && req.body.error.metadata && JSON.parse(req.body.error.metadata)) {
713
+ const orderId = JSON.parse(req.body.error.metadata).order_id;
714
+ req.body.razorpay_order_id = orderId;
715
+ }
716
+ req.body.STATUS = 'TXN_FAILURE';
717
+ req.body.ORDERID = req.body.razorpay_order_id || req.query.order_id;
718
+ isCancelled = true;
719
+ }
720
+ }
721
+ else if (config.payu_url) {
722
+ const payuRest = await payuInstance.verifyResult(req);
723
+ result = !!payuRest.STATUS;
724
+ req.body.STATUS = payuRest.STATUS;
725
+ req.body.TXNID = payuRest.TXNID;
726
+ req.body.ORDERID = payuRest.ORDERID || req.query.order_id;
727
+ req.body.extras = payuRest.data;
728
+ isCancelled = !!payuRest.cancelled;
729
+ }
730
+ else if (config.open_money_url) {
731
+ const openRest = await openMoneyInstance.verifyResult(req);
732
+ result = true;
733
+ req.body.STATUS = openRest.STATUS;
734
+ req.body.TXNID = openRest.TXNID;
735
+ req.body.ORDERID = openRest.ORDERID || req.query.order_id;
736
+ req.body.extras = openRest.data;
737
+ }
738
+ console.log("NodePayTMPG::Transaction => ", req.body.ORDERID, req.body.STATUS);
739
+ if (result || isCancelled) {
740
+ await this.updateTransaction(req, res);
741
+ }
742
+ else {
743
+ res.send({ message: "Something went wrong ! Please try again later .", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID });
744
+ }
745
+ }
746
+ async webhook(req, res) {
747
+ const config = this.config;
748
+ const payuInstance = this.payuInstance;
749
+ const openMoneyInstance = this.openMoneyInstance;
750
+ console.log("request_data ", req.originalUrl, JSON.stringify(req.body));
751
+ if (config.paytm_url) {
752
+ await this.callback(req, res);
753
+ return;
754
+ }
755
+ if (config.razor_url) {
756
+ const events = ["payment.captured", "payment.pending", "payment.failed"];
757
+ if (req.body.event && events.indexOf(req.body.event) > -1) {
758
+ if (req.body.payload &&
759
+ req.body.payload.payment &&
760
+ req.body.payload.payment.entity) {
761
+ const entity = req.body.payload.payment.entity;
762
+ const razorpay_order_id = entity.order_id;
763
+ const razorpay_payment_id = entity.id;
764
+ const status = entity.status;
765
+ const event = req.body.event;
766
+ console.log(`Razorpay webhook payment order=${razorpay_order_id} payid=${razorpay_payment_id} status=${status}`);
767
+ const reqBody = req.rawBody;
768
+ const signature = req.headers["x-razorpay-signature"];
769
+ const signatureValid = razorpay_1.default.validateWebhookSignature(reqBody, signature, config.SECRET);
770
+ if (signatureValid) {
771
+ if (event === events[0]) {
772
+ req.body.STATUS = "TXN_SUCCESS";
773
+ }
774
+ else if (event === events[1]) { //pending
775
+ req.body.STATUS = "TXN_PENDING";
776
+ }
777
+ else { // failed
778
+ req.body.STATUS = "TXN_FAILURE";
779
+ }
780
+ req.body.ORDERID = razorpay_order_id;
781
+ req.body.TXNID = razorpay_payment_id;
782
+ setTimeout(() => {
783
+ this.updateTransaction(req, res);
784
+ }, 3000);
785
+ }
786
+ else {
787
+ res.status(401).send({ message: "Invalid Rzpay signature" });
788
+ }
789
+ }
790
+ else {
791
+ res.status(400).send({ message: "Invalid Payload" });
792
+ }
793
+ }
794
+ else {
795
+ res.status(400).send({ message: "Unsupported event : " + req.body.event });
796
+ }
797
+ return;
798
+ }
799
+ if (config.payu_url) {
800
+ payuInstance.processWebhook(req, res, this.updateTransaction);
801
+ return;
802
+ }
803
+ if (config.open_money_url) {
804
+ openMoneyInstance.processWebhook(req, res, this.updateTransaction);
805
+ }
806
+ }
807
+ async createTxn(req, res) {
808
+ const config = this.config;
809
+ const razorPayInstance = this.razorPayInstance;
810
+ // mandayory field
811
+ const requiredFields = ['NAME', 'EMAIL', 'MOBILE_NO', 'TXN_AMOUNT', 'PRODUCT_NAME'];
812
+ const checkedFields = [];
813
+ let gotAllParams = true;
814
+ requiredFields.forEach(field => {
815
+ if (!req.body[field]) {
816
+ gotAllParams = false;
817
+ checkedFields.push(field);
818
+ }
819
+ });
820
+ if (!gotAllParams) {
821
+ res.status(400).send({ message: "Missing required fields", missing: checkedFields });
822
+ return;
823
+ }
824
+ try {
825
+ const user = await this.useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO });
826
+ let id = '';
827
+ if (config.paytm_url) {
828
+ id = "pay_" + makeid(config.id_length || IDLEN);
829
+ }
830
+ else if (config.razor_url) {
831
+ const options = {
832
+ amount: req.body.TXN_AMOUNT * 100,
833
+ currency: "INR",
834
+ receipt: user.id + '_' + Date.now()
835
+ };
836
+ const order = await razorPayInstance.orders.create(options);
837
+ id = order.id;
838
+ }
839
+ else if (config.payu_url) {
840
+ id = "payu_" + makeid(config.id_length || IDLEN);
841
+ }
842
+ else if (config.open_money_url) {
843
+ id = "pay_" + makeid(config.id_length || IDLEN);
844
+ }
845
+ const txnTask = {
846
+ id: id,
847
+ orderId: id,
848
+ cusId: user.id,
849
+ time: Date.now(),
850
+ status: 'INITIATED',
851
+ name: user.name,
852
+ email: user.email,
853
+ phone: user.phone,
854
+ amount: req.body.TXN_AMOUNT,
855
+ pname: req.body.PRODUCT_NAME,
856
+ returnUrl: req.body.RETURN_URL || '',
857
+ webhookUrl: req.body.WEBHOOK_URL || '',
858
+ extra: (req.body.EXTRA || ''),
859
+ clientId: req.body.CLIENT_ID || ''
860
+ };
861
+ const txn = await this.insertTransactionInDb(txnTask);
862
+ const urlData64 = this.encodeTxnDataForUrl(JSON.stringify({
863
+ NAME: txn.name,
864
+ EMAIL: txn.email,
865
+ MOBILE_NO: txn.phone,
866
+ ORDER_ID: txn.orderId,
867
+ RETURN_URL: txn.returnUrl,
868
+ WEBHOOK_URL: txn.webhookUrl,
869
+ TXN_AMOUNT: txn.amount,
870
+ PRODUCT_NAME: txn.pname,
871
+ clientId: txn.clientId
872
+ }));
873
+ txn.payurl = config.host_url + '/' + config.path_prefix + '/init?to=' + urlData64;
874
+ res.send(txn);
875
+ }
876
+ catch (err) {
877
+ console.log(err);
878
+ res.redirect('');
879
+ }
880
+ }
881
+ ;
882
+ async createTxnToken(req, res) {
883
+ return this.createTxn(req, res);
884
+ }
885
+ ;
886
+ // optional user
887
+ async getTransactions(req, res) {
888
+ // parameters can be from query or body
889
+ // MID, MOBILE_NO, PRODUCT_NAME, EMAIL, NAME, limit, offset
890
+ const params = { ...(req.query || {}), ...(req.body || {}) };
891
+ // Basic authz guard if caller supplies MID and it mismatches current config
892
+ if (params.MID && this.config.MID && params.MID !== this.config.MID) {
893
+ res.status(403).send({ message: 'MID mismatch' });
894
+ return;
895
+ }
896
+ // Build query map from incoming fields to db columns
897
+ const query = {};
898
+ const fieldMap = {
899
+ MOBILE_NO: 'phone',
900
+ PRODUCT_NAME: 'pname',
901
+ EMAIL: 'email',
902
+ NAME: 'name',
903
+ ORDER_ID: 'orderId',
904
+ ORDERID: 'orderId',
905
+ STATUS: 'status',
906
+ email: 'email',
907
+ phone: 'phone',
908
+ name: 'name',
909
+ product_name: 'pname',
910
+ order_id: 'orderId',
911
+ status: 'status',
912
+ mobile_no: 'phone'
913
+ };
914
+ Object.keys(fieldMap).forEach((key) => {
915
+ if (params[key]) {
916
+ query[fieldMap[key]] = params[key];
917
+ }
918
+ });
919
+ // Pagination
920
+ const limit = Math.min(parseInt(params.limit, 10) || 20, 100);
921
+ const offset = Math.max(parseInt(params.offset, 10) || 0, 0);
922
+ try {
923
+ let transactions = [];
924
+ const all = await this.db.get(this.tableNames.TRANSACTION, query, {
925
+ sort: [{ field: 'time', order: 'desc' }]
926
+ });
927
+ const safeAll = Array.isArray(all) ? all : [];
928
+ transactions = safeAll.slice(offset, offset + limit);
929
+ res.send({
930
+ limit,
931
+ offset,
932
+ count: transactions.length,
933
+ transactions
934
+ });
935
+ }
936
+ catch (err) {
937
+ console.log('getTransactions error', err);
938
+ res.status(500).send({ message: 'Failed to fetch transactions', error: (err === null || err === void 0 ? void 0 : err.message) || 'unknown_error' });
939
+ }
940
+ }
941
+ async status(req, res) {
942
+ const config = this.config;
943
+ const callbacks = this.callbacks;
944
+ const payuInstance = this.payuInstance;
945
+ const openMoneyInstance = this.openMoneyInstance;
946
+ const razorPayInstance = this.razorPayInstance;
947
+ if (!req.body.ORDERID && req.query.ORDERID) {
948
+ req.body.ORDERID = req.query.ORDERID;
949
+ }
950
+ if (!req.body.ORDER_ID && req.query.ORDER_ID) {
951
+ req.body.ORDER_ID = req.query.ORDER_ID;
952
+ }
953
+ if (!req.body.ORDER_ID && req.body.ORDERID) {
954
+ req.body.ORDER_ID = req.body.ORDERID;
955
+ }
956
+ if (!req.body.ORDER_ID) {
957
+ res.status(400).send({ message: "Missing ORDER_ID" });
958
+ return;
959
+ }
960
+ const myquery = { orderId: req.body.ORDER_ID };
961
+ const orderData = await this.db.getOne(this.tableNames.TRANSACTION, myquery).catch((err) => {
962
+ res.send(err);
963
+ return null;
964
+ });
965
+ if (!orderData) {
966
+ if (!res.headersSent) {
967
+ res.send({ message: "Order Not Found or not initiated yet!", ORDER_ID: req.body.ORDER_ID });
968
+ }
969
+ return;
970
+ }
971
+ if (orderData.status === "INITIATED") {
972
+ const params = {};
973
+ params["MID"] = config.MID;
974
+ params["ORDERID"] = req.body.ORDER_ID;
975
+ const onStatusUpdate = async (paytmResponse) => {
976
+ if (paytmResponse.TXNID && paytmResponse.TXNID.length > 4) {
977
+ orderData.status = paytmResponse.STATUS;
978
+ orderData.extra = JSON.stringify(paytmResponse);
979
+ try {
980
+ await this.db.update(this.tableNames.TRANSACTION, myquery, orderData);
981
+ }
982
+ catch (err) {
983
+ res.send({ message: "Error Occured !", ORDERID: paytmResponse.ORDERID, TXNID: paytmResponse.TXNID });
984
+ return;
985
+ }
986
+ if (callbacks && typeof callbacks.onFinish === 'function') {
987
+ callbacks.onFinish(req.body.ORDER_ID, orderData);
988
+ }
989
+ res.send(paytmResponse);
990
+ }
991
+ else {
992
+ res.send(orderData);
993
+ }
994
+ };
995
+ if (config.paytm_url) {
996
+ const paytmResponse = await this.getStatusFromPaytm(params, req.body.ORDER_ID);
997
+ await onStatusUpdate(paytmResponse);
998
+ }
999
+ else if (config.razor_url) {
1000
+ let result = await razorPayInstance.orders.fetch(req.body.ORDER_ID);
1001
+ result.ORDERID = req.body.ORDER_ID;
1002
+ if (result.status == 'paid' && result.amount_due == 0) {
1003
+ result.STATUS = 'TXN_SUCCESS';
1004
+ let payments = await razorPayInstance.orders.fetchPayments(req.body.ORDER_ID);
1005
+ payments.items.forEach((item) => {
1006
+ if (item.status == 'captured') {
1007
+ result.TXNID = item.id;
1008
+ }
1009
+ });
1010
+ result.payments = payments;
1011
+ await onStatusUpdate(result);
1012
+ }
1013
+ else {
1014
+ res.send(orderData);
1015
+ }
1016
+ }
1017
+ else if (config.payu_url) {
1018
+ let result = await payuInstance.getPaymentStatus(req.body.ORDER_ID);
1019
+ if (result && result.transaction_details && result.transaction_details[req.body.ORDER_ID]) {
1020
+ let txn = result.transaction_details[req.body.ORDER_ID];
1021
+ let status = 'TXN_FAILURE';
1022
+ if (txn.status == 'success') {
1023
+ status = 'TXN_SUCCESS';
1024
+ }
1025
+ else if (txn.status == 'pending') {
1026
+ status = 'TXN_PENDING';
1027
+ }
1028
+ await onStatusUpdate({
1029
+ STATUS: status,
1030
+ ORDERID: req.body.ORDER_ID,
1031
+ TXNID: txn.mihpayid || txn.txnid,
1032
+ payu: txn
1033
+ });
1034
+ }
1035
+ else {
1036
+ res.send(orderData);
1037
+ }
1038
+ }
1039
+ else if (config.open_money_url) {
1040
+ let extras = JSON.parse(orderData.extra);
1041
+ if (!extras || !extras.layer_pay_token_id) {
1042
+ res.status(500);
1043
+ res.send({ message: 'An unexpected error occured. No payment token exists' });
1044
+ return;
1045
+ }
1046
+ let result = await openMoneyInstance.getPaymentStatus(extras.layer_pay_token_id);
1047
+ result = JSON.parse(result);
1048
+ result.ORDERID = req.body.ORDER_ID;
1049
+ if (result.status == 'paid' || result.status == 'captured') {
1050
+ result.STATUS = 'TXN_SUCCESS';
1051
+ result.TXNID = result.id;
1052
+ await onStatusUpdate(result);
1053
+ }
1054
+ else if (result.status == 'pending' || result.status == 'attempted') {
1055
+ result.STATUS = 'TXN_PENDING';
1056
+ result.TXNID = result.id;
1057
+ await onStatusUpdate(result);
1058
+ }
1059
+ // else if (result.status == 'failed' || result.status == 'cancelled') {
1060
+ // result.STATUS = 'TXN_FAILED'
1061
+ // result.TXNID = result.id
1062
+ // onStatusUpdate(result)
1063
+ // }
1064
+ else {
1065
+ res.send(orderData);
1066
+ }
1067
+ }
1068
+ }
1069
+ else {
1070
+ res.send(orderData);
1071
+ }
1072
+ }
1073
+ async getStatusFromPaytm(params, orderId) {
1074
+ const checksum = await this.generateChecksum(params);
1075
+ try {
1076
+ const resp = await axios_1.default.post(`${this.config.paytm_url}/order/status`, { MID: this.config.MID, ORDERID: orderId, CHECKSUMHASH: checksum });
1077
+ if (resp.status === 200) {
1078
+ return resp.data;
1079
+ }
1080
+ console.log('ERROR:::', resp.status, '\n', resp.data);
1081
+ return { message: 'Error Occured !', ORDERID: orderId };
1082
+ }
1083
+ catch (err) {
1084
+ console.log('ERROR:::', err);
1085
+ return { message: 'Error Occured !', ORDERID: orderId };
1086
+ }
1087
+ }
1088
+ }
1089
+ exports.PaymentController = PaymentController;