node-paytmpg 5.3.1 → 5.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.
@@ -1,1067 +1,1171 @@
1
- var packageInfo = require('../../package.json')
2
- const checksum_lib = require('./checksum/checksum.js');
3
- var request = require('request')
4
- var Transaction;
5
- var IDLEN = 10;
6
- var nodeBase64 = require('nodejs-base64-converter');
7
- var RazorPay = require('razorpay');
8
- var OpenMoney = require('./adapters/open_money')
9
- const PaytmChecksum = require('./checksum/PaytmChecksum.js');
10
- const { stat } = require('fs');
11
- const { config } = require('process');
12
-
13
- 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
- <g transform="rotate(0 50 50)">
15
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
16
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite"></animate>
17
- </rect>
18
- </g><g transform="rotate(30 50 50)">
19
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
20
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite"></animate>
21
- </rect>
22
- </g><g transform="rotate(60 50 50)">
23
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
24
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
25
- </rect>
26
- </g><g transform="rotate(90 50 50)">
27
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
28
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite"></animate>
29
- </rect>
30
- </g><g transform="rotate(120 50 50)">
31
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
32
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite"></animate>
33
- </rect>
34
- </g><g transform="rotate(150 50 50)">
35
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
36
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
37
- </rect>
38
- </g><g transform="rotate(180 50 50)">
39
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
40
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite"></animate>
41
- </rect>
42
- </g><g transform="rotate(210 50 50)">
43
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
44
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite"></animate>
45
- </rect>
46
- </g><g transform="rotate(240 50 50)">
47
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
48
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
49
- </rect>
50
- </g><g transform="rotate(270 50 50)">
51
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
52
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite"></animate>
53
- </rect>
54
- </g><g transform="rotate(300 50 50)">
55
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
56
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite"></animate>
57
- </rect>
58
- </g><g transform="rotate(330 50 50)">
59
- <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
60
- <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
61
- </rect>
62
- </g>
63
- </svg>`
64
-
65
- function sanitizeRequest(body) {
66
-
67
- if (body.amount)
68
- body.amount = parseFloat(body.amount);
69
- if (body.TXN_AMOUNT)
70
- body.amount = parseFloat(body.TXN_AMOUNT);
71
- }
72
-
73
- module.exports = function (app, callbacks) {
74
- var config = (app.get('np_config'))
75
- var useController = require('./np_user.controller.js')(app, callbacks);
76
-
77
- var razorPayInstance;
78
- var openMoneyInstance = new OpenMoney(config);
79
-
80
- if (config.razor_url)
81
- razorPayInstance = new RazorPay({ key_id: config.KEY, key_secret: config.SECRET })
82
- if (config.open_money_url) {
83
- openMoneyInstance = new OpenMoney(config);
84
- }
85
-
86
- let usingMultiDbOrm = false;
87
- if (config.db_url) {
88
- Transaction = require('../models/np_transaction.model.js');
89
- usingMultiDbOrm = false;
90
-
91
- } else if (app.multidborm) {
92
- Transaction = require('../models/np_multidbplugin.js')('nptransactions', app.multidborm);
93
- Transaction.db = app.multidborm;
94
- Transaction.modelname = 'nptransactions'
95
- Transaction.idFieldName = 'orderId'
96
- app.NPTransaction = Transaction;
97
- usingMultiDbOrm = true;
98
-
99
- }
100
-
101
- var module = {};
102
-
103
- var config = (app.get('np_config'))
104
- function makeid(length) {
105
- var text = "";
106
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
107
-
108
- for (var i = 0; i < length; i++)
109
- text += possible.charAt(Math.floor(Math.random() * possible.length));
110
-
111
- return text;
112
- }
113
-
114
- var vp = __dirname + config.view_path
115
-
116
- module.home = (req, res) => {
117
-
118
- packageInfo.repository.url = packageInfo.repository.url.replace('git+', '')
119
- res.render(vp + "home.hbs", packageInfo)
120
-
121
-
122
- }
123
-
124
- module.init = async function (req, res) {
125
-
126
- if (!req.body.ORDER_ID && !req.body.EMAIL && req.query.to) {
127
-
128
- let toData = JSON.parse(nodeBase64.decode(req.query.to));
129
- req.body.NAME = toData.NAME
130
- req.body.EMAIL = toData.EMAIL
131
- req.body.MOBILE_NO = toData.MOBILE_NO
132
- req.body.ORDER_ID = toData.ORDER_ID
133
- }
134
-
135
- sanitizeRequest(req.body);
136
- let gotAllParams = true;
137
-
138
- 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
-
142
- for (var i = 0; i < checks.length; i++) {
143
-
144
- if (checks[i] === undefined) {
145
- gotAllParams = false;
146
- break;
147
- }
148
-
149
- }
150
- }
151
- else {
152
- gotAllParams = false;
153
- }
154
-
155
- // console.log(req.body)
156
-
157
- if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)
158
- &&
159
- (req.body.CUST_ID !== undefined && req.body.CUST_ID.length > 2)) {
160
- // console.log('redirect')
161
- // console.log(req.body)
162
- var params = {};
163
-
164
- params['MID'] = req.body.MID;
165
- params['WEBSITE'] = req.body.WEBSITE;
166
- params['CHANNEL_ID'] = req.body.CHANNEL_ID;
167
- params['INDUSTRY_TYPE_ID'] = req.body.INDUSTRY_TYPE_ID;
168
- params['ORDER_ID'] = req.body.ORDER_ID;
169
- params['CUST_ID'] = req.body.CUST_ID;
170
- params['TXN_AMOUNT'] = req.body.TXN_AMOUNT;
171
- params['CALLBACK_URL'] = req.body.CALLBACK_URL + "?order_id=" + req.body.ORDER_ID;
172
- params['EMAIL'] = req.body.EMAIL;
173
- params['MOBILE_NO'] = req.body.MOBILE_NO;
174
- params['PRODUCT_NAME'] = req.body.PRODUCT_NAME;
175
- params['NAME'] = req.body.NAME;
176
-
177
- if (config.paytm_url) {
178
-
179
- let initTxnbody = {
180
- "requestType": "Payment",
181
- "mid": params['MID'],
182
- "websiteName": params['WEBSITE'],
183
- "orderId": params['ORDER_ID'],
184
- "callbackUrl": params['CALLBACK_URL'],
185
- "txnAmount": {
186
- "value": params['TXN_AMOUNT'],
187
- "currency": params['CURRENCY'] || "INR",
188
- },
189
- "userInfo": {
190
- "custId": params['CUST_ID'],
191
- "mobile": params['MOBILE_NO'],
192
- "firstName": params['NAME'],
193
- "email": params['EMAIL']
194
- }
195
- };
196
- if (config.mode) {
197
- initTxnbody["enablePaymentMode"] = JSON.parse(config.mode)
198
- }
199
-
200
- let checksum = await PaytmChecksum.generateSignature(JSON.stringify(initTxnbody), config.KEY)
201
- let initTxnUrl = config.paytm_url + `/theia/api/v1/initiateTransaction?mid=${params['MID']}&orderId=${params['ORDER_ID']}`;
202
-
203
- request.post(
204
- initTxnUrl,
205
- {
206
- json: {
207
- "body": initTxnbody,
208
- "head": {
209
- "signature": checksum,
210
- "channelId": params['CHANNEL_ID']
211
- }
212
- }
213
- },
214
- function (error, response, body) {
215
-
216
- if (!error && response.statusCode != undefined
217
- && response.statusCode != NaN &&
218
- response.statusCode == 200 &&
219
- body.body &&
220
- body.body.resultInfo &&
221
- body.body.resultInfo.resultStatus == "S") {
222
-
223
- let paytmJsToken = {}
224
- paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
225
- paytmJsToken.ORDERID = params['ORDER_ID']
226
- paytmJsToken.ORDER_ID = params['ORDER_ID']
227
- paytmJsToken.CANCELLED = "cancelled"
228
- paytmJsToken.TOKEN = body.body.txnToken
229
- paytmJsToken.TXN_AMOUNT = params['TXN_AMOUNT']
230
- paytmJsToken.MID = params['MID']
231
- paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
232
- paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
233
-
234
-
235
-
236
- let paytmJsCheckouHtml = `<html>
237
- <head>
238
- <title>Merchant Checkout</title>
239
- <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0"/>
240
-
241
- </head>
242
- <body>
243
- <center>
244
- <h1>Please donot close this page or press the back button. Processing...</h1>
245
- ${loadingSVG}
246
- </center>
247
- <form id="cancelform" action="${params['CALLBACK_URL']}" method="post">
248
- <input type="hidden" name="TXNID" value="na"/>
249
- <input type="hidden" name="STATUS" value="TXN_FAILURE"/>
250
- <input type="hidden" name="CANCELLED" value="cancelled"/>
251
- <input id="RESPMSG" type="hidden" name="RESPMSG" value=""/>
252
- <input type="hidden" name="ORDERID" value="${params["ORDER_ID"]}"/>
253
- </form>
254
-
255
-
256
- <script>
257
-
258
- function getBodyColor(color){
259
- const hex = color.replace('#', '');
260
- const c_r = parseInt(hex.substr(0, 2), 16);
261
- const c_g = parseInt(hex.substr(2, 2), 16);
262
- const c_b = parseInt(hex.substr(4, 2), 16);
263
- const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
264
- // console.log(brightness , brightness > 155 ? "#fff" : "#1a1a1c")
265
- return brightness > 155 ? "#1a1a1c" : "#ffffff";
266
- }
267
-
268
- function shadeColor(color, percent) {
269
-
270
- var R = parseInt(color.substring(1,3),16);
271
- var G = parseInt(color.substring(3,5),16);
272
- var B = parseInt(color.substring(5,7),16);
273
-
274
- R = parseInt(R * (100 + percent) / 100);
275
- G = parseInt(G * (100 + percent) / 100);
276
- B = parseInt(B * (100 + percent) / 100);
277
-
278
- R = (R<255)?R:255;
279
- G = (G<255)?G:255;
280
- B = (B<255)?B:255;
281
-
282
- var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
283
- var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
284
- var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));
285
-
286
- return "#"+RR+GG+BB;
287
- }
288
-
289
- function failTxn(reason) {
290
- var form = document.getElementById("cancelform");
291
- var element2 = document.getElementById("RESPMSG");
292
- element2.value=reason;
293
- form.submit();
294
- }
295
- function onScriptLoad(){
296
- var config = {
297
- "root": "",
298
- "flow": "DEFAULT",
299
- "style": {
300
- // "bodyColor": shadeColor("${config.theme_color}",+40),
301
- "themeBackgroundColor": "${config.theme_color}",
302
- "themeColor": getBodyColor("${config.theme_color}"),
303
- "headerBackgroundColor": "${config.theme_color}",
304
- "headerColor": getBodyColor("${config.theme_color}")
305
- },
306
- "data": {
307
- "orderId": "${params['ORDER_ID']}", /* update order id */
308
- "token": "${body.body.txnToken}", /* update token value */
309
- "tokenType": "TXN_TOKEN",
310
- "amount": "${params['TXN_AMOUNT']}" /* update amount */
311
- },
312
- "handler": {
313
- "notifyMerchant": function(eventName,data){
314
- // console.log("notifyMerchant handler function called");
315
- // console.log("eventName => ",eventName);
316
- // console.log("data => ",data);
317
- if(eventName == "APP_CLOSED"){
318
- failTxn(eventName)
319
- }
320
- }
321
- }
322
- };
323
-
324
- if(window.Paytm && window.Paytm.CheckoutJS){
325
- window.Paytm.CheckoutJS.onLoad(function excecuteAfterCompleteLoad() {
326
- // initialze configuration using init method
327
- window.Paytm.CheckoutJS.init(config).then(function onSuccess() {
328
- // after successfully updating configuration, invoke JS Checkout
329
- window.Paytm.CheckoutJS.invoke();
330
- }).catch(function onError(error){
331
- // console.log("error => ",error);
332
- failTxn(error.message)
333
- });
334
- });
335
- }
336
- }
337
- </script>
338
- <script type="application/javascript" crossorigin="anonymous" src="${config.paytm_url}/merchantpgpui/checkoutjs/merchants/${params['MID']}.js" onload="onScriptLoad();" crossorigin="anonymous"></script>
339
-
340
-
341
- </body>
342
- </html>`
343
- if (res.token) {
344
- res.token(paytmJsToken)
345
- }
346
- return res.send(paytmJsCheckouHtml)
347
-
348
- }
349
- else {
350
- console.log('ERROR:::', error, '\n', body);
351
- res.status(500)
352
- var form_fields = "";
353
- let errorResp = {
354
- TXNID: "na",
355
- STATUS: "TXN_FAILURE",
356
- CANCELLED: "cancelled",
357
- ORDERID: params["ORDER_ID"]
358
- }
359
- for (var x in errorResp) {
360
- form_fields += "<input type='hidden' name='" + x + "' value='" + errorResp[x] + "' >";
361
- }
362
- form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + checksum + "' >";
363
- if (res.token) {
364
- res.token(undefined)
365
- }
366
- res.writeHead(200, { 'Content-Type': 'text/html' });
367
- res.write(`<html>
368
-
369
- <head>
370
- <title>Merchant Checkout Error</title>
371
- </head>
372
-
373
- <body>
374
- <center>
375
- <h1>Something went wrong. Please wait you will be redirected automatically...</h1>
376
- </center>
377
- <form method="post" action="${params['CALLBACK_URL']}" name="f1">${form_fields}</form>
378
- <script type="text/javascript">document.f1.submit();</script>
379
- </body>
380
-
381
- </html>`);
382
- res.end();
383
-
384
- }
385
- }
386
- );
387
-
388
- }
389
- else if (config.razor_url) {
390
-
391
- let fail = `<div style="display:none">
392
-
393
- <form method="post" action="${params['CALLBACK_URL']}" id="fail">
394
- <input name="razorpay_order_id" value="${params['ORDER_ID']}" hidden="true"/>
395
- </form>
396
- </div>`;
397
- let html = `
398
- <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
399
- <script>
400
- var options = {
401
- "key": "${config.KEY}",
402
- "amount": "${parseFloat(params['TXN_AMOUNT']) * 100}",
403
- "currency": "INR",
404
- "name": "${params['PRODUCT_NAME']}",
405
- "description": "Order # ${params['ORDER_ID']}",
406
- "image": "${config.logo}",
407
- "order_id": "${params['ORDER_ID']}",
408
- "callback_url": "${params['CALLBACK_URL']}",
409
- "prefill": {
410
- "name": "${params['NAME']}",
411
- "email": "${params['EMAIL']}",
412
- "contact": "${params['MOBILE_NO']}"
413
- },
414
- "theme": {
415
- "color": "${config.theme_color}"
416
- },
417
- "modal": {
418
- "ondismiss": function(){
419
- document.getElementById("fail").submit()
420
- }
421
- }
422
- };
423
- var rzp1 = new Razorpay(options);
424
-
425
- rzp1.open();
426
- </script>`;
427
-
428
- res.writeHead(200, { 'Content-Type': 'text/html' });
429
- 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}</center></body></html>`);
430
- res.end();
431
-
432
- }
433
- else if (config.open_money_url) {
434
- try {
435
- let pmttoken = await openMoneyInstance.generatePaymentToken(params);
436
- openMoneyInstance.renderProcessingPage(params, pmttoken, res, loadingSVG);
437
-
438
- var myquery = { orderId: params['ORDER_ID'] };
439
- Transaction.findOne(myquery, function (err, objForUpdate) {
440
-
441
- objForUpdate.extra = JSON.stringify({
442
- layer_pay_token_id: pmttoken.tokenid
443
- });
444
-
445
- var newvalues = { $set: objForUpdate };
446
- Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
447
- let status = 'Updated TXNID'
448
- });
449
-
450
- }, usingMultiDbOrm ? Transaction : undefined)
451
-
452
- } catch (e) {
453
- openMoneyInstance.renderError(params, e, res)
454
- }
455
- }
456
- if (callbacks !== undefined)
457
- callbacks.onStart(params['ORDER_ID'], params);
458
- }
459
- else if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2) || gotAllParams) {
460
-
461
-
462
- useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO },
463
- function (user) {
464
-
465
- //console.log(user)
466
-
467
- let onTxn = async function (txnData) {
468
-
469
-
470
- //console.log(txnData)
471
-
472
- var params = {};
473
- params['MID'] = config.MID;
474
- params['WEBSITE'] = config.WEBSITE;
475
- params['CHANNEL_ID'] = config.CHANNEL_ID;
476
- params['INDUSTRY_TYPE_ID'] = config.INDUSTRY_TYPE_ID;
477
- params['ORDER_ID'] = txnData.orderId;
478
- params['CUST_ID'] = txnData.cusId;
479
- params['TXN_AMOUNT'] = JSON.stringify(txnData.amount);
480
- params['CALLBACK_URL'] = config.host_url + '/' + config.path_prefix + '/callback'
481
- params['EMAIL'] = txnData.email;
482
- params['MOBILE_NO'] = txnData.phone;
483
- params['NAME'] = txnData.name;
484
- params['PRODUCT_NAME'] = txnData.pname;
485
-
486
-
487
- let showConfirmation =
488
- function (err, checksum) {
489
- res.render(vp + "init.hbs", {
490
- action: '',
491
- readonly: 'readonly',
492
- BUTTON: 'Pay',
493
- NAME: params['NAME'],
494
- EMAIL: params['EMAIL'],
495
- MOBILE_NO: params['MOBILE_NO'],
496
- PRODUCT_NAME: params['PRODUCT_NAME'],
497
- TXN_AMOUNT: params['TXN_AMOUNT'],
498
- MID: params['MID'],
499
- WEBSITE: params['WEBSITE'],
500
- ORDER_ID: params['ORDER_ID'],
501
- CUST_ID: params['CUST_ID'],
502
- INDUSTRY_TYPE_ID: params['INDUSTRY_TYPE_ID'],
503
- CHANNEL_ID: params['CHANNEL_ID'],
504
- CALLBACK_URL: params['CALLBACK_URL'],
505
- CHECKSUMHASH: checksum
506
- })
507
- }
508
-
509
-
510
- if (config.paytm_url)
511
- checksum_lib.genchecksum(params, config.KEY, showConfirmation);
512
- else if (config.razor_url) {
513
- showConfirmation()
514
- } else if (config.open_money_url) {
515
- showConfirmation()
516
- }
517
-
518
- };
519
-
520
-
521
-
522
- if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)) {
523
-
524
-
525
- var myquery = { orderId: req.body.ORDER_ID };
526
- Transaction.findOne(myquery, function (err, orderData) {
527
-
528
- onTxn(orderData);
529
-
530
- }, usingMultiDbOrm ? Transaction : undefined);
531
-
532
-
533
-
534
- }
535
- 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
- let orderId;
566
- if (config.paytm_url) {
567
- orderId = "pay_" + makeid(config.id_length || IDLEN)
568
- onOrder(orderId)
569
- }
570
- else if (config.razor_url) {
571
-
572
- var options = {
573
- amount: req.body.TXN_AMOUNT * 100,
574
- currency: "INR",
575
- receipt: user.id + '_' + Date.now()
576
- };
577
-
578
-
579
- razorPayInstance.orders.create(options, function (err, order) {
580
- if (err) {
581
- res.send({ message: "An error occurred ! " + err.description })
582
- return;
583
- }
584
- orderId = order.id
585
- onOrder(orderId)
586
- })
587
- }
588
- else if (config.open_money_url) {
589
- orderId = "pay_" + makeid(config.id_length || IDLEN)
590
- onOrder(orderId)
591
- }
592
-
593
-
594
-
595
- }
596
-
597
-
598
-
599
-
600
-
601
-
602
- });
603
-
604
-
605
- }
606
- else {
607
-
608
-
609
- res.render(vp + "init.hbs", {
610
-
611
- action: '',
612
- readonly: '',
613
- check: true,
614
- BUTTON: 'Submit',
615
- NAME: (req.body.NAME === undefined ? '' : req.body.NAME),
616
- EMAIL: (req.body.EMAIL === undefined ? '' : req.body.EMAIL),
617
- MOBILE_NO: (req.body.MOBILE_NO === undefined ? '' : req.body.MOBILE_NO),
618
- PRODUCT_NAME: (req.body.PRODUCT_NAME === undefined ? '' : req.body.PRODUCT_NAME),
619
- TXN_AMOUNT: (req.body.TXN_AMOUNT === undefined ? '' : req.body.TXN_AMOUNT),
620
- MID: config.MID,
621
- WEBSITE: config.WEBSITE,
622
- ORDER_ID: '',
623
- CUST_ID: '',
624
- INDUSTRY_TYPE_ID: config.INDUSTRY_TYPE_ID,
625
- CHANNEL_ID: config.CHANNEL_ID,
626
- CALLBACK_URL: config.CALLBACK_URL,
627
- CHECKSUMHASH: ''
628
-
629
- })
630
-
631
- }
632
-
633
- }
634
-
635
- function updateTransaction(req, res) {
636
- var myquery = { orderId: req.body.ORDERID };
637
-
638
- Transaction.findOne(myquery, function (err, objForUpdate) {
639
-
640
- if (err) {
641
- res.send({ message: "Transaction Not Found !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
642
- return;
643
- }
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;
651
- }
652
- if (req.body.status == "paid" && !req.body.STATUS) {
653
- req.body.STATUS = "TXN_SUCCESS"
654
- }
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) {
661
-
662
- if (err) {
663
- res.send({ message: "Error Occured !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
664
- }
665
- else {
666
-
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);
672
- }
673
- });
674
-
675
- }, usingMultiDbOrm ? Transaction : undefined)
676
- }
677
-
678
- module.callback = async (req, res) => {
679
- console.log("request_data ", req.originalUrl, JSON.stringify(req.body))
680
-
681
- var result = false;
682
- let isCancelled = false;
683
- if (config.paytm_url) {
684
- var checksumhash = req.body.CHECKSUMHASH;
685
- if (checksumhash) {
686
- result = checksum_lib.verifychecksum(req.body, config.KEY, checksumhash);
687
- }
688
- else {
689
- let liveStatus = await new Promise((resolve, reject) => {
690
- getStatusFromPaytm(req.body, req.body.ORDERID, (paytmResponse) => {
691
- resolve(paytmResponse)
692
- })
693
- })
694
- result = liveStatus.STATUS == req.body.STATUS;
695
- }
696
- if (req.body.STATUS == 'TXN_FAILURE' && req.body.CANCELLED == "cancelled" && req.body.TXNID) {
697
- isCancelled = true;
698
- }
699
-
700
- }
701
- else if (config.razor_url) {
702
-
703
- if (req.body.razorpay_payment_id) {
704
- result = checksum_lib.checkRazorSignature(req.body.razorpay_order_id,
705
- req.body.razorpay_payment_id,
706
- config.SECRET,
707
- req.body.razorpay_signature)
708
- if (result) {
709
- req.body.STATUS = 'TXN_SUCCESS'
710
- req.body.ORDERID = req.body.razorpay_order_id
711
- req.body.TXNID = req.body.razorpay_payment_id
712
- }
713
- }
714
- else {
715
- if (req.body.error && req.body.error.metadata && JSON.parse(req.body.error.metadata)) {
716
- let orderId = JSON.parse(req.body.error.metadata).order_id
717
- req.body.razorpay_order_id = orderId
718
- }
719
- req.body.STATUS = 'TXN_FAILURE'
720
- req.body.ORDERID = req.body.razorpay_order_id || req.query.order_id
721
- isCancelled = true;
722
- }
723
- }
724
- else if (config.open_money_url) {
725
- let openRest = await openMoneyInstance.verifyResult(req);
726
- result = true;
727
- req.body.STATUS = openRest.STATUS
728
- req.body.TXNID = openRest.TXNID
729
- req.body.ORDERID = openRest.ORDERID || req.query.order_id
730
- req.body.extras = openRest.data
731
- }
732
-
733
-
734
- //console.log("Checksum Result => ", result, "\n");
735
- console.log("NodePayTMPG::Transaction => ", req.body.ORDERID, req.body.STATUS);
736
- //console.log(req.body)
737
-
738
- if (result || isCancelled) {
739
-
740
- updateTransaction(req, res);
741
-
742
- }
743
- else {
744
-
745
- res.send({ message: "Something went wrong ! Please try again later .", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
746
-
747
- }
748
-
749
- }
750
-
751
- module.webhook = (req, res) => {
752
-
753
-
754
-
755
- console.log("request_data ", req.originalUrl, JSON.stringify(req.body))
756
-
757
- if (config.paytm_url) {
758
- module.callback(req, res)
759
- }
760
- else if (config.razor_url) {
761
- let events = ["payment.captured", "payment.pending", "payment.failed"]
762
- if (req.body.event && events.indexOf(req.body.event) > -1) {
763
- if (req.body.payload &&
764
- req.body.payload.payment &&
765
- req.body.payload.payment.entity) {
766
-
767
- let entity = req.body.payload.payment.entity;
768
- let razorpay_order_id = entity.order_id;
769
- let razorpay_payment_id = entity.id;
770
- let status = entity.status;
771
- let event = req.body.event;
772
- console.log(`Razorpay webhook payment order=${razorpay_order_id} payid=${razorpay_payment_id} status=${status}`)
773
-
774
- let reqBody = req.rawBody, signature = req.headers["x-razorpay-signature"];
775
-
776
- result = RazorPay.validateWebhookSignature(reqBody, req.headers['x-razorpay-signature'], config.SECRET)
777
- req.signatureVerified = result;
778
- if (result) {
779
- if (event == events[0]) {
780
- req.body.STATUS = "TXN_SUCCESS";
781
- }
782
- else if (event == events[1]) { //pending
783
- req.body.STATUS = "TXN_PENDING";
784
- }
785
- else { // failed
786
- req.body.STATUS = "TXN_FAILURE";
787
- }
788
- req.body.ORDERID = razorpay_order_id;
789
- req.body.TXNID = razorpay_payment_id;
790
- setTimeout(() => {
791
- updateTransaction(req, res)
792
- }, 3000)
793
- }
794
- else {
795
- res.status(401)
796
- res.send({ message: "Invalid Rzpay signature" })
797
- }
798
- }
799
- else {
800
- res.status(400)
801
- res.send({ message: "Invalid Payload" })
802
- }
803
- }
804
- else {
805
- res.status(400)
806
- res.send({ message: "Unsupported event : " + req.body.event })
807
- }
808
- }
809
- else if (config.open_money_url) {
810
- openMoneyInstance.processWebhook(req, res, updateTransaction)
811
- }
812
- }
813
-
814
- module.createTxn = (req, res) => {
815
-
816
-
817
- useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO },
818
- async function (user) {
819
-
820
-
821
- let id;
822
- if (config.paytm_url) {
823
- id = "pay_" + makeid(config.id_length || IDLEN)
824
- }
825
- else if (config.razor_url) {
826
-
827
- var options = {
828
- amount: req.body.TXN_AMOUNT * 100,
829
- currency: "INR",
830
- receipt: user.id + '_' + Date.now()
831
- };
832
- let order = await razorPayInstance.orders.create(options);
833
- id = order.id;
834
- }
835
- else if (config.open_money_url) {
836
- id = "pay_" + makeid(config.id_length || IDLEN)
837
- }
838
-
839
- var txnTask = new Transaction({
840
- id: id,
841
- orderId: id,
842
- cusId: user.id,
843
- time: Date.now(),
844
- status: 'INITIATED',
845
- name: user.name,
846
- email: user.email,
847
- phone: user.phone,
848
- amount: req.body.TXN_AMOUNT,
849
- pname: req.body.PRODUCT_NAME,
850
- extra: (req.body.EXTRA || '')
851
-
852
- });
853
-
854
-
855
- txnTask.save().then(function (txn) {
856
- var urlData64 = nodeBase64.encode(JSON.stringify({
857
- NAME: txn.name,
858
- EMAIL: txn.email,
859
- MOBILE_NO: txn.phone,
860
- ORDER_ID: txn.orderId
861
- }))
862
-
863
- txn.payurl = config.host_url + '/' + config.path_prefix + '/init?to=' + urlData64;
864
- res.send(txn)
865
- })
866
- .catch(err => {
867
-
868
- console.log(err)
869
-
870
- res.redirect('')
871
- });
872
-
873
-
874
- });
875
-
876
-
877
-
878
- };
879
-
880
- module.createTxnToken = (req, res) => {
881
-
882
-
883
- module.createTxn(req, {
884
- send: function (createTxnResult) {
885
-
886
- // console.log(createTxnResult)
887
-
888
- req.body.NAME = createTxnResult.name
889
- req.body.EMAIL = createTxnResult.email
890
- req.body.MOBILE_NO = createTxnResult.phone
891
- req.body.ORDER_ID = createTxnResult.orderId
892
- module.init(req, {
893
- render: (renderPath, initResultRender) => {
894
- // console.log(initResultRender)
895
- req.body = initResultRender
896
-
897
- module.init(req, {
898
- send: (initResult) => {
899
-
900
- },
901
- status: (status) => {
902
- console.log('status', status)
903
-
904
- },
905
- token: (tokenData) => {
906
- if (!tokenData) {
907
- res.status(500)
908
- res.send('Something went wrong. Please try again later.')
909
- }
910
- else {
911
- tokenData.payurl = createTxnResult.payurl;
912
- res.send(tokenData)
913
- }
914
- },
915
- render: (renderPath2, init2ResultRender) => {
916
- console.log('init2ResultRender', init2ResultRender)
917
- },
918
- end: (initResultWrite) => {
919
- console.log('initResultWrite', initResultWrite)
920
- },
921
- write: (initResultWrite) => {
922
- console.log('initResultWrite', initResultWrite)
923
- },
924
- writeHead: (initResultWriteHead) => {
925
- console.log('initResultWriteHead', initResultWriteHead)
926
- }
927
-
928
- })
929
-
930
- }
931
- })
932
- },
933
- redirect: res.redirect
934
- })
935
-
936
-
937
- };
938
-
939
-
940
- module.status = (req, res) => {
941
-
942
- if (!req.body.ORDER_ID && req.query.ORDER_ID) {
943
- req.body.ORDER_ID = req.query.ORDER_ID
944
- }
945
- var myquery = { orderId: req.body.ORDER_ID };
946
- Transaction.findOne(myquery, async function (err, orderData) {
947
-
948
-
949
- if (err) {
950
- res.send(err)
951
- return
952
- }
953
- if (orderData.status === "INITIATED") {
954
-
955
- var params = {}
956
- params["MID"] = config.MID;
957
- params["ORDERID"] = req.body.ORDER_ID;
958
-
959
- async function onStatusUpdate(paytmResponse) {
960
- if (paytmResponse.TXNID.length > 4) {
961
- orderData.status = paytmResponse.STATUS;
962
- orderData.extra = JSON.stringify(paytmResponse);
963
-
964
- var newvalues = { $set: orderData };
965
- Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
966
-
967
- if (err) {
968
- res.send({ message: "Error Occured !", ORDERID: paytmResponse.ORDERID, TXNID: paytmResponse.TXNID })
969
- }
970
- else {
971
- if (callbacks !== undefined)
972
- callbacks.onFinish(req.body.ORDER_ID, orderData);
973
- res.send(paytmResponse)
974
- }
975
- });
976
- }
977
- else {
978
- res.send(orderData)
979
-
980
- }
981
- }
982
-
983
- if (config.paytm_url) {
984
- getStatusFromPaytm(params, req.body.ORDER_ID, onStatusUpdate)
985
- }
986
- else if (config.razor_url) {
987
- let result = await razorPayInstance.orders.fetch(req.body.ORDER_ID)
988
- result.ORDERID = req.body.ORDER_ID
989
- if (result.status == 'paid' && result.amount_due == 0) {
990
- result.STATUS = 'TXN_SUCCESS'
991
- let payments = await razorPayInstance.orders.fetchPayments(req.body.ORDER_ID)
992
- payments.items.forEach(item => {
993
- if (item.status == 'captured') {
994
- result.TXNID = item.id
995
- }
996
- });
997
- result.payments = payments;
998
-
999
- onStatusUpdate(result)
1000
- }
1001
- else {
1002
- res.send(orderData);
1003
- }
1004
- }
1005
- else if (config.open_money_url) {
1006
- let extras = JSON.parse(orderData.extra)
1007
- if (!extras || !extras.layer_pay_token_id) {
1008
- res.status(500)
1009
- return res.send({ message: 'An unexpected error occured. No payment token exists' })
1010
- }
1011
- let result = await openMoneyInstance.getPaymentStatus(extras.layer_pay_token_id)
1012
- result = JSON.parse(result)
1013
- result.ORDERID = req.body.ORDER_ID
1014
- if (result.status == 'paid' || result.status == 'captured') {
1015
- result.STATUS = 'TXN_SUCCESS'
1016
- result.TXNID = result.id
1017
- onStatusUpdate(result)
1018
- }
1019
- else if (result.status == 'pending' || result.status == 'attempted') {
1020
- result.STATUS = 'TXN_PENDING'
1021
- result.TXNID = result.id
1022
- onStatusUpdate(result)
1023
- }
1024
- // else if (result.status == 'failed' || result.status == 'cancelled') {
1025
- // result.STATUS = 'TXN_FAILED'
1026
- // result.TXNID = result.id
1027
- // onStatusUpdate(result)
1028
- // }
1029
- else {
1030
- res.send(orderData);
1031
- }
1032
- }
1033
-
1034
- }
1035
- else {
1036
- res.send(orderData);
1037
- }
1038
-
1039
-
1040
- }, usingMultiDbOrm ? Transaction : undefined);
1041
-
1042
-
1043
- }
1044
-
1045
- function getStatusFromPaytm(params, orderId, cb) {
1046
- checksum_lib.genchecksum(params, config.KEY, function (err, checksum) {
1047
-
1048
- request.post(
1049
- config.paytm_url + "/order/status",
1050
- { json: { MID: config.MID, ORDERID: orderId, CHECKSUMHASH: checksum, } },
1051
- function (error, response, body) {
1052
-
1053
- if (!error && response.statusCode == 200) {
1054
- var paytmResponse = JSON.parse(JSON.stringify(body))
1055
- cb(paytmResponse)
1056
- }
1057
- else {
1058
- console.log('ERROR:::', error, '\n', response);
1059
- cb({ message: "Error Occured !", ORDERID: orderId })
1060
- }
1061
- }
1062
- );
1063
- });
1064
- }
1065
-
1066
- return module;
1067
- }
1
+ var packageInfo = require('../../package.json')
2
+ const checksum_lib = require('./checksum/checksum.js');
3
+ var request = require('request')
4
+ var Transaction;
5
+ var IDLEN = 10;
6
+ var nodeBase64 = require('nodejs-base64-converter');
7
+ var RazorPay = require('razorpay');
8
+ var OpenMoney = require('./adapters/open_money')
9
+ var PayU = require('./adapters/payu')
10
+ const PaytmChecksum = require('./checksum/PaytmChecksum.js');
11
+ const { stat } = require('fs');
12
+ const { config } = require('process');
13
+
14
+ 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">
15
+ <g transform="rotate(0 50 50)">
16
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
17
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite"></animate>
18
+ </rect>
19
+ </g><g transform="rotate(30 50 50)">
20
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
21
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite"></animate>
22
+ </rect>
23
+ </g><g transform="rotate(60 50 50)">
24
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
25
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
26
+ </rect>
27
+ </g><g transform="rotate(90 50 50)">
28
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
29
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite"></animate>
30
+ </rect>
31
+ </g><g transform="rotate(120 50 50)">
32
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
33
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite"></animate>
34
+ </rect>
35
+ </g><g transform="rotate(150 50 50)">
36
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
37
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
38
+ </rect>
39
+ </g><g transform="rotate(180 50 50)">
40
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
41
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite"></animate>
42
+ </rect>
43
+ </g><g transform="rotate(210 50 50)">
44
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
45
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite"></animate>
46
+ </rect>
47
+ </g><g transform="rotate(240 50 50)">
48
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
49
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
50
+ </rect>
51
+ </g><g transform="rotate(270 50 50)">
52
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
53
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite"></animate>
54
+ </rect>
55
+ </g><g transform="rotate(300 50 50)">
56
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
57
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite"></animate>
58
+ </rect>
59
+ </g><g transform="rotate(330 50 50)">
60
+ <rect x="47" y="24" rx="3" ry="6" width="6" height="12" fill="#0097a7">
61
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
62
+ </rect>
63
+ </g>
64
+ </svg>`
65
+
66
+ function sanitizeRequest(body) {
67
+
68
+ if (body.amount)
69
+ body.amount = parseFloat(body.amount);
70
+ if (body.TXN_AMOUNT)
71
+ body.amount = parseFloat(body.TXN_AMOUNT);
72
+ }
73
+
74
+ module.exports = function (app, callbacks) {
75
+ var config = (app.get('np_config'))
76
+ var useController = require('./np_user.controller.js')(app, callbacks);
77
+
78
+ var razorPayInstance;
79
+ var openMoneyInstance = new OpenMoney(config);
80
+ var payuInstance = new PayU(config)
81
+
82
+ if (config.razor_url) {
83
+ razorPayInstance = new RazorPay({ key_id: config.KEY, key_secret: config.SECRET })
84
+ }
85
+ if (config.open_money_url) {
86
+ openMoneyInstance = new OpenMoney(config);
87
+ }
88
+ if (config.payu_url) {
89
+ payuInstance = new PayU(config);
90
+ }
91
+
92
+ let usingMultiDbOrm = false;
93
+ if (config.db_url) {
94
+ Transaction = require('../models/np_transaction.model.js');
95
+ usingMultiDbOrm = false;
96
+
97
+ } else if (app.multidborm) {
98
+ const sample = {
99
+ orderId: "string",
100
+ cusId: "string",
101
+ time: 1770051201752,
102
+ timeStamp: 1770051201752,
103
+ status: "string",
104
+ name: "string",
105
+ email: "string",
106
+ phone: "string",
107
+ amount: 1,
108
+ pname: "string",
109
+ extra: "stringlarge",
110
+ TXNID: "27118670199",
111
+ returnUrl: "string"
112
+ }
113
+ Transaction = require('../models/np_multidbplugin.js')('nptransactions', app.multidborm, sample);
114
+ Transaction.db = app.multidborm;
115
+ Transaction.modelname = 'nptransactions'
116
+ Transaction.idFieldName = 'orderId'
117
+ app.NPTransaction = Transaction;
118
+ usingMultiDbOrm = true;
119
+
120
+ }
121
+
122
+ var module = {};
123
+
124
+ var config = (app.get('np_config'))
125
+ function makeid(length) {
126
+ var text = "";
127
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
128
+
129
+ for (var i = 0; i < length; i++)
130
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
131
+
132
+ return text;
133
+ }
134
+
135
+ var vp = __dirname + config.view_path
136
+
137
+ module.home = (req, res) => {
138
+
139
+ packageInfo.repository.url = packageInfo.repository.url.replace('git+', '')
140
+ res.render(vp + "home.hbs", packageInfo)
141
+
142
+
143
+ }
144
+
145
+ module.init = async function (req, res) {
146
+
147
+ if (!req.body.ORDER_ID && !req.body.EMAIL && req.query.to) {
148
+ let toData = JSON.parse(nodeBase64.decode(req.query.to));
149
+ req.body.NAME = toData.NAME
150
+ req.body.EMAIL = toData.EMAIL
151
+ req.body.TXN_AMOUNT = toData.TXN_AMOUNT
152
+ req.body.MOBILE_NO = toData.MOBILE_NO
153
+ req.body.ORDER_ID = toData.ORDER_ID || toData.ORDERID
154
+ req.body.PRODUCT_NAME = toData.PRODUCT_NAME
155
+ req.body.RETURN_URL = toData.RETURN_URL
156
+ }
157
+
158
+ sanitizeRequest(req.body);
159
+ let gotAllParams = true;
160
+ let checkedFields = ['TXN_AMOUNT', 'PRODUCT_NAME', 'MOBILE_NO', 'NAME', 'EMAIL']
161
+ if (req.body !== undefined) {
162
+
163
+ for (var i = 0; i < checkedFields.length; i++) {
164
+
165
+ if (req.body[checkedFields[i]] === undefined) {
166
+ gotAllParams = false;
167
+ break;
168
+ }
169
+
170
+ }
171
+ }
172
+ else {
173
+ gotAllParams = false;
174
+ }
175
+
176
+ // console.log(req.body)
177
+
178
+ if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)
179
+ &&
180
+ (req.body.CUST_ID !== undefined && req.body.CUST_ID.length > 2)) {
181
+ // console.log('redirect')
182
+ // console.log(req.body)
183
+ var params = {};
184
+
185
+ params['MID'] = req.body.MID;
186
+ params['WEBSITE'] = req.body.WEBSITE;
187
+ params['CHANNEL_ID'] = req.body.CHANNEL_ID;
188
+ params['INDUSTRY_TYPE_ID'] = req.body.INDUSTRY_TYPE_ID;
189
+ params['ORDER_ID'] = req.body.ORDER_ID || req.body.ORDERID;
190
+ params['CUST_ID'] = req.body.CUST_ID;
191
+ params['TXN_AMOUNT'] = req.body.TXN_AMOUNT;
192
+ params['CALLBACK_URL'] = req.body.CALLBACK_URL + "?order_id=" + req.body.ORDER_ID;
193
+ params['EMAIL'] = req.body.EMAIL;
194
+ params['MOBILE_NO'] = req.body.MOBILE_NO;
195
+ params['PRODUCT_NAME'] = req.body.PRODUCT_NAME;
196
+ params['NAME'] = req.body.NAME;
197
+
198
+ if (config.paytm_url) {
199
+
200
+ let initTxnbody = {
201
+ "requestType": "Payment",
202
+ "mid": params['MID'],
203
+ "websiteName": params['WEBSITE'],
204
+ "orderId": params['ORDER_ID'],
205
+ "callbackUrl": params['CALLBACK_URL'],
206
+ "txnAmount": {
207
+ "value": params['TXN_AMOUNT'],
208
+ "currency": params['CURRENCY'] || "INR",
209
+ },
210
+ "userInfo": {
211
+ "custId": params['CUST_ID'],
212
+ "mobile": params['MOBILE_NO'],
213
+ "firstName": params['NAME'],
214
+ "email": params['EMAIL']
215
+ }
216
+ };
217
+ if (config.mode) {
218
+ initTxnbody["enablePaymentMode"] = JSON.parse(config.mode)
219
+ }
220
+
221
+ let checksum = await PaytmChecksum.generateSignature(JSON.stringify(initTxnbody), config.KEY)
222
+ let initTxnUrl = config.paytm_url + `/theia/api/v1/initiateTransaction?mid=${params['MID']}&orderId=${params['ORDER_ID']}`;
223
+
224
+ request.post(
225
+ initTxnUrl,
226
+ {
227
+ json: {
228
+ "body": initTxnbody,
229
+ "head": {
230
+ "signature": checksum,
231
+ "channelId": params['CHANNEL_ID']
232
+ }
233
+ }
234
+ },
235
+ function (error, response, body) {
236
+
237
+ if (!error && response.statusCode != undefined
238
+ && response.statusCode != NaN &&
239
+ response.statusCode == 200 &&
240
+ body.body &&
241
+ body.body.resultInfo &&
242
+ body.body.resultInfo.resultStatus == "S") {
243
+
244
+ let paytmJsToken = {}
245
+ paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
246
+ paytmJsToken.ORDERID = params['ORDER_ID']
247
+ paytmJsToken.ORDER_ID = params['ORDER_ID']
248
+ paytmJsToken.CANCELLED = "cancelled"
249
+ paytmJsToken.TOKEN = body.body.txnToken
250
+ paytmJsToken.TXN_AMOUNT = params['TXN_AMOUNT']
251
+ paytmJsToken.MID = params['MID']
252
+ paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
253
+ paytmJsToken.CALLBACK_URL = params['CALLBACK_URL']
254
+
255
+
256
+
257
+ let paytmJsCheckouHtml = `<html>
258
+ <head>
259
+ <title>Merchant Checkout</title>
260
+ <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0"/>
261
+
262
+ </head>
263
+ <body>
264
+ <center>
265
+ <h1>Please donot close this page or press the back button. Processing...</h1>
266
+ ${loadingSVG}
267
+ </center>
268
+ <form id="cancelform" action="${params['CALLBACK_URL']}" method="post">
269
+ <input type="hidden" name="TXNID" value="na"/>
270
+ <input type="hidden" name="STATUS" value="TXN_FAILURE"/>
271
+ <input type="hidden" name="CANCELLED" value="cancelled"/>
272
+ <input id="RESPMSG" type="hidden" name="RESPMSG" value=""/>
273
+ <input type="hidden" name="ORDERID" value="${params["ORDER_ID"]}"/>
274
+ </form>
275
+
276
+
277
+ <script>
278
+
279
+ function getBodyColor(color){
280
+ const hex = color.replace('#', '');
281
+ const c_r = parseInt(hex.substr(0, 2), 16);
282
+ const c_g = parseInt(hex.substr(2, 2), 16);
283
+ const c_b = parseInt(hex.substr(4, 2), 16);
284
+ const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
285
+ // console.log(brightness , brightness > 155 ? "#fff" : "#1a1a1c")
286
+ return brightness > 155 ? "#1a1a1c" : "#ffffff";
287
+ }
288
+
289
+ function shadeColor(color, percent) {
290
+
291
+ var R = parseInt(color.substring(1,3),16);
292
+ var G = parseInt(color.substring(3,5),16);
293
+ var B = parseInt(color.substring(5,7),16);
294
+
295
+ R = parseInt(R * (100 + percent) / 100);
296
+ G = parseInt(G * (100 + percent) / 100);
297
+ B = parseInt(B * (100 + percent) / 100);
298
+
299
+ R = (R<255)?R:255;
300
+ G = (G<255)?G:255;
301
+ B = (B<255)?B:255;
302
+
303
+ var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
304
+ var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
305
+ var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));
306
+
307
+ return "#"+RR+GG+BB;
308
+ }
309
+
310
+ function failTxn(reason) {
311
+ var form = document.getElementById("cancelform");
312
+ var element2 = document.getElementById("RESPMSG");
313
+ element2.value=reason;
314
+ form.submit();
315
+ }
316
+ function onScriptLoad(){
317
+ var config = {
318
+ "root": "",
319
+ "flow": "DEFAULT",
320
+ "style": {
321
+ // "bodyColor": shadeColor("${config.theme_color}",+40),
322
+ "themeBackgroundColor": "${config.theme_color}",
323
+ "themeColor": getBodyColor("${config.theme_color}"),
324
+ "headerBackgroundColor": "${config.theme_color}",
325
+ "headerColor": getBodyColor("${config.theme_color}")
326
+ },
327
+ "data": {
328
+ "orderId": "${params['ORDER_ID']}", /* update order id */
329
+ "token": "${body.body.txnToken}", /* update token value */
330
+ "tokenType": "TXN_TOKEN",
331
+ "amount": "${params['TXN_AMOUNT']}" /* update amount */
332
+ },
333
+ "handler": {
334
+ "notifyMerchant": function(eventName,data){
335
+ // console.log("notifyMerchant handler function called");
336
+ // console.log("eventName => ",eventName);
337
+ // console.log("data => ",data);
338
+ if(eventName == "APP_CLOSED"){
339
+ failTxn(eventName)
340
+ }
341
+ }
342
+ }
343
+ };
344
+
345
+ if(window.Paytm && window.Paytm.CheckoutJS){
346
+ window.Paytm.CheckoutJS.onLoad(function excecuteAfterCompleteLoad() {
347
+ // initialze configuration using init method
348
+ window.Paytm.CheckoutJS.init(config).then(function onSuccess() {
349
+ // after successfully updating configuration, invoke JS Checkout
350
+ window.Paytm.CheckoutJS.invoke();
351
+ }).catch(function onError(error){
352
+ // console.log("error => ",error);
353
+ failTxn(error.message)
354
+ });
355
+ });
356
+ }
357
+ }
358
+ </script>
359
+ <script type="application/javascript" crossorigin="anonymous" src="${config.paytm_url}/merchantpgpui/checkoutjs/merchants/${params['MID']}.js" onload="onScriptLoad();" crossorigin="anonymous"></script>
360
+
361
+
362
+ </body>
363
+ </html>`
364
+ if (res.token) {
365
+ res.token(paytmJsToken)
366
+ }
367
+ return res.send(paytmJsCheckouHtml)
368
+
369
+ }
370
+ else {
371
+ console.log('ERROR:::', error, '\n', body);
372
+ res.status(500)
373
+ var form_fields = "";
374
+ let errorResp = {
375
+ TXNID: "na",
376
+ STATUS: "TXN_FAILURE",
377
+ CANCELLED: "cancelled",
378
+ ORDERID: params["ORDER_ID"]
379
+ }
380
+ for (var x in errorResp) {
381
+ form_fields += "<input type='hidden' name='" + x + "' value='" + errorResp[x] + "' >";
382
+ }
383
+ form_fields += "<input type='hidden' name='CHECKSUMHASH' value='" + checksum + "' >";
384
+ if (res.token) {
385
+ res.token(undefined)
386
+ }
387
+ res.writeHead(200, { 'Content-Type': 'text/html' });
388
+ res.write(`<html>
389
+
390
+ <head>
391
+ <title>Merchant Checkout Error</title>
392
+ </head>
393
+
394
+ <body>
395
+ <center>
396
+ <h1>Something went wrong. Please wait you will be redirected automatically...</h1>
397
+ </center>
398
+ <form method="post" action="${params['CALLBACK_URL']}" name="f1">${form_fields}</form>
399
+ <script type="text/javascript">document.f1.submit();</script>
400
+ </body>
401
+
402
+ </html>`);
403
+ res.end();
404
+
405
+ }
406
+ }
407
+ );
408
+
409
+ }
410
+ else if (config.razor_url) {
411
+
412
+ let fail = `<div style="display:none">
413
+
414
+ <form method="post" action="${params['CALLBACK_URL']}" id="fail">
415
+ <input name="razorpay_order_id" value="${params['ORDER_ID']}" hidden="true"/>
416
+ </form>
417
+ </div>`;
418
+ let html = `
419
+ <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
420
+ <script>
421
+ var options = {
422
+ "key": "${config.KEY}",
423
+ "amount": "${parseFloat(params['TXN_AMOUNT']) * 100}",
424
+ "currency": "INR",
425
+ "name": "${params['PRODUCT_NAME']}",
426
+ "description": "Order # ${params['ORDER_ID']}",
427
+ "image": "${config.logo}",
428
+ "order_id": "${params['ORDER_ID']}",
429
+ "callback_url": "${params['CALLBACK_URL']}",
430
+ "prefill": {
431
+ "name": "${params['NAME']}",
432
+ "email": "${params['EMAIL']}",
433
+ "contact": "${params['MOBILE_NO']}"
434
+ },
435
+ "theme": {
436
+ "color": "${config.theme_color}"
437
+ },
438
+ "modal": {
439
+ "ondismiss": function(){
440
+ document.getElementById("fail").submit()
441
+ }
442
+ }
443
+ };
444
+ var rzp1 = new Razorpay(options);
445
+
446
+ rzp1.open();
447
+ </script>`;
448
+
449
+ res.writeHead(200, { 'Content-Type': 'text/html' });
450
+ 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}</center></body></html>`);
451
+ res.end();
452
+
453
+ }
454
+ else if (config.payu_url) {
455
+ const payuRequest = payuInstance.generatePaymentRequest(params);
456
+ payuInstance.renderProcessingPage(params, payuRequest, res, loadingSVG);
457
+ }
458
+ else if (config.open_money_url) {
459
+ try {
460
+ let pmttoken = await openMoneyInstance.generatePaymentToken(params);
461
+ openMoneyInstance.renderProcessingPage(params, pmttoken, res, loadingSVG);
462
+
463
+ var myquery = { orderId: params['ORDER_ID'] };
464
+ Transaction.findOne(myquery, function (err, objForUpdate) {
465
+
466
+ objForUpdate.extra = JSON.stringify({
467
+ layer_pay_token_id: pmttoken.tokenid
468
+ });
469
+
470
+ var newvalues = { $set: objForUpdate };
471
+ Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
472
+ let status = 'Updated TXNID'
473
+ });
474
+
475
+ }, usingMultiDbOrm ? Transaction : undefined)
476
+
477
+ } catch (e) {
478
+ openMoneyInstance.renderError(params, e, res)
479
+ }
480
+ }
481
+ if (callbacks !== undefined)
482
+ callbacks.onStart(params['ORDER_ID'], params);
483
+ }
484
+ else if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2) || gotAllParams) {
485
+
486
+
487
+ useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO },
488
+ function (user) {
489
+
490
+ //console.log(user)
491
+
492
+ let onTxn = async function (txnData) {
493
+
494
+
495
+ //console.log(txnData)
496
+
497
+ var params = {};
498
+ params['MID'] = config.MID;
499
+ params['WEBSITE'] = config.WEBSITE;
500
+ params['CHANNEL_ID'] = config.CHANNEL_ID;
501
+ params['INDUSTRY_TYPE_ID'] = config.INDUSTRY_TYPE_ID;
502
+ params['ORDER_ID'] = txnData.orderId;
503
+ params['CUST_ID'] = txnData.cusId;
504
+ params['TXN_AMOUNT'] = JSON.stringify(txnData.amount);
505
+ params['CALLBACK_URL'] = config.host_url + '/' + config.path_prefix + '/callback'
506
+ params['EMAIL'] = txnData.email;
507
+ params['MOBILE_NO'] = txnData.phone;
508
+ params['NAME'] = txnData.name;
509
+ params['PRODUCT_NAME'] = txnData.pname;
510
+
511
+
512
+ let showConfirmation =
513
+ function (err, checksum) {
514
+ res.render(vp + "init.hbs", {
515
+ action: '',
516
+ readonly: 'readonly',
517
+ BUTTON: 'Pay',
518
+ NAME: params['NAME'],
519
+ EMAIL: params['EMAIL'],
520
+ MOBILE_NO: params['MOBILE_NO'],
521
+ PRODUCT_NAME: params['PRODUCT_NAME'],
522
+ TXN_AMOUNT: params['TXN_AMOUNT'],
523
+ MID: params['MID'],
524
+ WEBSITE: params['WEBSITE'],
525
+ ORDER_ID: params['ORDER_ID'],
526
+ CUST_ID: params['CUST_ID'],
527
+ INDUSTRY_TYPE_ID: params['INDUSTRY_TYPE_ID'],
528
+ CHANNEL_ID: params['CHANNEL_ID'],
529
+ CALLBACK_URL: params['CALLBACK_URL'],
530
+ CHECKSUMHASH: checksum
531
+ })
532
+ }
533
+
534
+
535
+ if (config.paytm_url)
536
+ checksum_lib.genchecksum(params, config.KEY, showConfirmation);
537
+ else if (config.razor_url) {
538
+ showConfirmation()
539
+ } else if (config.payu_url) {
540
+ showConfirmation()
541
+ } else if (config.open_money_url) {
542
+ showConfirmation()
543
+ }
544
+
545
+ };
546
+
547
+
548
+
549
+
550
+ function onOrder(orderId) {
551
+
552
+ var txnTask = new Transaction({
553
+ orderId: orderId,
554
+ cusId: user.id,
555
+ time: Date.now(),
556
+ timeStamp: Date.now(),
557
+ status: 'INITIATED',
558
+ name: user.name,
559
+ email: user.email,
560
+ phone: user.phone,
561
+ amount: req.body.TXN_AMOUNT,
562
+ pname: req.body.PRODUCT_NAME,
563
+ extra: '',
564
+ returnUrl: req.body.RETURN_URL || ''
565
+ });
566
+
567
+ return txnTask.save().then(onTxn)
568
+ .catch(err => {
569
+
570
+ console.log(err)
571
+ if (req.body.RETURN_URL) {
572
+ res.redirect(req.body.RETURN_URL + "?status=failed")
573
+ return;
574
+ }
575
+ res.redirect('')
576
+ });
577
+ }
578
+
579
+ if ((req.body.ORDER_ID !== undefined && req.body.ORDER_ID.length > 2)) {
580
+ var myquery = { orderId: req.body.ORDER_ID };
581
+ Transaction.findOne(myquery, function (err, orderData) {
582
+ if (err || (!orderData)) {
583
+ if (gotAllParams) {
584
+ console.log("Creating new order for ", req.body.ORDER_ID)
585
+ onOrder(req.body.ORDER_ID)
586
+ }
587
+ else {
588
+ res.send({ message: "Order Not Found or missing required data: " + checkedFields.join(", "), ORDERID: req.body.ORDER_ID })
589
+ }
590
+ }
591
+ else {
592
+ onTxn(orderData);
593
+ }
594
+
595
+ }, usingMultiDbOrm ? Transaction : undefined);
596
+ }
597
+ else {
598
+ let orderId;
599
+ if (config.paytm_url) {
600
+ orderId = "pay_" + makeid(config.id_length || IDLEN)
601
+ onOrder(orderId)
602
+ }
603
+ else if (config.razor_url) {
604
+
605
+ var options = {
606
+ amount: req.body.TXN_AMOUNT * 100,
607
+ currency: "INR",
608
+ receipt: user.id + '_' + Date.now()
609
+ };
610
+
611
+
612
+ razorPayInstance.orders.create(options, function (err, order) {
613
+ if (err) {
614
+ res.send({ message: "An error occurred ! " + err.description })
615
+ return;
616
+ }
617
+ orderId = order.id
618
+ onOrder(orderId)
619
+ })
620
+ }
621
+ else if (config.open_money_url) {
622
+ orderId = "pay_" + makeid(config.id_length || IDLEN)
623
+ onOrder(orderId)
624
+ } else if (config.payu_url) {
625
+ orderId = "payu_" + makeid(config.id_length || IDLEN)
626
+ onOrder(orderId)
627
+ }
628
+
629
+
630
+
631
+ }
632
+
633
+
634
+
635
+
636
+
637
+
638
+ });
639
+
640
+
641
+ }
642
+ else {
643
+
644
+
645
+ res.render(vp + "init.hbs", {
646
+
647
+ action: '',
648
+ readonly: '',
649
+ check: true,
650
+ BUTTON: 'Submit',
651
+ NAME: (req.body.NAME === undefined ? '' : req.body.NAME),
652
+ EMAIL: (req.body.EMAIL === undefined ? '' : req.body.EMAIL),
653
+ MOBILE_NO: (req.body.MOBILE_NO === undefined ? '' : req.body.MOBILE_NO),
654
+ PRODUCT_NAME: (req.body.PRODUCT_NAME === undefined ? '' : req.body.PRODUCT_NAME),
655
+ TXN_AMOUNT: (req.body.TXN_AMOUNT === undefined ? '' : req.body.TXN_AMOUNT),
656
+ MID: config.MID,
657
+ WEBSITE: config.WEBSITE,
658
+ ORDER_ID: '',
659
+ CUST_ID: '',
660
+ INDUSTRY_TYPE_ID: config.INDUSTRY_TYPE_ID,
661
+ CHANNEL_ID: config.CHANNEL_ID,
662
+ CALLBACK_URL: config.CALLBACK_URL,
663
+ CHECKSUMHASH: ''
664
+
665
+ })
666
+
667
+ }
668
+
669
+ }
670
+
671
+ function updateTransaction(req, res) {
672
+ var myquery = { orderId: req.body.ORDERID };
673
+
674
+ Transaction.findOne(myquery, function (err, objForUpdate) {
675
+ let returnUrl = objForUpdate ? objForUpdate.returnUrl : null;
676
+ if (returnUrl == 'undefined') {
677
+ returnUrl = undefined
678
+ }
679
+ if (err || !objForUpdate) {
680
+ if (returnUrl) {
681
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
682
+ returnUrl = returnUrl + separator + 'status=FAILED&message=txn_not_found&ORDERID=' + req.body.ORDERID;
683
+ return res.redirect(returnUrl);
684
+ }
685
+ res.send({ message: "Transaction Not Found !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
686
+ return;
687
+ }
688
+ if (objForUpdate.status != ("INITIATED") && objForUpdate.status != ("TXN_PENDING") && objForUpdate.status != ("PENDING")) {
689
+ objForUpdate.readonly = "readonly"
690
+ objForUpdate.action = config.homepage
691
+ if (returnUrl) {
692
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
693
+ returnUrl = returnUrl + separator + 'status=' + objForUpdate.status + '&ORDERID=' + objForUpdate.orderId + '&TXNID=' + objForUpdate.TXNID;
694
+ return res.redirect(returnUrl);
695
+ }
696
+ else {
697
+ res.render(vp + "result.hbs", objForUpdate);
698
+ }
699
+ console.log("Transaction already processed ", req.body.ORDERID)
700
+ // res.send({ message: "Transaction already processed", status: objForUpdate.status, ORDERID: objForUpdate.orderId, TXNID: objForUpdate.TXNID, TXNID: req.body.TXNID })
701
+ return;
702
+ }
703
+ if (req.body.status == "paid" && !req.body.STATUS) {
704
+ req.body.STATUS = "TXN_SUCCESS"
705
+ }
706
+ objForUpdate.status = req.body.STATUS;
707
+ objForUpdate.TXNID = req.body.TXNID;
708
+ objForUpdate.extra = JSON.stringify(req.body);
709
+
710
+ var newvalues = { $set: objForUpdate };
711
+ Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
712
+
713
+ if (err) {
714
+ if (returnUrl) {
715
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
716
+ returnUrl = returnUrl + separator + 'status=FAILED&message=update_error&ORDERID=' + req.body.ORDERID;
717
+ return res.redirect(returnUrl);
718
+ }
719
+ res.send({ message: "Error Occured !", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
720
+ }
721
+ else {
722
+
723
+ if (callbacks !== undefined)
724
+ callbacks.onFinish(req.body.ORDERID, req.body);
725
+ objForUpdate.readonly = "readonly"
726
+ objForUpdate.action = config.homepage
727
+ if (returnUrl) {
728
+ let separator = returnUrl.indexOf('?') > -1 ? '&' : '?';
729
+ returnUrl = returnUrl + separator + 'status=' + objForUpdate.status + '&ORDERID=' + objForUpdate.orderId + '&TXNID=' + objForUpdate.TXNID;
730
+ return res.redirect(returnUrl);
731
+ }
732
+ res.render(vp + "result.hbs", objForUpdate);
733
+ }
734
+ });
735
+
736
+ }, usingMultiDbOrm ? Transaction : undefined)
737
+ }
738
+
739
+ module.callback = async (req, res) => {
740
+ console.log("request_data ", req.originalUrl, JSON.stringify(req.body))
741
+
742
+ var result = false;
743
+ let isCancelled = false;
744
+ if (config.paytm_url) {
745
+ var checksumhash = req.body.CHECKSUMHASH;
746
+ if (checksumhash) {
747
+ result = checksum_lib.verifychecksum(req.body, config.KEY, checksumhash);
748
+ }
749
+ else {
750
+ let liveStatus = await new Promise((resolve, reject) => {
751
+ getStatusFromPaytm(req.body, req.body.ORDERID, (paytmResponse) => {
752
+ resolve(paytmResponse)
753
+ })
754
+ })
755
+ result = liveStatus.STATUS == req.body.STATUS;
756
+ }
757
+ if (req.body.STATUS == 'TXN_FAILURE' && req.body.CANCELLED == "cancelled" && req.body.TXNID) {
758
+ isCancelled = true;
759
+ }
760
+
761
+ }
762
+ else if (config.razor_url) {
763
+
764
+ if (req.body.razorpay_payment_id) {
765
+ result = checksum_lib.checkRazorSignature(req.body.razorpay_order_id,
766
+ req.body.razorpay_payment_id,
767
+ config.SECRET,
768
+ req.body.razorpay_signature)
769
+ if (result) {
770
+ req.body.STATUS = 'TXN_SUCCESS'
771
+ req.body.ORDERID = req.body.razorpay_order_id
772
+ req.body.TXNID = req.body.razorpay_payment_id
773
+ }
774
+ }
775
+ else {
776
+ if (req.body.error && req.body.error.metadata && JSON.parse(req.body.error.metadata)) {
777
+ let orderId = JSON.parse(req.body.error.metadata).order_id
778
+ req.body.razorpay_order_id = orderId
779
+ }
780
+ req.body.STATUS = 'TXN_FAILURE'
781
+ req.body.ORDERID = req.body.razorpay_order_id || req.query.order_id
782
+ isCancelled = true;
783
+ }
784
+ }
785
+ else if (config.payu_url) {
786
+ const payuRest = await payuInstance.verifyResult(req);
787
+ result = payuRest.valid;
788
+ req.body.STATUS = payuRest.STATUS;
789
+ req.body.TXNID = payuRest.TXNID;
790
+ req.body.ORDERID = payuRest.ORDERID || req.query.order_id;
791
+ req.body.extras = payuRest.data;
792
+ result = true;
793
+ isCancelled = payuRest.cancelled;
794
+ }
795
+ else if (config.open_money_url) {
796
+ let openRest = await openMoneyInstance.verifyResult(req);
797
+ result = true;
798
+ req.body.STATUS = openRest.STATUS
799
+ req.body.TXNID = openRest.TXNID
800
+ req.body.ORDERID = openRest.ORDERID || req.query.order_id
801
+ req.body.extras = openRest.data
802
+ }
803
+
804
+
805
+ //console.log("Checksum Result => ", result, "\n");
806
+ console.log("NodePayTMPG::Transaction => ", req.body.ORDERID, req.body.STATUS);
807
+ //console.log(req.body)
808
+
809
+ if (result || isCancelled) {
810
+
811
+ updateTransaction(req, res);
812
+
813
+ }
814
+ else {
815
+
816
+ res.send({ message: "Something went wrong ! Please try again later .", ORDERID: req.body.ORDERID, TXNID: req.body.TXNID })
817
+
818
+ }
819
+
820
+ }
821
+
822
+ module.webhook = (req, res) => {
823
+
824
+
825
+
826
+ console.log("request_data ", req.originalUrl, JSON.stringify(req.body))
827
+
828
+ if (config.paytm_url) {
829
+ module.callback(req, res)
830
+ }
831
+ else if (config.razor_url) {
832
+ let events = ["payment.captured", "payment.pending", "payment.failed"]
833
+ if (req.body.event && events.indexOf(req.body.event) > -1) {
834
+ if (req.body.payload &&
835
+ req.body.payload.payment &&
836
+ req.body.payload.payment.entity) {
837
+
838
+ let entity = req.body.payload.payment.entity;
839
+ let razorpay_order_id = entity.order_id;
840
+ let razorpay_payment_id = entity.id;
841
+ let status = entity.status;
842
+ let event = req.body.event;
843
+ console.log(`Razorpay webhook payment order=${razorpay_order_id} payid=${razorpay_payment_id} status=${status}`)
844
+
845
+ let reqBody = req.rawBody, signature = req.headers["x-razorpay-signature"];
846
+
847
+ result = RazorPay.validateWebhookSignature(reqBody, req.headers['x-razorpay-signature'], config.SECRET)
848
+ req.signatureVerified = result;
849
+ if (result) {
850
+ if (event == events[0]) {
851
+ req.body.STATUS = "TXN_SUCCESS";
852
+ }
853
+ else if (event == events[1]) { //pending
854
+ req.body.STATUS = "TXN_PENDING";
855
+ }
856
+ else { // failed
857
+ req.body.STATUS = "TXN_FAILURE";
858
+ }
859
+ req.body.ORDERID = razorpay_order_id;
860
+ req.body.TXNID = razorpay_payment_id;
861
+ setTimeout(() => {
862
+ updateTransaction(req, res)
863
+ }, 3000)
864
+ }
865
+ else {
866
+ res.status(401)
867
+ res.send({ message: "Invalid Rzpay signature" })
868
+ }
869
+ }
870
+ else {
871
+ res.status(400)
872
+ res.send({ message: "Invalid Payload" })
873
+ }
874
+ }
875
+ else {
876
+ res.status(400)
877
+ res.send({ message: "Unsupported event : " + req.body.event })
878
+ }
879
+ }
880
+ else if (config.payu_url) {
881
+ payuInstance.processWebhook(req, res, updateTransaction)
882
+ }
883
+ else if (config.open_money_url) {
884
+ openMoneyInstance.processWebhook(req, res, updateTransaction)
885
+ }
886
+ }
887
+
888
+ module.createTxn = (req, res) => {
889
+
890
+
891
+ useController.create({ name: req.body.NAME, email: req.body.EMAIL, phone: req.body.MOBILE_NO },
892
+ async function (user) {
893
+
894
+
895
+ let id;
896
+ if (config.paytm_url) {
897
+ id = "pay_" + makeid(config.id_length || IDLEN)
898
+ }
899
+ else if (config.razor_url) {
900
+
901
+ var options = {
902
+ amount: req.body.TXN_AMOUNT * 100,
903
+ currency: "INR",
904
+ receipt: user.id + '_' + Date.now()
905
+ };
906
+ let order = await razorPayInstance.orders.create(options);
907
+ id = order.id;
908
+ }
909
+ else if (config.payu_url) {
910
+ id = "payu_" + makeid(config.id_length || IDLEN)
911
+ }
912
+ else if (config.open_money_url) {
913
+ id = "pay_" + makeid(config.id_length || IDLEN)
914
+ }
915
+
916
+ var txnTask = new Transaction({
917
+ id: id,
918
+ orderId: id,
919
+ cusId: user.id,
920
+ time: Date.now(),
921
+ status: 'INITIATED',
922
+ name: user.name,
923
+ email: user.email,
924
+ phone: user.phone,
925
+ amount: req.body.TXN_AMOUNT,
926
+ pname: req.body.PRODUCT_NAME,
927
+ returnUrl: req.body.RETURN_URL || '',
928
+ extra: (req.body.EXTRA || '')
929
+
930
+ });
931
+
932
+
933
+ txnTask.save().then(function (txn) {
934
+ var urlData64 = nodeBase64.encode(JSON.stringify({
935
+ NAME: txn.name,
936
+ EMAIL: txn.email,
937
+ MOBILE_NO: txn.phone,
938
+ ORDER_ID: txn.orderId,
939
+ RETURN_URL: txn.returnUrl,
940
+ TXN_AMOUNT: txn.amount,
941
+ PRODUCT_NAME: txn.pname
942
+ }))
943
+
944
+ txn.payurl = config.host_url + '/' + config.path_prefix + '/init?to=' + urlData64;
945
+ res.send(txn)
946
+ })
947
+ .catch(err => {
948
+
949
+ console.log(err)
950
+
951
+ res.redirect('')
952
+ });
953
+
954
+
955
+ });
956
+
957
+
958
+
959
+ };
960
+
961
+ module.createTxnToken = (req, res) => {
962
+
963
+
964
+ module.createTxn(req, {
965
+ send: function (createTxnResult) {
966
+
967
+ // console.log(createTxnResult)
968
+
969
+ req.body.NAME = createTxnResult.name
970
+ req.body.EMAIL = createTxnResult.email
971
+ req.body.MOBILE_NO = createTxnResult.phone
972
+ req.body.ORDER_ID = createTxnResult.orderId
973
+ req.body.RETURN_URL = createTxnResult.returnUrl
974
+ module.init(req, {
975
+ render: (renderPath, initResultRender) => {
976
+ // console.log(initResultRender)
977
+ req.body = initResultRender
978
+
979
+ module.init(req, {
980
+ send: (initResult) => {
981
+
982
+ },
983
+ status: (status) => {
984
+ console.log('status', status)
985
+
986
+ },
987
+ token: (tokenData) => {
988
+ if (!tokenData) {
989
+ res.status(500)
990
+ res.send('Something went wrong. Please try again later.')
991
+ }
992
+ else {
993
+ tokenData.payurl = createTxnResult.payurl;
994
+ res.send(tokenData)
995
+ }
996
+ },
997
+ render: (renderPath2, init2ResultRender) => {
998
+ console.log('init2ResultRender', init2ResultRender)
999
+ },
1000
+ end: (initResultWrite) => {
1001
+ console.log('initResultWrite', initResultWrite)
1002
+ },
1003
+ write: (initResultWrite) => {
1004
+ console.log('initResultWrite', initResultWrite)
1005
+ },
1006
+ writeHead: (initResultWriteHead) => {
1007
+ console.log('initResultWriteHead', initResultWriteHead)
1008
+ }
1009
+
1010
+ })
1011
+
1012
+ }
1013
+ })
1014
+ },
1015
+ redirect: res.redirect
1016
+ })
1017
+
1018
+
1019
+ };
1020
+
1021
+
1022
+ module.status = (req, res) => {
1023
+
1024
+ if (!req.body.ORDER_ID && req.query.ORDER_ID) {
1025
+ req.body.ORDER_ID = req.query.ORDER_ID
1026
+ }
1027
+ var myquery = { orderId: req.body.ORDER_ID };
1028
+ Transaction.findOne(myquery, async function (err, orderData) {
1029
+
1030
+
1031
+ if (err) {
1032
+ res.send(err)
1033
+ return
1034
+ }
1035
+ if (orderData.status === "INITIATED") {
1036
+
1037
+ var params = {}
1038
+ params["MID"] = config.MID;
1039
+ params["ORDERID"] = req.body.ORDER_ID;
1040
+
1041
+ async function onStatusUpdate(paytmResponse) {
1042
+ if (paytmResponse.TXNID.length > 4) {
1043
+ orderData.status = paytmResponse.STATUS;
1044
+ orderData.extra = JSON.stringify(paytmResponse);
1045
+
1046
+ var newvalues = { $set: orderData };
1047
+ Transaction.updateOne(myquery, newvalues, function (err, saveRes) {
1048
+
1049
+ if (err) {
1050
+ res.send({ message: "Error Occured !", ORDERID: paytmResponse.ORDERID, TXNID: paytmResponse.TXNID })
1051
+ }
1052
+ else {
1053
+ if (callbacks !== undefined)
1054
+ callbacks.onFinish(req.body.ORDER_ID, orderData);
1055
+ res.send(paytmResponse)
1056
+ }
1057
+ });
1058
+ }
1059
+ else {
1060
+ res.send(orderData)
1061
+
1062
+ }
1063
+ }
1064
+
1065
+ if (config.paytm_url) {
1066
+ getStatusFromPaytm(params, req.body.ORDER_ID, onStatusUpdate)
1067
+ }
1068
+ else if (config.razor_url) {
1069
+ let result = await razorPayInstance.orders.fetch(req.body.ORDER_ID)
1070
+ result.ORDERID = req.body.ORDER_ID
1071
+ if (result.status == 'paid' && result.amount_due == 0) {
1072
+ result.STATUS = 'TXN_SUCCESS'
1073
+ let payments = await razorPayInstance.orders.fetchPayments(req.body.ORDER_ID)
1074
+ payments.items.forEach(item => {
1075
+ if (item.status == 'captured') {
1076
+ result.TXNID = item.id
1077
+ }
1078
+ });
1079
+ result.payments = payments;
1080
+
1081
+ onStatusUpdate(result)
1082
+ }
1083
+ else {
1084
+ res.send(orderData);
1085
+ }
1086
+ }
1087
+ else if (config.payu_url) {
1088
+ let result = await payuInstance.getPaymentStatus(req.body.ORDER_ID)
1089
+ if (result && result.transaction_details && result.transaction_details[req.body.ORDER_ID]) {
1090
+ let txn = result.transaction_details[req.body.ORDER_ID];
1091
+ let status = 'TXN_FAILURE'
1092
+ if (txn.status == 'success') {
1093
+ status = 'TXN_SUCCESS'
1094
+ }
1095
+ else if (txn.status == 'pending') {
1096
+ status = 'TXN_PENDING'
1097
+ }
1098
+ onStatusUpdate({
1099
+ STATUS: status,
1100
+ ORDERID: req.body.ORDER_ID,
1101
+ TXNID: txn.mihpayid || txn.txnid,
1102
+ payu: txn
1103
+ })
1104
+ }
1105
+ else {
1106
+ res.send(orderData);
1107
+ }
1108
+ }
1109
+ else if (config.open_money_url) {
1110
+ let extras = JSON.parse(orderData.extra)
1111
+ if (!extras || !extras.layer_pay_token_id) {
1112
+ res.status(500)
1113
+ return res.send({ message: 'An unexpected error occured. No payment token exists' })
1114
+ }
1115
+ let result = await openMoneyInstance.getPaymentStatus(extras.layer_pay_token_id)
1116
+ result = JSON.parse(result)
1117
+ result.ORDERID = req.body.ORDER_ID
1118
+ if (result.status == 'paid' || result.status == 'captured') {
1119
+ result.STATUS = 'TXN_SUCCESS'
1120
+ result.TXNID = result.id
1121
+ onStatusUpdate(result)
1122
+ }
1123
+ else if (result.status == 'pending' || result.status == 'attempted') {
1124
+ result.STATUS = 'TXN_PENDING'
1125
+ result.TXNID = result.id
1126
+ onStatusUpdate(result)
1127
+ }
1128
+ // else if (result.status == 'failed' || result.status == 'cancelled') {
1129
+ // result.STATUS = 'TXN_FAILED'
1130
+ // result.TXNID = result.id
1131
+ // onStatusUpdate(result)
1132
+ // }
1133
+ else {
1134
+ res.send(orderData);
1135
+ }
1136
+ }
1137
+
1138
+ }
1139
+ else {
1140
+ res.send(orderData);
1141
+ }
1142
+
1143
+
1144
+ }, usingMultiDbOrm ? Transaction : undefined);
1145
+
1146
+
1147
+ }
1148
+
1149
+ function getStatusFromPaytm(params, orderId, cb) {
1150
+ checksum_lib.genchecksum(params, config.KEY, function (err, checksum) {
1151
+
1152
+ request.post(
1153
+ config.paytm_url + "/order/status",
1154
+ { json: { MID: config.MID, ORDERID: orderId, CHECKSUMHASH: checksum, } },
1155
+ function (error, response, body) {
1156
+
1157
+ if (!error && response.statusCode == 200) {
1158
+ var paytmResponse = JSON.parse(JSON.stringify(body))
1159
+ cb(paytmResponse)
1160
+ }
1161
+ else {
1162
+ console.log('ERROR:::', error, '\n', response);
1163
+ cb({ message: "Error Occured !", ORDERID: orderId })
1164
+ }
1165
+ }
1166
+ );
1167
+ });
1168
+ }
1169
+
1170
+ return module;
1171
+ }