node-paytmpg 5.3.2 → 6.4.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.
@@ -6,9 +6,11 @@ var IDLEN = 10;
6
6
  var nodeBase64 = require('nodejs-base64-converter');
7
7
  var RazorPay = require('razorpay');
8
8
  var OpenMoney = require('./adapters/open_money')
9
+ var PayU = require('./adapters/payu')
9
10
  const PaytmChecksum = require('./checksum/PaytmChecksum.js');
10
11
  const { stat } = require('fs');
11
12
  const { config } = require('process');
13
+ const path = require('path');
12
14
 
13
15
  let loadingSVG = ` <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;background:#fff;display:block;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
14
16
  <g transform="rotate(0 50 50)">
@@ -76,12 +78,17 @@ module.exports = function (app, callbacks) {
76
78
 
77
79
  var razorPayInstance;
78
80
  var openMoneyInstance = new OpenMoney(config);
81
+ var payuInstance = new PayU(config)
79
82
 
80
- if (config.razor_url)
83
+ if (config.razor_url) {
81
84
  razorPayInstance = new RazorPay({ key_id: config.KEY, key_secret: config.SECRET })
85
+ }
82
86
  if (config.open_money_url) {
83
87
  openMoneyInstance = new OpenMoney(config);
84
88
  }
89
+ if (config.payu_url) {
90
+ payuInstance = new PayU(config);
91
+ }
85
92
 
86
93
  let usingMultiDbOrm = false;
87
94
  if (config.db_url) {
@@ -89,7 +96,22 @@ module.exports = function (app, callbacks) {
89
96
  usingMultiDbOrm = false;
90
97
 
91
98
  } else if (app.multidborm) {
92
- Transaction = require('../models/np_multidbplugin.js')('nptransactions', app.multidborm);
99
+ const sample = {
100
+ orderId: "string",
101
+ cusId: "string",
102
+ time: 1770051201752,
103
+ timeStamp: 1770051201752,
104
+ status: "string",
105
+ name: "string",
106
+ email: "string",
107
+ phone: "string",
108
+ amount: 1,
109
+ pname: "string",
110
+ extra: "stringlarge",
111
+ TXNID: "27118670199",
112
+ returnUrl: "string"
113
+ }
114
+ Transaction = require('../models/np_multidbplugin.js')('nptransactions', app.multidborm, sample);
93
115
  Transaction.db = app.multidborm;
94
116
  Transaction.modelname = 'nptransactions'
95
117
  Transaction.idFieldName = 'orderId'
@@ -111,7 +133,10 @@ module.exports = function (app, callbacks) {
111
133
  return text;
112
134
  }
113
135
 
114
- var vp = __dirname + config.view_path
136
+ const viewRoot = config.templateDir
137
+ ? config.templateDir
138
+ : path.join(__dirname, '..', 'views');
139
+ var vp = config.resolved_view_path || (viewRoot.endsWith(path.sep) ? viewRoot : viewRoot + path.sep)
115
140
 
116
141
  module.home = (req, res) => {
117
142
 
@@ -123,25 +148,25 @@ module.exports = function (app, callbacks) {
123
148
 
124
149
  module.init = async function (req, res) {
125
150
 
126
- if (!req.body.ORDER_ID && !req.body.EMAIL && req.query.to) {
127
-
151
+ if (!req.body.ORDER_ID && !req.body.EMAIL && req.query?.to) {
128
152
  let toData = JSON.parse(nodeBase64.decode(req.query.to));
129
153
  req.body.NAME = toData.NAME
130
154
  req.body.EMAIL = toData.EMAIL
155
+ req.body.TXN_AMOUNT = toData.TXN_AMOUNT
131
156
  req.body.MOBILE_NO = toData.MOBILE_NO
132
- req.body.ORDER_ID = toData.ORDER_ID
157
+ req.body.ORDER_ID = toData.ORDER_ID || toData.ORDERID
158
+ req.body.PRODUCT_NAME = toData.PRODUCT_NAME
159
+ req.body.RETURN_URL = toData.RETURN_URL
133
160
  }
134
161
 
135
162
  sanitizeRequest(req.body);
136
163
  let gotAllParams = true;
137
-
164
+ let checkedFields = ['TXN_AMOUNT', 'PRODUCT_NAME', 'MOBILE_NO', 'NAME', 'EMAIL']
138
165
  if (req.body !== undefined) {
139
- let checks = [req.body.TXN_AMOUNT, req.body.PRODUCT_NAME,
140
- req.body.MOBILE_NO, req.body.NAME, req.body.EMAIL]
141
166
 
142
- for (var i = 0; i < checks.length; i++) {
167
+ for (var i = 0; i < checkedFields.length; i++) {
143
168
 
144
- if (checks[i] === undefined) {
169
+ if (req.body[checkedFields[i]] === undefined) {
145
170
  gotAllParams = false;
146
171
  break;
147
172
  }
@@ -165,7 +190,7 @@ module.exports = function (app, callbacks) {
165
190
  params['WEBSITE'] = req.body.WEBSITE;
166
191
  params['CHANNEL_ID'] = req.body.CHANNEL_ID;
167
192
  params['INDUSTRY_TYPE_ID'] = req.body.INDUSTRY_TYPE_ID;
168
- params['ORDER_ID'] = req.body.ORDER_ID;
193
+ params['ORDER_ID'] = req.body.ORDER_ID || req.body.ORDERID;
169
194
  params['CUST_ID'] = req.body.CUST_ID;
170
195
  params['TXN_AMOUNT'] = req.body.TXN_AMOUNT;
171
196
  params['CALLBACK_URL'] = req.body.CALLBACK_URL + "?order_id=" + req.body.ORDER_ID;
@@ -430,6 +455,10 @@ module.exports = function (app, callbacks) {
430
455
  res.end();
431
456
 
432
457
  }
458
+ else if (config.payu_url) {
459
+ const payuRequest = payuInstance.generatePaymentRequest(params);
460
+ payuInstance.renderProcessingPage(params, payuRequest, res, loadingSVG);
461
+ }
433
462
  else if (config.open_money_url) {
434
463
  try {
435
464
  let pmttoken = await openMoneyInstance.generatePaymentToken(params);
@@ -453,8 +482,9 @@ module.exports = function (app, callbacks) {
453
482
  openMoneyInstance.renderError(params, e, res)
454
483
  }
455
484
  }
456
- if (callbacks !== undefined)
485
+ if (callbacks && typeof callbacks.onStart === 'function') {
457
486
  callbacks.onStart(params['ORDER_ID'], params);
487
+ }
458
488
  }
459
489
  else if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2) || gotAllParams) {
460
490
 
@@ -487,7 +517,7 @@ module.exports = function (app, callbacks) {
487
517
  let showConfirmation =
488
518
  function (err, checksum) {
489
519
  res.render(vp + "init.hbs", {
490
- action: '',
520
+ action:"/"+ config.path_prefix+"/init",
491
521
  readonly: 'readonly',
492
522
  BUTTON: 'Pay',
493
523
  NAME: params['NAME'],
@@ -511,6 +541,8 @@ module.exports = function (app, callbacks) {
511
541
  checksum_lib.genchecksum(params, config.KEY, showConfirmation);
512
542
  else if (config.razor_url) {
513
543
  showConfirmation()
544
+ } else if (config.payu_url) {
545
+ showConfirmation()
514
546
  } else if (config.open_money_url) {
515
547
  showConfirmation()
516
548
  }
@@ -519,49 +551,55 @@ module.exports = function (app, callbacks) {
519
551
 
520
552
 
521
553
 
522
- if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)) {
523
554
 
555
+ function onOrder(orderId) {
524
556
 
525
- var myquery = { orderId: req.body.ORDER_ID };
526
- Transaction.findOne(myquery, function (err, orderData) {
557
+ var txnTask = new Transaction({
558
+ orderId: orderId,
559
+ cusId: user.id,
560
+ time: Date.now(),
561
+ timeStamp: Date.now(),
562
+ status: 'INITIATED',
563
+ name: user.name,
564
+ email: user.email,
565
+ phone: user.phone,
566
+ amount: req.body.TXN_AMOUNT,
567
+ pname: req.body.PRODUCT_NAME,
568
+ extra: '',
569
+ returnUrl: req.body.RETURN_URL || ''
570
+ });
527
571
 
528
- onTxn(orderData);
529
-
530
- }, usingMultiDbOrm ? Transaction : undefined);
572
+ return txnTask.save().then(onTxn)
573
+ .catch(err => {
531
574
 
575
+ console.log(err)
576
+ if (req.body.RETURN_URL) {
577
+ res.redirect(req.body.RETURN_URL + "?status=failed")
578
+ return;
579
+ }
580
+ res.redirect('')
581
+ });
582
+ }
532
583
 
584
+ if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)) {
585
+ var myquery = { orderId: req.body.ORDER_ID };
586
+ Transaction.findOne(myquery, function (err, orderData) {
587
+ if (err || (!orderData)) {
588
+ if (gotAllParams) {
589
+ console.log("Creating new order for ", req.body.ORDER_ID)
590
+ onOrder(req.body.ORDER_ID)
591
+ }
592
+ else {
593
+ res.send({ message: "Order Not Found or missing required data: " + checkedFields.join(", "), ORDERID: req.body.ORDER_ID })
594
+ }
595
+ }
596
+ else {
597
+ onTxn(orderData);
598
+ }
533
599
 
600
+ }, usingMultiDbOrm ? Transaction : undefined);
534
601
  }
535
602
  else {
536
-
537
-
538
- function onOrder(orderId) {
539
-
540
- var txnTask = new Transaction({
541
-
542
- orderId: orderId,
543
- cusId: user.id,
544
- time: Date.now(),
545
- timeStamp: Date.now(),
546
- status: 'INITIATED',
547
- name: user.name,
548
- email: user.email,
549
- phone: user.phone,
550
- amount: req.body.TXN_AMOUNT,
551
- pname: req.body.PRODUCT_NAME,
552
- extra: ''
553
-
554
- });
555
-
556
- txnTask.save().then(onTxn)
557
- .catch(err => {
558
-
559
- console.log(err)
560
-
561
- res.redirect('')
562
- });
563
- }
564
-
565
603
  let orderId;
566
604
  if (config.paytm_url) {
567
605
  orderId = "pay_" + makeid(config.id_length || IDLEN)
@@ -588,6 +626,9 @@ module.exports = function (app, callbacks) {
588
626
  else if (config.open_money_url) {
589
627
  orderId = "pay_" + makeid(config.id_length || IDLEN)
590
628
  onOrder(orderId)
629
+ } else if (config.payu_url) {
630
+ orderId = "payu_" + makeid(config.id_length || IDLEN)
631
+ onOrder(orderId)
591
632
  }
592
633
 
593
634
 
@@ -608,7 +649,7 @@ module.exports = function (app, callbacks) {
608
649
 
609
650
  res.render(vp + "init.hbs", {
610
651
 
611
- action: '',
652
+ action:"/"+ config.path_prefix+"/init",
612
653
  readonly: '',
613
654
  check: true,
614
655
  BUTTON: 'Submit',
@@ -632,52 +673,96 @@ module.exports = function (app, callbacks) {
632
673
 
633
674
  }
634
675
 
635
- function updateTransaction(req, res) {
636
- var myquery = { orderId: req.body.ORDERID };
676
+ async function updateTransaction(req, res) {
677
+ var orderToFind = req.body.ORDERID || req.body.ORDER_ID || req.body.ORDERId || (req.query && req.query.order_id) || req.body.ORDER_ID;
678
+ var myquery = { orderId: orderToFind };
679
+
680
+ let objForUpdate = null;
681
+ try {
682
+ // try default
683
+ objForUpdate = await Transaction.findOne(myquery).catch(() => null);
684
+ // try id
685
+ if (!objForUpdate) objForUpdate = await Transaction.findOne({ id: orderToFind }).catch(() => null);
686
+ // try uppercase key
687
+ if (!objForUpdate) objForUpdate = await Transaction.findOne({ ORDERID: orderToFind }).catch(() => null);
688
+ } catch (e) {
689
+ // ignore lookup errors
690
+ objForUpdate = objForUpdate || null;
691
+ }
637
692
 
638
- Transaction.findOne(myquery, function (err, objForUpdate) {
693
+ let returnUrl = objForUpdate ? objForUpdate.returnUrl : null;
694
+ if (returnUrl == 'undefined') returnUrl = undefined;
639
695
 
640
- if (err) {
641
- res.send({ message: "Transaction Not Found !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
642
- return;
696
+ if (!objForUpdate) {
697
+ if (returnUrl) {
698
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
699
+ returnUrl = returnUrl + separator + 'status=FAILED&message=txn_not_found&ORDERID=' + req.body.ORDERID;
700
+ return res.redirect(returnUrl);
643
701
  }
644
- if (objForUpdate.status != ("INITIATED") && objForUpdate.status != ("TXN_PENDING") && objForUpdate.status != ("PENDING")) {
645
- objForUpdate.readonly = "readonly"
646
- objForUpdate.action = config.homepage
647
- res.render(vp + "result.hbs", objForUpdate);
648
- console.log("Transaction already processed ", req.body.ORDERID)
649
- // res.send({ message: "Transaction already processed", status: objForUpdate.status, ORDERID: objForUpdate.orderId, TXNID: objForUpdate.TXNID, TXNID: req.body.TXNID })
650
- return;
702
+ return res.send({ message: "Transaction Not Found !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID });
703
+ }
704
+
705
+ if (objForUpdate.status != ("INITIATED") && objForUpdate.status != ("TXN_PENDING") && objForUpdate.status != ("PENDING")) {
706
+ objForUpdate.readonly = "readonly";
707
+ objForUpdate.action = config.homepage;
708
+ if (returnUrl) {
709
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
710
+ returnUrl = returnUrl + separator + 'status=' + objForUpdate.status + '&ORDERID=' + objForUpdate.orderId + '&TXNID=' + objForUpdate.TXNID;
711
+ return res.redirect(returnUrl);
651
712
  }
652
- if (req.body.status == "paid" && !req.body.STATUS) {
653
- req.body.STATUS = "TXN_SUCCESS"
713
+ else {
714
+ return res.render(vp + "result.hbs", objForUpdate);
654
715
  }
655
- objForUpdate.status = req.body.STATUS;
656
- objForUpdate.TXNID = req.body.TXNID;
657
- objForUpdate.extra = JSON.stringify(req.body);
658
-
659
- var newvalues = { $set: objForUpdate };
660
- Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
716
+ }
661
717
 
662
- if (err) {
663
- res.send({ message: "Error Occured !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
664
- }
665
- else {
718
+ if (req.body.status == "paid" && !req.body.STATUS) req.body.STATUS = "TXN_SUCCESS";
719
+ objForUpdate.status = req.body.STATUS;
720
+ objForUpdate.TXNID = req.body.TXNID;
721
+ objForUpdate.extra = JSON.stringify(req.body);
666
722
 
667
- if (callbacks !== undefined)
668
- callbacks.onFinish(req.body.ORDERID, req.body);
669
- objForUpdate.readonly = "readonly"
670
- objForUpdate.action = config.homepage
671
- res.render(vp + "result.hbs", objForUpdate);
723
+ var newvalues = { $set: objForUpdate };
724
+ Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
725
+ if (err) {
726
+ if (returnUrl) {
727
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
728
+ returnUrl = returnUrl + separator + 'status=FAILED&message=update_error&ORDERID=' + req.body.ORDERID;
729
+ return res.redirect(returnUrl);
672
730
  }
673
- });
731
+ return res.send({ message: "Error Occured !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID });
732
+ }
674
733
 
675
- }, usingMultiDbOrm ? Transaction : undefined)
734
+ if (callbacks && typeof callbacks.onFinish === 'function') {
735
+ callbacks.onFinish(req.body.ORDERID, objForUpdate);
736
+ }
737
+ objForUpdate.readonly = "readonly";
738
+ objForUpdate.action = config.homepage;
739
+ if (returnUrl) {
740
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
741
+ returnUrl = returnUrl + separator + 'status=' + objForUpdate.status + '&ORDERID=' + objForUpdate.orderId + '&TXNID=' + objForUpdate.TXNID;
742
+ return res.redirect(returnUrl);
743
+ }
744
+ res.render(vp + "result.hbs", objForUpdate);
745
+ });
676
746
  }
677
747
 
678
748
  module.callback = async (req, res) => {
679
749
  console.log("request_data ", req.originalUrl, JSON.stringify(req.body))
680
750
 
751
+ // Normalize common order id and txn id field names (support ORDER_ID, ORDERID, etc.)
752
+ try {
753
+ if ((!req.body.ORDERID || req.body.ORDERID === '') && req.body.ORDER_ID) {
754
+ req.body.ORDERID = req.body.ORDER_ID;
755
+ }
756
+ if ((!req.body.TXNID || req.body.TXNID === '') && req.body.TXN_ID) {
757
+ req.body.TXNID = req.body.TXN_ID;
758
+ }
759
+ if ((!req.body.ORDERID || req.body.ORDERID === '') && req.query && req.query.order_id) {
760
+ req.body.ORDERID = req.query.order_id;
761
+ }
762
+ } catch (e) {
763
+ // ignore
764
+ }
765
+
681
766
  var result = false;
682
767
  let isCancelled = false;
683
768
  if (config.paytm_url) {
@@ -721,6 +806,16 @@ module.exports = function (app, callbacks) {
721
806
  isCancelled = true;
722
807
  }
723
808
  }
809
+ else if (config.payu_url) {
810
+ const payuRest = await payuInstance.verifyResult(req);
811
+ result = payuRest.valid;
812
+ req.body.STATUS = payuRest.STATUS;
813
+ req.body.TXNID = payuRest.TXNID;
814
+ req.body.ORDERID = payuRest.ORDERID || req.query.order_id;
815
+ req.body.extras = payuRest.data;
816
+ result = true;
817
+ isCancelled = payuRest.cancelled;
818
+ }
724
819
  else if (config.open_money_url) {
725
820
  let openRest = await openMoneyInstance.verifyResult(req);
726
821
  result = true;
@@ -806,6 +901,9 @@ module.exports = function (app, callbacks) {
806
901
  res.send({ message: "Unsupported event : " + req.body.event })
807
902
  }
808
903
  }
904
+ else if (config.payu_url) {
905
+ payuInstance.processWebhook(req, res, updateTransaction)
906
+ }
809
907
  else if (config.open_money_url) {
810
908
  openMoneyInstance.processWebhook(req, res, updateTransaction)
811
909
  }
@@ -832,6 +930,9 @@ module.exports = function (app, callbacks) {
832
930
  let order = await razorPayInstance.orders.create(options);
833
931
  id = order.id;
834
932
  }
933
+ else if (config.payu_url) {
934
+ id = "payu_" + makeid(config.id_length || IDLEN)
935
+ }
835
936
  else if (config.open_money_url) {
836
937
  id = "pay_" + makeid(config.id_length || IDLEN)
837
938
  }
@@ -847,6 +948,7 @@ module.exports = function (app, callbacks) {
847
948
  phone: user.phone,
848
949
  amount: req.body.TXN_AMOUNT,
849
950
  pname: req.body.PRODUCT_NAME,
951
+ returnUrl: req.body.RETURN_URL || '',
850
952
  extra: (req.body.EXTRA || '')
851
953
 
852
954
  });
@@ -857,7 +959,10 @@ module.exports = function (app, callbacks) {
857
959
  NAME: txn.name,
858
960
  EMAIL: txn.email,
859
961
  MOBILE_NO: txn.phone,
860
- ORDER_ID: txn.orderId
962
+ ORDER_ID: txn.orderId,
963
+ RETURN_URL: txn.returnUrl,
964
+ TXN_AMOUNT: txn.amount,
965
+ PRODUCT_NAME: txn.pname
861
966
  }))
862
967
 
863
968
  txn.payurl = config.host_url + '/' + config.path_prefix + '/init?to=' + urlData64;
@@ -889,6 +994,7 @@ module.exports = function (app, callbacks) {
889
994
  req.body.EMAIL = createTxnResult.email
890
995
  req.body.MOBILE_NO = createTxnResult.phone
891
996
  req.body.ORDER_ID = createTxnResult.orderId
997
+ req.body.RETURN_URL = createTxnResult.returnUrl
892
998
  module.init(req, {
893
999
  render: (renderPath, initResultRender) => {
894
1000
  // console.log(initResultRender)
@@ -968,8 +1074,9 @@ module.exports = function (app, callbacks) {
968
1074
  res.send({ message: "Error Occured !", ORDERID: paytmResponse.ORDERID, TXNID: paytmResponse.TXNID })
969
1075
  }
970
1076
  else {
971
- if (callbacks !== undefined)
1077
+ if (callbacks && typeof callbacks.onFinish === 'function') {
972
1078
  callbacks.onFinish(req.body.ORDER_ID, orderData);
1079
+ }
973
1080
  res.send(paytmResponse)
974
1081
  }
975
1082
  });
@@ -1002,6 +1109,28 @@ module.exports = function (app, callbacks) {
1002
1109
  res.send(orderData);
1003
1110
  }
1004
1111
  }
1112
+ else if (config.payu_url) {
1113
+ let result = await payuInstance.getPaymentStatus(req.body.ORDER_ID)
1114
+ if (result && result.transaction_details && result.transaction_details[req.body.ORDER_ID]) {
1115
+ let txn = result.transaction_details[req.body.ORDER_ID];
1116
+ let status = 'TXN_FAILURE'
1117
+ if (txn.status == 'success') {
1118
+ status = 'TXN_SUCCESS'
1119
+ }
1120
+ else if (txn.status == 'pending') {
1121
+ status = 'TXN_PENDING'
1122
+ }
1123
+ onStatusUpdate({
1124
+ STATUS: status,
1125
+ ORDERID: req.body.ORDER_ID,
1126
+ TXNID: txn.mihpayid || txn.txnid,
1127
+ payu: txn
1128
+ })
1129
+ }
1130
+ else {
1131
+ res.send(orderData);
1132
+ }
1133
+ }
1005
1134
  else if (config.open_money_url) {
1006
1135
  let extras = JSON.parse(orderData.extra)
1007
1136
  if (!extras || !extras.layer_pay_token_id) {