node-paytmpg 7.1.1 → 7.1.3

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
 
@@ -238,21 +238,20 @@ class OpenMoney {
238
238
  });
239
239
  }
240
240
  renderProcessingPage(params, pmttoken, res, loadingSVG) {
241
+ const headScript = `<script src="${this.config.script_url}"></script>`;
242
+ const bodyScript = `<script>triggerLayer();</script>`;
243
+ const html = require('../htmlhelper').buildProcessingPageHtml(pmttoken.html, loadingSVG, 'Merchant Checkout Page', headScript, bodyScript);
241
244
  res.writeHead(200, { 'Content-Type': 'text/html' });
242
- res.write(`<html><head><title>Merchant Checkout Page</title>\n <script src="${this.config.script_url}"></script>\n </head><body><center><h1>Processing ! Please do not refresh this page...</h1><br>${pmttoken.html}<br><br>${loadingSVG}</center><script>triggerLayer();</script></body></html>`);
245
+ res.write(html);
243
246
  res.end();
244
247
  }
245
248
  renderError(params, error, res) {
246
249
  console.log('ERROR:::', error, '\n');
247
250
  res.status(500);
248
- let form_fields = '';
249
- const errorResp = { TXNID: 'na', STATUS: 'TXN_FAILURE', CANCELLED: 'cancelled', ORDERID: params['ORDER_ID'] };
250
- for (const x in errorResp) {
251
- form_fields += "<input type='hidden' name='" + x + "' value='" + errorResp[x] + "' >";
252
- }
253
- form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + params['CHECKSUM'] + "' >";
251
+ const errorResp = { TXNID: 'na', STATUS: 'TXN_FAILURE', CANCELLED: 'cancelled', ORDERID: params['ORDER_ID'], CHECKSUMHASH: params['CHECKSUM'] };
252
+ const html = require('../htmlhelper').buildAutoPostFormHtml(params['CALLBACK_URL'], errorResp);
254
253
  res.writeHead(200, { 'Content-Type': 'text/html' });
255
- res.write(`<html>\n\n <head>\n <title>Merchant Checkout Error</title>\n </head>\n \n <body>\n <center>\n <h1>Something went wrong. Please wait you will be redirected automatically...</h1>\n </center>\n <form method="post" action="${params['CALLBACK_URL']}" name="f1">${form_fields}</form>\n <script type="text/javascript">document.f1.submit();</script>\n </body>\n \n </html>`);
254
+ res.write(html);
256
255
  res.end();
257
256
  }
258
257
  }
@@ -175,40 +175,25 @@ class PayU {
175
175
  return this.postCommand('verify_payment', transactionId);
176
176
  }
177
177
  renderProcessingPage(params, paymentReq, res, loadingSVG) {
178
+ // delegate HTML construction to htmlhelper's builder (keeps behavior identical)
179
+ const html = require('../htmlhelper').buildProcessingPageHtml(paymentReq.html, loadingSVG);
178
180
  res.writeHead(200, { 'Content-Type': 'text/html' });
179
- res.write(`<html><head><title>Merchant Checkout Page</title></head><body><center><h1>Processing ! Please do not refresh this page...</h1><br>${paymentReq.html}<br><br>${loadingSVG}</center></body></html>`);
181
+ res.write(html);
180
182
  res.end();
181
183
  }
182
184
  renderError(params, error, res) {
183
185
  console.log('ERROR:::', error, '\n');
184
186
  res.status(500);
185
- let formFields = '';
186
187
  const errorResp = {
187
188
  TXNID: 'na',
188
189
  STATUS: 'TXN_FAILURE',
189
190
  CANCELLED: 'cancelled',
190
191
  ORDERID: params.ORDER_ID,
192
+ CHECKSUMHASH: params.CHECKSUM || ''
191
193
  };
192
- Object.keys(errorResp).forEach((key) => {
193
- formFields += `<input type='hidden' name='${key}' value='${errorResp[key]}' >`;
194
- });
195
- formFields += `<input type='hidden' name='CHECKSUMHASH' value='${params.CHECKSUM || ''}' >`;
194
+ const html = require('../htmlhelper').buildAutoPostFormHtml(params.CALLBACK_URL, errorResp);
196
195
  res.writeHead(200, { 'Content-Type': 'text/html' });
197
- res.write(`<html>
198
-
199
- <head>
200
- <title>Merchant Checkout Error</title>
201
- </head>
202
-
203
- <body>
204
- <center>
205
- <h1>Something went wrong. Please wait you will be redirected automatically...</h1>
206
- </center>
207
- <form method='post' action='${params.CALLBACK_URL}' name='f1'>${formFields}</form>
208
- <script type='text/javascript'>document.f1.submit();</script>
209
- </body>
210
-
211
- </html>`);
196
+ res.write(html);
212
197
  res.end();
213
198
  }
214
199
  processWebhook(req, res, updateTransaction) {
@@ -64,8 +64,9 @@ http.createServer(function (req, res) {
64
64
  form_fields += "<input type='hidden' name='" + x + "' value='" + params[x] + "' >";
65
65
  }
66
66
  form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + checksum + "' >";
67
+ const html = require('../htmlhelper').buildAutoPostFormHtml(txn_url, Object.assign({}, params, { CHECKSUMHASH: checksum }), 'Merchant Checkout Page');
67
68
  res.writeHead(200, { 'Content-Type': 'text/html' });
68
- res.write('<html><head><title>Merchant Checkout Page</title></head><body><center><h1>Please do not refresh this page...</h1></center><form method="post" action="' + txn_url + '" name="f1">' + form_fields + '</form><script type="text/javascript">document.f1.submit();</script></body></html>');
69
+ res.write(html);
69
70
  res.end();
70
71
  });
71
72
  break;
@@ -115,8 +116,9 @@ http.createServer(function (req, res) {
115
116
  for (const x in _result) {
116
117
  html += x + ' => ' + _result[x] + '<br/>';
117
118
  }
119
+ const out = require('../htmlhelper').buildProcessingPageHtml(html, '', 'Callback Response');
118
120
  res.writeHead(200, { 'Content-Type': 'text/html' });
119
- res.write(html);
121
+ res.write(out);
120
122
  res.end();
121
123
  });
122
124
  });
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderView = renderView;
4
+ exports.buildAutoPostFormHtml = buildAutoPostFormHtml;
5
+ exports.sendAutoPostForm = sendAutoPostForm;
6
+ exports.buildProcessingPageHtml = buildProcessingPageHtml;
7
+ exports.renderProcessingPage = renderProcessingPage;
8
+ exports.renderPaytmJsCheckout = renderPaytmJsCheckout;
9
+ exports.renderRazorpayCheckout = renderRazorpayCheckout;
10
+ const paytm_1 = require("./adapters/paytm");
11
+ function wantsJson(req) {
12
+ // Return true only when the caller EXPLICITLY sets Accept to only `application/json`.
13
+ // Examples that return true: "application/json" or "application/json; q=1"
14
+ // Examples that return false: "application/json, */*", "text/html", missing header, etc.
15
+ const hdr = String((req && req.headers && req.headers.accept) || '').trim().toLowerCase();
16
+ if (!hdr)
17
+ return false;
18
+ const types = hdr.split(',').map(t => t.split(';')[0].trim()).filter(Boolean);
19
+ return types.length > 0 && types.every(t => t === 'application/json');
20
+ }
21
+ function renderView(req, res, viewFile, data) {
22
+ if (wantsJson(req)) {
23
+ return res.json(data);
24
+ }
25
+ return res.render(viewFile, data);
26
+ }
27
+ function buildAutoPostFormHtml(action, fields, title = 'Merchant Checkout Error') {
28
+ const inputs = Object.keys(fields || {}).map((k) => {
29
+ const v = fields[k] === undefined || fields[k] === null ? '' : String(fields[k]);
30
+ return `<input type='hidden' name='${k}' value='${v}' >`;
31
+ }).join('');
32
+ return `<!doctype html><html><head><meta charset="utf-8"><title>${title}</title></head><body><center><h1>Something went wrong. Please wait you will be redirected automatically...</h1></center><form method="post" action="${action}" name="f1">${inputs}</form><script type="text/javascript">document.f1.submit();</script></body></html>`;
33
+ }
34
+ function sendAutoPostForm(req, res, action, fields) {
35
+ if (wantsJson(req)) {
36
+ // send dynamic content as JSON instead of embedding in an HTML form
37
+ return res.status(res.statusCode || 200).json({ action, fields });
38
+ }
39
+ const html = buildAutoPostFormHtml(action, fields);
40
+ return res.status(200).contentType('text/html').send(html);
41
+ }
42
+ function buildProcessingPageHtml(innerHtml, loadingSVG = '', title = 'Merchant Checkout Page', headScripts = '', bodyScripts = '') {
43
+ return `<!doctype html><html><head><meta charset="utf-8"><title>${title}</title>${headScripts}</head><body><center><h1>Processing ! Please do not refresh this page...</h1><br>${innerHtml}<br><br>${loadingSVG}</center>${bodyScripts}</body></html>`;
44
+ }
45
+ function renderProcessingPage(req, res, innerHtml, loadingSVG = '', headScripts = '', bodyScripts = '') {
46
+ if (wantsJson(req)) {
47
+ return res.json({ provider: 'processing', html: innerHtml, loadingSVG, headScripts, bodyScripts });
48
+ }
49
+ const html = buildProcessingPageHtml(innerHtml, loadingSVG, 'Merchant Checkout Page', headScripts, bodyScripts);
50
+ return res.status(200).contentType('text/html').send(html);
51
+ }
52
+ function renderPaytmJsCheckout(req, res, paytmJsToken, config) {
53
+ if (wantsJson(req)) {
54
+ // return the dynamic payload which would otherwise be embedded into the generated HTML
55
+ return res.json({ provider: 'paytm', token: paytmJsToken });
56
+ }
57
+ const html = (0, paytm_1.createPaytmJsCheckoutHtml)(paytmJsToken, config);
58
+ return res.send(html);
59
+ }
60
+ function renderRazorpayCheckout(req, res, params, config, loadingSVG) {
61
+ const options = {
62
+ key: String(config.KEY),
63
+ amount: Number(params['TXN_AMOUNT']) * 100,
64
+ currency: 'INR',
65
+ name: params['PRODUCT_NAME'],
66
+ description: `Order # ${params['ORDER_ID']}`,
67
+ image: config.logo,
68
+ order_id: params['ORDER_ID'],
69
+ callback_url: params['CALLBACK_URL'],
70
+ prefill: {
71
+ name: params['NAME'],
72
+ email: params['EMAIL'],
73
+ contact: params['MOBILE_NO']
74
+ },
75
+ theme: {
76
+ color: config.theme_color
77
+ }
78
+ };
79
+ if (wantsJson(req)) {
80
+ return res.json({ provider: 'razorpay', options, failForm: { action: params['CALLBACK_URL'], fields: { razorpay_order_id: params['ORDER_ID'] } }, loadingSVG });
81
+ }
82
+ const fail = `<div style="display:none"><form method="post" action="${params['CALLBACK_URL']}" id="fail"><input name="razorpay_order_id" value="${params['ORDER_ID']}" hidden="true"/></form></div>`;
83
+ const scriptOptions = `
84
+ <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
85
+ <script>
86
+ var options = ${JSON.stringify(options, null, 4)};
87
+ options.modal = options.modal || {};
88
+ options.modal.ondismiss = function(){ document.getElementById('fail').submit(); };
89
+ var rzp1 = new Razorpay(options);
90
+ rzp1.open();
91
+ </script>`;
92
+ const html = `<!doctype html><html><head><title>Merchant Checkout Page</title></head><body><center><h1>Processing ! Please do not refresh this page...</h1><br>${scriptOptions}<br>${fail}<br>${loadingSVG}</center></body></html>`;
93
+ return res.status(200).contentType('text/html').send(html);
94
+ }
@@ -49,7 +49,7 @@ const payu_1 = __importDefault(require("./adapters/payu"));
49
49
  const user_controller_1 = require("./user.controller");
50
50
  const utils_1 = require("../utils/utils");
51
51
  const loadingsvg_1 = require("./static/loadingsvg");
52
- const paytm_1 = require("./adapters/paytm");
52
+ const htmlhelper_1 = require("./htmlhelper");
53
53
  const IDLEN = 14;
54
54
  function makeid(length) {
55
55
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@@ -178,7 +178,7 @@ class PaymentController {
178
178
  }
179
179
  home(req, res) {
180
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);
181
+ return (0, htmlhelper_1.renderView)(req, res, this.viewPath + "home.hbs", package_json_1.default);
182
182
  }
183
183
  async init(req, res) {
184
184
  var _a;
@@ -273,114 +273,36 @@ class PaymentController {
273
273
  paytmJsToken.TXN_AMOUNT = params['TXN_AMOUNT'];
274
274
  paytmJsToken.MID = params['MID'];
275
275
  paytmJsToken.CALLBACK_URL = params['CALLBACK_URL'];
276
- return res.send((0, paytm_1.createPaytmJsCheckoutHtml)(paytmJsToken, this.config));
276
+ return (0, htmlhelper_1.renderPaytmJsCheckout)(req, res, paytmJsToken, this.config);
277
277
  }
278
278
  else {
279
279
  console.log('ERROR:::', resp.status, '\n', body);
280
280
  res.status(500);
281
- var form_fields = '';
282
- let errorResp = {
281
+ const errorResp = {
283
282
  TXNID: 'na',
284
283
  STATUS: 'TXN_FAILURE',
285
284
  CANCELLED: 'cancelled',
286
- ORDERID: params['ORDER_ID']
285
+ ORDERID: params['ORDER_ID'],
286
+ CHECKSUMHASH: checksum
287
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();
288
+ return (0, htmlhelper_1.sendAutoPostForm)(req, res, params['CALLBACK_URL'], errorResp);
309
289
  }
310
290
  }
311
291
  catch (err) {
312
292
  console.log('ERROR:::', err);
313
293
  res.status(500);
314
- var form_fields = '';
315
- let errorResp = {
294
+ const errorResp = {
316
295
  TXNID: 'na',
317
296
  STATUS: 'TXN_FAILURE',
318
297
  CANCELLED: 'cancelled',
319
- ORDERID: params['ORDER_ID']
298
+ ORDERID: params['ORDER_ID'],
299
+ CHECKSUMHASH: checksum
320
300
  };
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();
301
+ return (0, htmlhelper_1.sendAutoPostForm)(req, res, params['CALLBACK_URL'], errorResp);
342
302
  }
343
303
  }
344
304
  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();
305
+ return (0, htmlhelper_1.renderRazorpayCheckout)(req, res, params, this.config, loadingsvg_1.LoadingSVG);
384
306
  }
385
307
  else if (this.config.payu_url) {
386
308
  const payuRequest = this.payuInstance.generatePaymentRequest(params);
@@ -426,7 +348,7 @@ class PaymentController {
426
348
  params['NAME'] = txnData.name;
427
349
  params['PRODUCT_NAME'] = txnData.pname;
428
350
  const showConfirmation = (checksum = '') => {
429
- res.render(vp + "init.hbs", {
351
+ return (0, htmlhelper_1.renderView)(req, res, vp + "init.hbs", {
430
352
  path_prefix: config.path_prefix,
431
353
  action: "/" + config.path_prefix + "/init",
432
354
  readonly: 'readonly',
@@ -533,7 +455,7 @@ class PaymentController {
533
455
  }
534
456
  }
535
457
  else {
536
- res.render(this.viewPath + "init.hbs", {
458
+ return (0, htmlhelper_1.renderView)(req, res, this.viewPath + "init.hbs", {
537
459
  path_prefix: this.config.path_prefix,
538
460
  action: "/" + this.config.path_prefix + "/init",
539
461
  readonly: '',
@@ -615,7 +537,7 @@ class PaymentController {
615
537
  const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
616
538
  return res.redirect(`${returnUrl}${separator}status=${objForUpdate.status}&ORDERID=${objForUpdate.orderId}&TXNID=${objForUpdate.txnId}`);
617
539
  }
618
- res.render(vp + "result.hbs", {
540
+ (0, htmlhelper_1.renderView)(req, res, vp + "result.hbs", {
619
541
  path_prefix: config.path_prefix,
620
542
  ...objForUpdate
621
543
  });
@@ -654,7 +576,7 @@ class PaymentController {
654
576
  const separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
655
577
  return res.redirect(`${returnUrl}${separator}status=${objForUpdate.status}&ORDERID=${objForUpdate.orderId}&TXNID=${objForUpdate.txnId}`);
656
578
  }
657
- res.render(vp + "result.hbs", {
579
+ (0, htmlhelper_1.renderView)(req, res, vp + "result.hbs", {
658
580
  path_prefix: config.path_prefix,
659
581
  ...objForUpdate
660
582
  });
@@ -700,6 +622,12 @@ class PaymentController {
700
622
  }
701
623
  }
702
624
  else if (config.razor_url) {
625
+ let orderid = req.body.razorpay_order_id || req.query.ORDERID || req.query.order_id;
626
+ let liveResonse = null;
627
+ if (orderid) {
628
+ liveResonse = await this.razorPayInstance.orders.fetch(orderid).catch(() => null);
629
+ req.body.extras = liveResonse;
630
+ }
703
631
  if (req.body.razorpay_payment_id) {
704
632
  result = checksum_1.default.checkRazorSignature(req.body.razorpay_order_id, req.body.razorpay_payment_id, config.SECRET, req.body.razorpay_signature);
705
633
  if (result) {
@@ -713,7 +641,7 @@ class PaymentController {
713
641
  const orderId = JSON.parse(req.body.error.metadata).order_id;
714
642
  req.body.razorpay_order_id = orderId;
715
643
  }
716
- req.body.STATUS = 'TXN_FAILURE';
644
+ req.body.STATUS = (liveResonse === null || liveResonse === void 0 ? void 0 : liveResonse.attempts) ? 'TXN_FAILURE' : 'CANCELLED';
717
645
  req.body.ORDERID = req.body.razorpay_order_id || req.query.order_id;
718
646
  isCancelled = true;
719
647
  }
@@ -28,7 +28,7 @@ class NPUserController {
28
28
  objForUpdate.phone = userData.phone;
29
29
  if (userData.name && userData.name.length > 2)
30
30
  objForUpdate.name = userData.name;
31
- const newvalues = { $set: objForUpdate };
31
+ const newvalues = objForUpdate;
32
32
  try {
33
33
  await this.db.update(this.tableName, myquery, newvalues);
34
34
  return objForUpdate;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-paytmpg",
3
- "version": "7.1.1",
3
+ "version": "7.1.3",
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.1.1",
3
+ "version": "7.1.3",
4
4
  "description": "Payment Gateway Integration using NodeJS",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {