node-paytmpg 6.4.7 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +132 -182
- package/app/views/layouts/index.hbs +7 -7
- package/app/views/result.hbs +1 -1
- package/dist/app/controllers/adapters/open_money.js +400 -0
- package/dist/app/controllers/adapters/paytm.js +34 -0
- package/{app → dist/app}/controllers/adapters/payu.js +208 -239
- package/dist/app/controllers/checksum/PaytmChecksum.js +118 -0
- package/dist/app/controllers/checksum/checksum.js +158 -0
- package/dist/app/controllers/checksum/crypt.js +117 -0
- package/dist/app/controllers/checksum/server.js +130 -0
- package/dist/app/controllers/payment.controller.js +985 -0
- package/dist/app/controllers/static/loadingsvg.js +54 -0
- package/dist/app/controllers/user.controller.js +53 -0
- package/dist/app/models/index.js +2 -0
- package/dist/app/routes/payment_route.js +46 -0
- package/dist/app/utils/buildConfig.js +210 -0
- package/dist/app/utils/utils.js +20 -0
- package/dist/app/views/home.hbs +22 -0
- package/dist/app/views/init.hbs +98 -0
- package/dist/app/views/layouts/index.hbs +53 -0
- package/dist/app/views/result.hbs +33 -0
- package/dist/index.js +119 -0
- package/dist/package.json +67 -0
- package/dist/public/css/style.css +455 -0
- package/dist/public/js/index.js +283 -0
- package/dist/public/layer_checkout.js +38 -0
- package/dist/public/pay.png +0 -0
- package/dist/public/start.png +0 -0
- package/dist/public/start2.png +0 -0
- package/dist/public/stat.png +0 -0
- package/dist/public/test.html +24 -0
- package/dist/public/test.html~ +24 -0
- package/package.json +29 -6
- package/public/test.html~ +24 -0
- package/.github/workflows/codeql-analysis.yml +0 -71
- package/.github/workflows/nodejs.yml +0 -24
- package/.github/workflows/npm-publish.yml +0 -23
- package/Dockerfile +0 -9
- package/app/controllers/adapters/open_money.js +0 -515
- package/app/controllers/checksum/PaytmChecksum.js +0 -94
- package/app/controllers/checksum/checksum.js +0 -154
- package/app/controllers/checksum/crypt.js +0 -98
- package/app/controllers/checksum/server.js +0 -132
- package/app/controllers/np_user.controller.js +0 -89
- package/app/controllers/payment_controller.js +0 -1295
- package/app/models/np_multidbplugin.js +0 -111
- package/app/models/np_transaction.model.js +0 -16
- package/app/models/np_user.model.js +0 -12
- package/app/routes/payment_route.js +0 -73
- package/app.yaml +0 -18
- package/example.js +0 -34
- package/index.js +0 -90
- package/lib/config/buildConfig.js +0 -113
- package/lib/config/defaults.js +0 -37
- package/lib/config/validator.js +0 -103
- package/lib/services/database.service.js +0 -153
- package/lib/utils/id-generator.js +0 -30
- package/lib/utils/sanitizer.js +0 -25
|
@@ -1,229 +1,199 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
payload.
|
|
30
|
-
|
|
31
|
-
payload.
|
|
32
|
-
payload.
|
|
33
|
-
payload.
|
|
34
|
-
payload.
|
|
35
|
-
payload.
|
|
36
|
-
payload.
|
|
37
|
-
payload.
|
|
38
|
-
payload.
|
|
39
|
-
payload.
|
|
40
|
-
payload.
|
|
41
|
-
payload.
|
|
42
|
-
payload.
|
|
43
|
-
payload.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
buildResponseHash(data) {
|
|
50
|
-
const amount = this.normalizeAmount(data.amount);
|
|
51
|
-
const sequence = [
|
|
52
|
-
data.additionalCharges || null,
|
|
53
|
-
this.config.salt,
|
|
54
|
-
data.status || '',
|
|
55
|
-
'', '', '', '', '', '', '', '', '', '',
|
|
56
|
-
data.udf5 || '',
|
|
57
|
-
data.udf4 || '',
|
|
58
|
-
data.udf3 || '',
|
|
59
|
-
data.udf2 || '',
|
|
60
|
-
data.udf1 || '',
|
|
61
|
-
data.email || '',
|
|
62
|
-
data.firstname || '',
|
|
63
|
-
data.productinfo || '',
|
|
64
|
-
amount,
|
|
65
|
-
data.txnid || '',
|
|
66
|
-
data.key || ''
|
|
67
|
-
];
|
|
68
|
-
const filtered = sequence.filter((
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
status
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
* @param {*} paymentmode optional
|
|
198
|
-
* @param {*} productype optional
|
|
199
|
-
* @returns
|
|
200
|
-
*/
|
|
201
|
-
async checkBqrTxnStatus(transactionId) {
|
|
202
|
-
return this.postCommand('verify_payment', transactionId);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
renderProcessingPage(params, paymentReq, res, loadingSVG) {
|
|
206
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
207
|
-
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>`);
|
|
208
|
-
res.end();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
renderError(params, error, res) {
|
|
212
|
-
console.log('ERROR:::', error, '\n');
|
|
213
|
-
res.status(500);
|
|
214
|
-
let formFields = '';
|
|
215
|
-
const errorResp = {
|
|
216
|
-
TXNID: 'na',
|
|
217
|
-
STATUS: 'TXN_FAILURE',
|
|
218
|
-
CANCELLED: 'cancelled',
|
|
219
|
-
ORDERID: params['ORDER_ID']
|
|
220
|
-
};
|
|
221
|
-
Object.keys(errorResp).forEach((key) => {
|
|
222
|
-
formFields += "<input type='hidden' name='" + key + "' value='" + errorResp[key] + "' >";
|
|
223
|
-
});
|
|
224
|
-
formFields += "<input type='hidden' name='CHECKSUMHASH' value='" + (params['CHECKSUM'] || '') + "' >";
|
|
225
|
-
|
|
226
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class PayU {
|
|
9
|
+
constructor(npconfig) {
|
|
10
|
+
const baseUrl = (npconfig.payu_url || '').replace(/\/$/, '');
|
|
11
|
+
const isSandbox = baseUrl.indexOf('test.payu.in') > -1;
|
|
12
|
+
const verifyUrl = npconfig.payu_verify_url || (isSandbox
|
|
13
|
+
? 'https://test.payu.in/merchant/postservice.php?form=2'
|
|
14
|
+
: 'https://info.payu.in/merchant/postservice.php?form=2');
|
|
15
|
+
this.config = {
|
|
16
|
+
key: npconfig.KEY,
|
|
17
|
+
salt: npconfig.SECRET,
|
|
18
|
+
baseUrl,
|
|
19
|
+
paymentUrl: npconfig.payu_payment_url || (baseUrl ? `${baseUrl}/_payment` : ''),
|
|
20
|
+
verifyUrl,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
normalizeAmount(amount) {
|
|
24
|
+
const value = parseFloat(amount || 0);
|
|
25
|
+
return value.toFixed(2);
|
|
26
|
+
}
|
|
27
|
+
buildRequestHash(payload) {
|
|
28
|
+
const parts = [
|
|
29
|
+
payload.key,
|
|
30
|
+
payload.txnid,
|
|
31
|
+
this.normalizeAmount(payload.amount),
|
|
32
|
+
payload.productinfo,
|
|
33
|
+
payload.firstname,
|
|
34
|
+
payload.email,
|
|
35
|
+
payload.udf1 || '',
|
|
36
|
+
payload.udf2 || '',
|
|
37
|
+
payload.udf3 || '',
|
|
38
|
+
payload.udf4 || '',
|
|
39
|
+
payload.udf5 || '',
|
|
40
|
+
payload.udf6 || '',
|
|
41
|
+
payload.udf7 || '',
|
|
42
|
+
payload.udf8 || '',
|
|
43
|
+
payload.udf9 || '',
|
|
44
|
+
payload.udf10 || '',
|
|
45
|
+
this.config.salt,
|
|
46
|
+
];
|
|
47
|
+
return crypto_1.default.createHash('sha512').update(parts.join('|')).digest('hex');
|
|
48
|
+
}
|
|
49
|
+
buildResponseHash(data) {
|
|
50
|
+
const amount = this.normalizeAmount(data.amount);
|
|
51
|
+
const sequence = [
|
|
52
|
+
data.additionalCharges || null,
|
|
53
|
+
this.config.salt,
|
|
54
|
+
data.status || '',
|
|
55
|
+
'', '', '', '', '', '', '', '', '', '',
|
|
56
|
+
data.udf5 || '',
|
|
57
|
+
data.udf4 || '',
|
|
58
|
+
data.udf3 || '',
|
|
59
|
+
data.udf2 || '',
|
|
60
|
+
data.udf1 || '',
|
|
61
|
+
data.email || '',
|
|
62
|
+
data.firstname || '',
|
|
63
|
+
data.productinfo || '',
|
|
64
|
+
amount,
|
|
65
|
+
data.txnid || '',
|
|
66
|
+
data.key || '',
|
|
67
|
+
];
|
|
68
|
+
const filtered = sequence.filter((value) => value !== null);
|
|
69
|
+
return crypto_1.default.createHash('sha512').update(filtered.join('|')).digest('hex');
|
|
70
|
+
}
|
|
71
|
+
generatePaymentRequest(params) {
|
|
72
|
+
const payload = {
|
|
73
|
+
key: this.config.key,
|
|
74
|
+
txnid: params.ORDER_ID,
|
|
75
|
+
amount: this.normalizeAmount(params.TXN_AMOUNT),
|
|
76
|
+
productinfo: params.PRODUCT_NAME,
|
|
77
|
+
firstname: params.NAME,
|
|
78
|
+
email: params.EMAIL,
|
|
79
|
+
phone: params.MOBILE_NO,
|
|
80
|
+
surl: params.CALLBACK_URL,
|
|
81
|
+
furl: params.CALLBACK_URL,
|
|
82
|
+
udf1: params.CUST_ID || '',
|
|
83
|
+
udf2: params.ORDER_ID || '',
|
|
84
|
+
service_provider: 'payu_paisa',
|
|
85
|
+
};
|
|
86
|
+
payload.hash = this.buildRequestHash(payload);
|
|
87
|
+
const formFields = Object.keys(payload)
|
|
88
|
+
.map((key) => `<input type='hidden' name='${key}' value='${payload[key]}' />`)
|
|
89
|
+
.join('');
|
|
90
|
+
const html = `<form action='${this.config.paymentUrl}' method='post' id='payu_payment_form' style='display:none'>${formFields}</form><script>document.getElementById('payu_payment_form').submit();</script>`;
|
|
91
|
+
return { html, payload };
|
|
92
|
+
}
|
|
93
|
+
decodeTransactionResponse(txnDataBase64FromPayu) {
|
|
94
|
+
const txnDataJson = Buffer.from(txnDataBase64FromPayu, 'base64').toString('utf-8');
|
|
95
|
+
return JSON.parse(txnDataJson);
|
|
96
|
+
}
|
|
97
|
+
async verifyResult(req) {
|
|
98
|
+
var _a, _b, _c;
|
|
99
|
+
const originalBody = req.body || {};
|
|
100
|
+
const lookupId = originalBody.txnid || ((_a = req.query) === null || _a === void 0 ? void 0 : _a.order_id);
|
|
101
|
+
const statusResp = await this.checkBqrTxnStatus(lookupId);
|
|
102
|
+
let resData = null;
|
|
103
|
+
if (!resData && statusResp && statusResp.transaction_details) {
|
|
104
|
+
const td = statusResp.transaction_details;
|
|
105
|
+
if (td[lookupId]) {
|
|
106
|
+
resData = td[lookupId];
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
for (const key of Object.keys(td)) {
|
|
110
|
+
const txn = td[key];
|
|
111
|
+
if (!txn)
|
|
112
|
+
continue;
|
|
113
|
+
if ((txn.txnid && txn.txnid.toString() === lookupId) || key.toString().endsWith(lookupId)) {
|
|
114
|
+
resData = txn;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const source = resData || statusResp || originalBody;
|
|
121
|
+
const msg = ((statusResp === null || statusResp === void 0 ? void 0 : statusResp.msg) || '').toString();
|
|
122
|
+
const statusText = (source.status || source.unmappedstatus || msg || '').toString().toLowerCase();
|
|
123
|
+
let status = 'TXN_FAILURE';
|
|
124
|
+
if (statusText.includes('success') || statusText.includes('completed') || statusText.includes('captured')) {
|
|
125
|
+
status = 'TXN_SUCCESS';
|
|
126
|
+
}
|
|
127
|
+
else if (statusText.includes('pending')) {
|
|
128
|
+
status = 'TXN_PENDING';
|
|
129
|
+
}
|
|
130
|
+
const orderId = (source.udf2 || source.order_id || source.txnid || lookupId).toString();
|
|
131
|
+
const txnId = source.mihpayid || source.txnid || null;
|
|
132
|
+
return {
|
|
133
|
+
STATUS: status,
|
|
134
|
+
ORDERID: orderId,
|
|
135
|
+
TXNID: txnId,
|
|
136
|
+
data: resData || statusResp || originalBody,
|
|
137
|
+
cancelled: ((_c = (_b = source.unmappedstatus) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b).includes('cancelled')) || false,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async getPaymentStatus(txnId) {
|
|
141
|
+
const verifyPayload = new URLSearchParams();
|
|
142
|
+
verifyPayload.append('key', this.config.key || '');
|
|
143
|
+
verifyPayload.append('command', 'verify_payment');
|
|
144
|
+
verifyPayload.append('var1', txnId || '');
|
|
145
|
+
const hashString = [this.config.key, 'verify_payment', txnId, this.config.salt].join('|');
|
|
146
|
+
verifyPayload.append('hash', crypto_1.default.createHash('sha512').update(hashString).digest('hex'));
|
|
147
|
+
try {
|
|
148
|
+
const response = await axios_1.default.post(this.config.verifyUrl, verifyPayload.toString(), {
|
|
149
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
150
|
+
});
|
|
151
|
+
return response.data;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
return { error: error.message };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async postCommand(command, transactionId) {
|
|
158
|
+
const payload = new URLSearchParams();
|
|
159
|
+
payload.append('key', this.config.key || '');
|
|
160
|
+
payload.append('command', command || '');
|
|
161
|
+
payload.append('var1', transactionId || '');
|
|
162
|
+
const hashString = [this.config.key, command, transactionId, this.config.salt].join('|');
|
|
163
|
+
payload.append('hash', crypto_1.default.createHash('sha512').update(hashString).digest('hex'));
|
|
164
|
+
try {
|
|
165
|
+
const response = await axios_1.default.post(this.config.verifyUrl, payload.toString(), {
|
|
166
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
167
|
+
});
|
|
168
|
+
return response.data;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return { error: error.message };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async checkBqrTxnStatus(transactionId) {
|
|
175
|
+
return this.postCommand('verify_payment', transactionId);
|
|
176
|
+
}
|
|
177
|
+
renderProcessingPage(params, paymentReq, res, loadingSVG) {
|
|
178
|
+
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>`);
|
|
180
|
+
res.end();
|
|
181
|
+
}
|
|
182
|
+
renderError(params, error, res) {
|
|
183
|
+
console.log('ERROR:::', error, '\n');
|
|
184
|
+
res.status(500);
|
|
185
|
+
let formFields = '';
|
|
186
|
+
const errorResp = {
|
|
187
|
+
TXNID: 'na',
|
|
188
|
+
STATUS: 'TXN_FAILURE',
|
|
189
|
+
CANCELLED: 'cancelled',
|
|
190
|
+
ORDERID: params.ORDER_ID,
|
|
191
|
+
};
|
|
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 || ''}' >`;
|
|
196
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
227
197
|
res.write(`<html>
|
|
228
198
|
|
|
229
199
|
<head>
|
|
@@ -234,18 +204,17 @@ class PayU {
|
|
|
234
204
|
<center>
|
|
235
205
|
<h1>Something went wrong. Please wait you will be redirected automatically...</h1>
|
|
236
206
|
</center>
|
|
237
|
-
<form method=
|
|
238
|
-
<script type=
|
|
207
|
+
<form method='post' action='${params.CALLBACK_URL}' name='f1'>${formFields}</form>
|
|
208
|
+
<script type='text/javascript'>document.f1.submit();</script>
|
|
239
209
|
</body>
|
|
240
210
|
|
|
241
|
-
</html>`);
|
|
242
|
-
res.end();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
res.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
module.exports = PayU;
|
|
211
|
+
</html>`);
|
|
212
|
+
res.end();
|
|
213
|
+
}
|
|
214
|
+
processWebhook(req, res, updateTransaction) {
|
|
215
|
+
res.status(201);
|
|
216
|
+
res.send({ message: 'Webhook not implemented for PayU' });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.default = PayU;
|
|
220
|
+
module.exports = PayU;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const crypto = __importStar(require("crypto"));
|
|
37
|
+
class PaytmChecksum {
|
|
38
|
+
static encrypt(input, key) {
|
|
39
|
+
const cipher = crypto.createCipheriv('AES-128-CBC', key, PaytmChecksum.iv);
|
|
40
|
+
let encrypted = cipher.update(input, 'binary', 'base64');
|
|
41
|
+
encrypted += cipher.final('base64');
|
|
42
|
+
return encrypted;
|
|
43
|
+
}
|
|
44
|
+
static decrypt(encrypted, key) {
|
|
45
|
+
const decipher = crypto.createDecipheriv('AES-128-CBC', key, PaytmChecksum.iv);
|
|
46
|
+
let decrypted = decipher.update(encrypted, 'base64', 'binary');
|
|
47
|
+
try {
|
|
48
|
+
decrypted += decipher.final('binary');
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.log(e);
|
|
52
|
+
}
|
|
53
|
+
return decrypted;
|
|
54
|
+
}
|
|
55
|
+
static generateSignature(params, key) {
|
|
56
|
+
if (typeof params !== 'object' && typeof params !== 'string') {
|
|
57
|
+
const error = 'string or object expected, ' + (typeof params) + ' given.';
|
|
58
|
+
return Promise.reject(error);
|
|
59
|
+
}
|
|
60
|
+
if (typeof params !== 'string') {
|
|
61
|
+
params = PaytmChecksum.getStringByParams(params);
|
|
62
|
+
}
|
|
63
|
+
return PaytmChecksum.generateSignatureByString(params, key);
|
|
64
|
+
}
|
|
65
|
+
static verifySignature(params, key, checksum) {
|
|
66
|
+
if (typeof params !== 'object' && typeof params !== 'string') {
|
|
67
|
+
const error = 'string or object expected, ' + (typeof params) + ' given.';
|
|
68
|
+
return Promise.reject(error);
|
|
69
|
+
}
|
|
70
|
+
if (typeof params !== 'string') {
|
|
71
|
+
if (params.hasOwnProperty('CHECKSUMHASH')) {
|
|
72
|
+
delete params.CHECKSUMHASH;
|
|
73
|
+
}
|
|
74
|
+
params = PaytmChecksum.getStringByParams(params);
|
|
75
|
+
}
|
|
76
|
+
return PaytmChecksum.verifySignatureByString(params, key, checksum);
|
|
77
|
+
}
|
|
78
|
+
static async generateSignatureByString(params, key) {
|
|
79
|
+
const salt = await PaytmChecksum.generateRandomString(4);
|
|
80
|
+
return PaytmChecksum.calculateChecksum(params, key, salt);
|
|
81
|
+
}
|
|
82
|
+
static verifySignatureByString(params, key, checksum) {
|
|
83
|
+
const paytm_hash = PaytmChecksum.decrypt(checksum, key);
|
|
84
|
+
const salt = paytm_hash.substr(paytm_hash.length - 4);
|
|
85
|
+
return (paytm_hash === PaytmChecksum.calculateHash(params, salt));
|
|
86
|
+
}
|
|
87
|
+
static generateRandomString(length) {
|
|
88
|
+
return new Promise(function (resolve, reject) {
|
|
89
|
+
crypto.randomBytes((length * 3.0) / 4.0, function (err, buf) {
|
|
90
|
+
if (!err) {
|
|
91
|
+
const salt = buf.toString('base64');
|
|
92
|
+
resolve(salt);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.log('error occurred in generateRandomString: ' + err);
|
|
96
|
+
reject(err);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
static getStringByParams(params) {
|
|
102
|
+
const data = {};
|
|
103
|
+
Object.keys(params).sort().forEach(function (key) {
|
|
104
|
+
data[key] = (params[key] !== null && String(params[key]).toLowerCase() !== 'null') ? params[key] : '';
|
|
105
|
+
});
|
|
106
|
+
return Object.values(data).join('|');
|
|
107
|
+
}
|
|
108
|
+
static calculateHash(params, salt) {
|
|
109
|
+
const finalString = params + '|' + salt;
|
|
110
|
+
return crypto.createHash('sha256').update(finalString).digest('hex') + salt;
|
|
111
|
+
}
|
|
112
|
+
static calculateChecksum(params, key, salt) {
|
|
113
|
+
const hashString = PaytmChecksum.calculateHash(params, salt);
|
|
114
|
+
return PaytmChecksum.encrypt(hashString, key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
PaytmChecksum.iv = '@@@@&&&&####$$$$';
|
|
118
|
+
exports.default = PaytmChecksum;
|