Commit bc5bcfea87edf7c94b3274a282dece731c33c4b0
1 parent
ba873b76b4
Exists in
master
pendingLimitCount
Showing 1 changed file with 31 additions and 5 deletions Inline Diff
partner-kospinjasa.js
1 | var winston = require('winston'); | 1 | var winston = require('winston'); |
2 | var soap = require('soap'); | 2 | var soap = require('soap'); |
3 | var crypto = require('crypto'); | 3 | var crypto = require('crypto'); |
4 | var strftime = require('strftime'); | 4 | var strftime = require('strftime'); |
5 | var fs = require("fs"); | 5 | var fs = require("fs"); |
6 | var http = require("http"); | 6 | var http = require("http"); |
7 | var url = require("url"); | 7 | var url = require("url"); |
8 | var mongoClient = require('mongodb').MongoClient; | 8 | var mongoClient = require('mongodb').MongoClient; |
9 | var moment = require('moment'); | 9 | var moment = require('moment'); |
10 | 10 | ||
11 | process.chdir(__dirname); | 11 | process.chdir(__dirname); |
12 | 12 | ||
13 | var max_retry = 10; | 13 | var max_retry = 10; |
14 | var sleep_before_retry = 5000; | 14 | var sleep_before_retry = 5000; |
15 | 15 | ||
16 | var config; | 16 | var config; |
17 | var matrix; | ||
17 | var callbackReport; | 18 | var callbackReport; |
18 | var aaa; | 19 | var aaa; |
19 | var logger; | 20 | var logger; |
20 | var options; | 21 | var options; |
21 | var mongodb; | 22 | var mongodb; |
22 | 23 | ||
24 | |||
23 | function start(_config, _callbackReport, options) { | 25 | function start(_config, _callbackReport, options) { |
24 | config = _config; | 26 | config = _config; |
25 | callbackReport = _callbackReport | 27 | callbackReport = _callbackReport |
26 | 28 | ||
27 | if (options && options.aaa) { | 29 | if (options && options.aaa) { |
28 | aaa = options.aaa; | 30 | aaa = options.aaa; |
29 | } | 31 | } |
30 | 32 | ||
31 | if (options && options.logger) { | 33 | if (options && options.logger) { |
32 | logger = options.logger; | 34 | logger = options.logger; |
33 | } else { | 35 | } else { |
34 | logger = new winston.Logger({ | 36 | logger = new winston.Logger({ |
35 | transports: [ | 37 | transports: [ |
36 | new (winston.transports.Console)() | 38 | new (winston.transports.Console)() |
37 | ] | 39 | ] |
38 | }); | 40 | }); |
39 | } | 41 | } |
40 | 42 | ||
43 | if (options && options.matrix) { | ||
44 | matrix = options.matrix; | ||
45 | } | ||
46 | |||
41 | initMongoClient(); | 47 | initMongoClient(); |
42 | } | 48 | } |
43 | 49 | ||
50 | function callbackReportWrapper(requestId, responseCode, message, dontIncrement) { | ||
51 | callbackReport(requestId, responseCode, message); | ||
52 | |||
53 | if (dontIncrement) { | ||
54 | return; | ||
55 | } | ||
56 | |||
57 | try { | ||
58 | aaa.incrementStrikeStatus(responseCode); | ||
59 | } catch(err) { | ||
60 | logger.warn("Gagal aaa.incrementStrikeStatus: " + err); | ||
61 | } | ||
62 | } | ||
63 | |||
44 | function initMongoClient() { | 64 | function initMongoClient() { |
45 | if (!config || !config.mongodb || !config.mongodb.url) { | 65 | if (!config || !config.mongodb || !config.mongodb.url) { |
46 | return; | 66 | return; |
47 | } | 67 | } |
48 | 68 | ||
49 | try { | 69 | try { |
50 | var url = config.mongodb.url; | 70 | var url = config.mongodb.url; |
51 | 71 | ||
52 | mongoClient.connect(url, function(err, db) { | 72 | mongoClient.connect(url, function(err, db) { |
53 | if (err) { | 73 | if (err) { |
54 | logger.warn('Failed to connect to mongodb', {err: err}); | 74 | logger.warn('Failed to connect to mongodb', {err: err}); |
55 | return; | 75 | return; |
56 | } | 76 | } |
57 | mongodb = db; | 77 | mongodb = db; |
58 | logger.info('MongoDB connected'); | 78 | logger.info('MongoDB connected'); |
59 | }); | 79 | }); |
60 | } | 80 | } |
61 | catch(err) { | 81 | catch(err) { |
62 | logger.warn('Exception when connecting to mongodb', {err: err, url: url}); | 82 | logger.warn('Exception when connecting to mongodb', {err: err, url: url}); |
63 | } | 83 | } |
64 | } | 84 | } |
65 | 85 | ||
66 | function insertTaskToMongoDb(task) { | 86 | function insertTaskToMongoDb(task) { |
67 | if (!isMongoReady()) { return; } | 87 | if (!isMongoReady()) { return; } |
68 | 88 | ||
69 | task.supplier = config.globals.gateway_name; | 89 | task.supplier = config.globals.gateway_name; |
70 | task.rc = '68'; | 90 | task.rc = '68'; |
71 | 91 | ||
72 | try { | 92 | try { |
73 | mongodb.collection(config.mongodb.collection).insertOne(task); | 93 | mongodb.collection(config.mongodb.collection).insertOne(task); |
74 | } | 94 | } |
75 | catch(err) { | 95 | catch(err) { |
76 | //logger.warn('Exception when inserting document to mongodb', {err: err, task: task}); | 96 | //logger.warn('Exception when inserting document to mongodb', {err: err, task: task}); |
77 | } | 97 | } |
78 | } | 98 | } |
79 | 99 | ||
80 | function pushResponseToMongoDb(task, response, rc) { | 100 | function pushResponseToMongoDb(task, response, rc) { |
81 | if (!isMongoReady()) { return; } | 101 | if (!isMongoReady()) { return; } |
82 | 102 | ||
83 | 103 | ||
84 | try { | 104 | try { |
85 | if (!response.ts) { | 105 | if (!response.ts) { |
86 | response.ts = strftime('%Y-%m-%d %H:%M:%S', new Date()); | 106 | response.ts = strftime('%Y-%m-%d %H:%M:%S', new Date()); |
87 | } | 107 | } |
88 | 108 | ||
89 | mongodb.collection(config.mongodb.collection).updateOne( | 109 | mongodb.collection(config.mongodb.collection).updateOne( |
90 | {requestId: task.requestId}, | 110 | {requestId: task.requestId}, |
91 | { | 111 | { |
92 | $set: { | 112 | $set: { |
93 | lastResponse: response, | 113 | lastResponse: response, |
94 | supplier: config.globals.gateway_name, | 114 | supplier: config.globals.gateway_name, |
95 | rc: rc | 115 | rc: rc |
96 | }, | 116 | }, |
97 | $push: { | 117 | $push: { |
98 | responses: response | 118 | responses: response |
99 | } | 119 | } |
100 | }, | 120 | }, |
101 | function(err, result) { | 121 | function(err, result) { |
102 | if (err) { | 122 | if (err) { |
103 | logger.warn('Error when pushing response to mongodb', {err: err, task: task, response: response}); | 123 | logger.warn('Error when pushing response to mongodb', {err: err, task: task, response: response}); |
104 | return; | 124 | return; |
105 | } | 125 | } |
106 | } | 126 | } |
107 | ); | 127 | ); |
108 | } | 128 | } |
109 | catch(err) { | 129 | catch(err) { |
110 | logger.warn('Exception when pushing response to mongodb', {err: err, task: task, response: response}); | 130 | logger.warn('Exception when pushing response to mongodb', {err: err, task: task, response: response}); |
111 | } | 131 | } |
112 | } | 132 | } |
113 | 133 | ||
114 | function isMongoReady() { | 134 | function isMongoReady() { |
115 | if (!config.mongodb) { return; } | 135 | if (!config.mongodb) { return; } |
116 | if (!config.mongodb.collection) { return; } | 136 | if (!config.mongodb.collection) { return; } |
117 | if (!mongodb) { return; } | 137 | if (!mongodb) { return; } |
118 | 138 | ||
119 | return true; | 139 | return true; |
120 | } | 140 | } |
121 | 141 | ||
122 | function topupRequest(task, retry) { | 142 | function topupRequest(task, retry) { |
143 | if (config && config.globals && config.globals.reject_on_pending_count && matrix && matrix.strikeStatus && matrix.strikeStatus.pending) { | ||
144 | if (parseInt(config.globals.reject_on_pending_count) <= matrix.strikeStatus.pending) { | ||
145 | callbackReport(task.requestId, '13', 'Reject trx karena pending terlalu banyak'); | ||
146 | return; | ||
147 | } | ||
148 | } | ||
149 | |||
123 | task.ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss'); | 150 | task.ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss'); |
124 | task.ts_date = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD'); | 151 | task.ts_date = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD'); |
125 | 152 | ||
126 | insertTaskToMongoDb(task); | 153 | insertTaskToMongoDb(task); |
127 | |||
128 | saldoCheck(billpayment, task); | 154 | saldoCheck(billpayment, task); |
129 | } | 155 | } |
130 | 156 | ||
131 | function saldoCheck(callback, task) { | 157 | function saldoCheck(callback, task) { |
132 | 158 | ||
133 | var params = { | 159 | var params = { |
134 | userName: config.h2h_out.userid, | 160 | userName: config.h2h_out.userid, |
135 | productCode: '00000' , | 161 | productCode: '00000' , |
136 | terminal: 'H2HIPN10', | 162 | terminal: 'H2HIPN10', |
137 | transactionType: '61', | 163 | transactionType: '61', |
138 | reff: Math.ceil( Math.random() * 99999999 ), | 164 | reff: Math.ceil( Math.random() * 99999999 ), |
139 | timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date()) | 165 | timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date()) |
140 | } | 166 | } |
141 | 167 | ||
142 | params.signature = createSignatureForSaldoCheck(params, config.h2h_out.password); | 168 | params.signature = createSignatureForSaldoCheck(params, config.h2h_out.password); |
143 | 169 | ||
144 | soap.createClient(config.h2h_out.partner, function(err, soapClient) { | 170 | soap.createClient(config.h2h_out.partner, function(err, soapClient) { |
145 | 171 | ||
146 | if (err) { | 172 | if (err) { |
147 | 173 | ||
148 | var errorMessage = 'Error creating soap client for saldoCheck: ' + err; | 174 | var errorMessage = 'Error creating soap client for saldoCheck: ' + err; |
149 | 175 | ||
150 | logger.warn(errorMessage, {err: err}); | 176 | logger.warn(errorMessage, {err: err}); |
151 | callbackReport(task.requestId, '40', errorMessage); | 177 | callbackReportWrapper(task.requestId, '40', errorMessage); |
152 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40'); | 178 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40'); |
153 | 179 | ||
154 | return; | 180 | return; |
155 | } | 181 | } |
156 | 182 | ||
157 | logger.info('Requesting to service', {url: config.h2h_out.partner, params: params}); | 183 | logger.info('Requesting to service', {url: config.h2h_out.partner, params: params}); |
158 | soapClient.apih2h.apih2hPort.saldoCheck({ inputSaldo: params }, function(err, result) { | 184 | soapClient.apih2h.apih2hPort.saldoCheck({ inputSaldo: params }, function(err, result) { |
159 | 185 | ||
160 | logger.verbose( | 186 | logger.verbose( |
161 | 'Got saldoCheck response', | 187 | 'Got saldoCheck response', |
162 | { | 188 | { |
163 | lastEndpoint: soapClient.lastEndpoint, | 189 | lastEndpoint: soapClient.lastEndpoint, |
164 | lastRequest: soapClient.lastRequest, | 190 | lastRequest: soapClient.lastRequest, |
165 | lastMessage: soapClient.lastMessage, | 191 | lastMessage: soapClient.lastMessage, |
166 | lastResponse: soapClient.lastResponse, | 192 | lastResponse: soapClient.lastResponse, |
167 | } | 193 | } |
168 | ); | 194 | ); |
169 | 195 | ||
170 | if (err) { | 196 | if (err) { |
171 | var errorMessage = 'Error requesting saldoCheck: ' + err; | 197 | var errorMessage = 'Error requesting saldoCheck: ' + err; |
172 | 198 | ||
173 | logger.warn(errorMessage, {err: err}); | 199 | logger.warn(errorMessage, {err: err}); |
174 | callbackReport(task.requestId, '40', errorMessage); | 200 | callbackReportWrapper(task.requestId, '40', errorMessage); |
175 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40'); | 201 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40'); |
176 | } | 202 | } |
177 | 203 | ||
178 | var balance; | 204 | var balance; |
179 | logger.verbose('saldoCheck result', {result: result}); | 205 | logger.verbose('saldoCheck result', {result: result}); |
180 | 206 | ||
181 | try { | 207 | try { |
182 | balance = result.outputParameter.bit61.$value; | 208 | balance = result.outputParameter.bit61.$value; |
183 | } | 209 | } |
184 | catch(e) { | 210 | catch(e) { |
185 | balance = 'UNKNOWN'; | 211 | balance = 'UNKNOWN'; |
186 | } | 212 | } |
187 | 213 | ||
188 | 214 | ||
189 | if (task) { | 215 | if (task) { |
190 | callback(task, balance); | 216 | callback(task, balance); |
191 | } | 217 | } |
192 | }); | 218 | }); |
193 | }); | 219 | }); |
194 | 220 | ||
195 | } | 221 | } |
196 | 222 | ||
197 | function billpayment(task, balance) { | 223 | function billpayment(task, balance) { |
198 | 224 | ||
199 | var terminalSuffix = Math.ceil( Math.random() * 20 ) + 10; | 225 | var terminalSuffix = Math.ceil( Math.random() * 20 ) + 10; |
200 | var remoteProduct = task.remoteProduct.split(','); | 226 | var remoteProduct = task.remoteProduct.split(','); |
201 | 227 | ||
202 | var params = { | 228 | var params = { |
203 | userName: config.h2h_out.userid, | 229 | userName: config.h2h_out.userid, |
204 | productCode: remoteProduct[0] , | 230 | productCode: remoteProduct[0] , |
205 | terminal: 'H2HIPN' + terminalSuffix, | 231 | terminal: 'H2HIPN' + terminalSuffix, |
206 | transactionType: '50', | 232 | transactionType: '50', |
207 | billNumber: createBillNumber(task.destination), | 233 | billNumber: createBillNumber(task.destination), |
208 | amount: remoteProduct[1], | 234 | amount: remoteProduct[1], |
209 | bit61: createBillNumber(task.destination), | 235 | bit61: createBillNumber(task.destination), |
210 | reff: task.requestId, | 236 | reff: task.requestId, |
211 | timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date()) | 237 | timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date()) |
212 | } | 238 | } |
213 | 239 | ||
214 | var signature = createSignature(params, config.h2h_out.password); | 240 | var signature = createSignature(params, config.h2h_out.password); |
215 | params.signature = signature; | 241 | params.signature = signature; |
216 | 242 | ||
217 | soap.createClient(config.h2h_out.partner, function(err, soapClient) { | 243 | soap.createClient(config.h2h_out.partner, function(err, soapClient) { |
218 | 244 | ||
219 | var _params = { | 245 | var _params = { |
220 | userName: params.userName, | 246 | userName: params.userName, |
221 | signature: params.signature, | 247 | signature: params.signature, |
222 | productCode: params.productCode, | 248 | productCode: params.productCode, |
223 | terminal: params.terminal, | 249 | terminal: params.terminal, |
224 | transactionType: params.transactionType, | 250 | transactionType: params.transactionType, |
225 | billNumber: params.billNumber, | 251 | billNumber: params.billNumber, |
226 | amount: params.amount, | 252 | amount: params.amount, |
227 | bit61: params.bit61, | 253 | bit61: params.bit61, |
228 | reff: params.reff, | 254 | reff: params.reff, |
229 | timeStamp: params.timeStamp | 255 | timeStamp: params.timeStamp |
230 | } | 256 | } |
231 | 257 | ||
232 | logger.info('Requesting to service', {url: config.h2h_out.partner, params: _params}); | 258 | logger.info('Requesting to service', {url: config.h2h_out.partner, params: _params}); |
233 | 259 | ||
234 | soapClient.apih2h.apih2hPort.billpayment({ inputCheck: _params }, function(err, result) { | 260 | soapClient.apih2h.apih2hPort.billpayment({ inputCheck: _params }, function(err, result) { |
235 | logger.verbose( | 261 | logger.verbose( |
236 | 'Got response', | 262 | 'Got response', |
237 | { | 263 | { |
238 | lastEndpoint: soapClient.lastEndpoint, | 264 | lastEndpoint: soapClient.lastEndpoint, |
239 | lastRequest: soapClient.lastRequest, | 265 | lastRequest: soapClient.lastRequest, |
240 | lastMessage: soapClient.lastMessage, | 266 | lastMessage: soapClient.lastMessage, |
241 | lastResponse: soapClient.lastResponse, | 267 | lastResponse: soapClient.lastResponse, |
242 | } | 268 | } |
243 | ); | 269 | ); |
244 | 270 | ||
245 | if (err) { | 271 | if (err) { |
246 | var errorMessage = 'Error requesting service: ' + err; | 272 | var errorMessage = 'Error requesting service: ' + err; |
247 | 273 | ||
248 | logger.warn(errorMessage, {err: err}); | 274 | logger.warn(errorMessage, {err: err}); |
249 | callbackReport(task.requestId, '68', errorMessage); | 275 | callbackReportWrapper(task.requestId, '68', errorMessage); |
250 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: soapClient.lastResponse}, '68'); | 276 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: soapClient.lastResponse}, '68'); |
251 | 277 | ||
252 | return; | 278 | return; |
253 | } | 279 | } |
254 | 280 | ||
255 | topupResponseHandler(task, result, balance, soapClient.lastResponse); | 281 | topupResponseHandler(task, result, balance, soapClient.lastResponse); |
256 | }); | 282 | }); |
257 | }); | 283 | }); |
258 | } | 284 | } |
259 | 285 | ||
260 | function topupResponseHandler(task, response, balance, rawResponse) { | 286 | function topupResponseHandler(task, response, balance, rawResponse) { |
261 | var st24rc = '68'; | 287 | var st24rc = '68'; |
262 | var st24message = response.outputParameter.resultDesc.$value; | 288 | var st24message = response.outputParameter.resultDesc.$value; |
263 | 289 | ||
264 | var resultCode = parseInt(response.outputParameter.resultCode.$value); | 290 | var resultCode = parseInt(response.outputParameter.resultCode.$value); |
265 | var bit39 = parseInt(response.outputParameter.bit39.$value); | 291 | var bit39 = parseInt(response.outputParameter.bit39.$value); |
266 | 292 | ||
267 | var sn = ''; | 293 | var sn = ''; |
268 | 294 | ||
269 | if ( resultCode == 1 ) { | 295 | if ( resultCode == 1 ) { |
270 | // product disabled | 296 | // product disabled |
271 | st24rc = '13'; | 297 | st24rc = '13'; |
272 | } | 298 | } |
273 | else if ( resultCode == 2 ) { | 299 | else if ( resultCode == 2 ) { |
274 | // prodcode disable | 300 | // prodcode disable |
275 | st24rc = '13'; | 301 | st24rc = '13'; |
276 | } | 302 | } |
277 | else if ( resultCode == 3 ) { | 303 | else if ( resultCode == 3 ) { |
278 | // duplicate reff | 304 | // duplicate reff |
279 | st24rc = '55'; | 305 | st24rc = '55'; |
280 | } | 306 | } |
281 | else if ( resultCode == 4 ) { | 307 | else if ( resultCode == 4 ) { |
282 | // not enough balance | 308 | // not enough balance |
283 | st24rc = '40'; | 309 | st24rc = '40'; |
284 | } | 310 | } |
285 | else if ( resultCode == 5 ) { | 311 | else if ( resultCode == 5 ) { |
286 | // username blocked | 312 | // username blocked |
287 | st24rc = '40'; | 313 | st24rc = '40'; |
288 | } | 314 | } |
289 | else if ( resultCode == 6 ) { | 315 | else if ( resultCode == 6 ) { |
290 | // not exists username | 316 | // not exists username |
291 | st24rc = '40'; | 317 | st24rc = '40'; |
292 | } | 318 | } |
293 | else if ( resultCode == 11 ) { | 319 | else if ( resultCode == 11 ) { |
294 | // invalid request | 320 | // invalid request |
295 | st24rc = '40' | 321 | st24rc = '40' |
296 | } | 322 | } |
297 | else if ( resultCode == 12 ) { | 323 | else if ( resultCode == 12 ) { |
298 | // no route to host | 324 | // no route to host |
299 | st24rc = '40' | 325 | st24rc = '40' |
300 | } | 326 | } |
301 | else if ( resultCode == 13 ) { | 327 | else if ( resultCode == 13 ) { |
302 | // invalid signature | 328 | // invalid signature |
303 | st24rc = '40' | 329 | st24rc = '40' |
304 | } | 330 | } |
305 | else if ( bit39 == 6 ) { | 331 | else if ( bit39 == 6 ) { |
306 | st24rc = '40'; | 332 | st24rc = '40'; |
307 | st24message = 'Error Transaksi ditolak karena terjadi error di H2H dengan response code diluar daftar ini. Silahkan hubungi H2H'; | 333 | st24message = 'Error Transaksi ditolak karena terjadi error di H2H dengan response code diluar daftar ini. Silahkan hubungi H2H'; |
308 | } | 334 | } |
309 | else if ( bit39 == 12 ) { | 335 | else if ( bit39 == 12 ) { |
310 | st24rc = '40'; | 336 | st24rc = '40'; |
311 | st24message = 'Invalid Transaction Transaksi ditolak karena flow transaksi tidak valid'; | 337 | st24message = 'Invalid Transaction Transaksi ditolak karena flow transaksi tidak valid'; |
312 | } | 338 | } |
313 | else if ( bit39 == 13 ) { | 339 | else if ( bit39 == 13 ) { |
314 | st24rc = '13'; | 340 | st24rc = '13'; |
315 | st24message = 'Invalid voucher nominal'; | 341 | st24message = 'Invalid voucher nominal'; |
316 | } | 342 | } |
317 | else if ( bit39 == 14 ) { | 343 | else if ( bit39 == 14 ) { |
318 | st24rc = '14'; | 344 | st24rc = '14'; |
319 | st24message = 'MSISDN tidak ditemukan'; | 345 | st24message = 'MSISDN tidak ditemukan'; |
320 | } | 346 | } |
321 | else if ( bit39 == 30 ) { | 347 | else if ( bit39 == 30 ) { |
322 | st24rc = '40'; | 348 | st24rc = '40'; |
323 | st24message = 'Format Error'; | 349 | st24message = 'Format Error'; |
324 | } | 350 | } |
325 | else if ( bit39 == 31 ) { | 351 | else if ( bit39 == 31 ) { |
326 | st24rc = '40'; | 352 | st24rc = '40'; |
327 | st24message = 'Kode bank tidak terdaftar'; | 353 | st24message = 'Kode bank tidak terdaftar'; |
328 | } | 354 | } |
329 | else if ( bit39 == 63 ) { | 355 | else if ( bit39 == 63 ) { |
330 | st24rc = '40'; | 356 | st24rc = '40'; |
331 | st24message = 'Reversal denied'; | 357 | st24message = 'Reversal denied'; |
332 | } | 358 | } |
333 | else if ( bit39 == 68 ) { | 359 | else if ( bit39 == 68 ) { |
334 | st24rc = '68'; | 360 | st24rc = '68'; |
335 | st24message = 'Transaksi sedang dalam proses'; | 361 | st24message = 'Transaksi sedang dalam proses'; |
336 | } | 362 | } |
337 | else if ( bit39 == 69 ) { | 363 | else if ( bit39 == 69 ) { |
338 | st24rc = '68'; | 364 | st24rc = '68'; |
339 | st24message = 'Respon Ok lebih dari 24 detik'; | 365 | st24message = 'Respon Ok lebih dari 24 detik'; |
340 | } | 366 | } |
341 | else if ( bit39 == 70 ) { | 367 | else if ( bit39 == 70 ) { |
342 | st24rc = '13'; | 368 | st24rc = '13'; |
343 | st24message = 'Voucher out of stock'; | 369 | st24message = 'Voucher out of stock'; |
344 | } | 370 | } |
345 | else if ( bit39 == 79 ) { | 371 | else if ( bit39 == 79 ) { |
346 | st24rc = '14'; | 372 | st24rc = '14'; |
347 | st24message = 'Phone number is blocked by Telkomsel'; | 373 | st24message = 'Phone number is blocked by Telkomsel'; |
348 | } | 374 | } |
349 | else if ( bit39 == 81 ) { | 375 | else if ( bit39 == 81 ) { |
350 | st24rc = '14'; | 376 | st24rc = '14'; |
351 | st24message = 'Phone number is expired'; | 377 | st24message = 'Phone number is expired'; |
352 | } | 378 | } |
353 | else if ( bit39 == 89 ) { | 379 | else if ( bit39 == 89 ) { |
354 | st24rc = '40'; | 380 | st24rc = '40'; |
355 | st24message = 'Link to billing provider is down'; | 381 | st24message = 'Link to billing provider is down'; |
356 | } | 382 | } |
357 | else if ( bit39 == 91 ) { | 383 | else if ( bit39 == 91 ) { |
358 | st24rc = '40'; | 384 | st24rc = '40'; |
359 | st24message = 'Database problem'; | 385 | st24message = 'Database problem'; |
360 | } | 386 | } |
361 | else if ( bit39 == 92 ) { | 387 | else if ( bit39 == 92 ) { |
362 | st24rc = '40'; | 388 | st24rc = '40'; |
363 | st24message = 'Unable to route transaction'; | 389 | st24message = 'Unable to route transaction'; |
364 | } | 390 | } |
365 | else if ( bit39 == 94 ) { | 391 | else if ( bit39 == 94 ) { |
366 | st24rc = '40'; | 392 | st24rc = '40'; |
367 | st24message = 'Duplicate reversal request'; | 393 | st24message = 'Duplicate reversal request'; |
368 | } | 394 | } |
369 | else if ( resultCode == 0 && bit39 == 0) { | 395 | else if ( resultCode == 0 && bit39 == 0) { |
370 | 396 | ||
371 | try { | 397 | try { |
372 | sn = response.outputParameter.bit61.$value.substring(43); | 398 | sn = response.outputParameter.bit61.$value.substring(43); |
373 | } | 399 | } |
374 | catch(e) { | 400 | catch(e) { |
375 | sn = ''; | 401 | sn = ''; |
376 | } | 402 | } |
377 | 403 | ||
378 | st24message = 'SN=' + sn + '; ' + st24message; | 404 | st24message = 'SN=' + sn + '; ' + st24message; |
379 | st24rc = '00'; | 405 | st24rc = '00'; |
380 | } | 406 | } |
381 | 407 | ||
382 | var message = | 408 | var message = |
383 | response.outputParameter.resultCode.$value | 409 | response.outputParameter.resultCode.$value |
384 | + " " + response.outputParameter.resultDesc.$value | 410 | + " " + response.outputParameter.resultDesc.$value |
385 | + "; BIT39: " + response.outputParameter.bit39.$value | 411 | + "; BIT39: " + response.outputParameter.bit39.$value |
386 | ; | 412 | ; |
387 | 413 | ||
388 | if (response.outputParameter.resultDesc.$value != st24message) { | 414 | if (response.outputParameter.resultDesc.$value != st24message) { |
389 | var message = message + " " + st24message; | 415 | var message = message + " " + st24message; |
390 | } | 416 | } |
391 | 417 | ||
392 | message = message + ' -- Prev Balance: ' + balance; | 418 | message = message + ' -- Prev Balance: ' + balance; |
393 | 419 | ||
394 | var parsedResponse = { | 420 | var parsedResponse = { |
395 | productCode: response.outputParameter.productCode.$value, | 421 | productCode: response.outputParameter.productCode.$value, |
396 | terminal: response.outputParameter.terminal.$value, | 422 | terminal: response.outputParameter.terminal.$value, |
397 | transactionType: response.outputParameter.transactionType.$value, | 423 | transactionType: response.outputParameter.transactionType.$value, |
398 | billNumber: response.outputParameter.billNumber.$value, | 424 | billNumber: response.outputParameter.billNumber.$value, |
399 | amount: response.outputParameter.amount.$value, | 425 | amount: response.outputParameter.amount.$value, |
400 | bit61: response.outputParameter.bit61.$value, | 426 | bit61: response.outputParameter.bit61.$value, |
401 | reff: response.outputParameter.reff.$value, | 427 | reff: response.outputParameter.reff.$value, |
402 | timeStamp: response.outputParameter.timeStamp.$value, | 428 | timeStamp: response.outputParameter.timeStamp.$value, |
403 | resultCode: response.outputParameter.resultCode.$value, | 429 | resultCode: response.outputParameter.resultCode.$value, |
404 | resultDesc: response.outputParameter.resultDesc.$value, | 430 | resultDesc: response.outputParameter.resultDesc.$value, |
405 | bit39: response.outputParameter.bit39.$value, | 431 | bit39: response.outputParameter.bit39.$value, |
406 | prevBalance: balance, | 432 | prevBalance: balance, |
407 | sn: sn, | 433 | sn: sn, |
408 | st24message: st24message, | 434 | st24message: st24message, |
409 | } | 435 | } |
410 | 436 | ||
411 | var combinedMessage = ''; | 437 | var combinedMessage = ''; |
412 | 438 | ||
413 | Object.keys(parsedResponse).forEach(function(key,index) { | 439 | Object.keys(parsedResponse).forEach(function(key,index) { |
414 | combinedMessage += key + ': ' + parsedResponse[key] + '; ' | 440 | combinedMessage += key + ': ' + parsedResponse[key] + '; ' |
415 | }); | 441 | }); |
416 | combinedMessage = combinedMessage.trim(); | 442 | combinedMessage = combinedMessage.trim(); |
417 | 443 | ||
418 | parsedResponse.MESSAGE = combinedMessage; | 444 | parsedResponse.MESSAGE = combinedMessage; |
419 | 445 | ||
420 | logger.info('Got result: ' + message, {response: response}); | 446 | logger.info('Got result: ' + message, {response: response}); |
421 | callbackReport(task.requestId, st24rc, st24message + ' -- Prev Balance: ' + balance); | 447 | callbackReportWrapper(task.requestId, st24rc, st24message + ' -- Prev Balance: ' + balance); |
422 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: rawResponse, parsed: parsedResponse}, st24rc); | 448 | pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: rawResponse, parsed: parsedResponse}, st24rc); |
423 | } | 449 | } |
424 | 450 | ||
425 | function createSignature(params, password) { | 451 | function createSignature(params, password) { |
426 | var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex'); | 452 | var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex'); |
427 | var plain = | 453 | var plain = |
428 | params.userName | 454 | params.userName |
429 | + passwordHash | 455 | + passwordHash |
430 | + params.productCode | 456 | + params.productCode |
431 | + params.terminal | 457 | + params.terminal |
432 | + params.transactionType | 458 | + params.transactionType |
433 | + params.billNumber | 459 | + params.billNumber |
434 | + params.amount | 460 | + params.amount |
435 | + params.reff | 461 | + params.reff |
436 | + params.timeStamp; | 462 | + params.timeStamp; |
437 | 463 | ||
438 | return crypto.createHash('sha1').update(plain).digest().toString('hex'); | 464 | return crypto.createHash('sha1').update(plain).digest().toString('hex'); |
439 | } | 465 | } |
440 | 466 | ||
441 | function createSignatureForSaldoCheck(params, password) { | 467 | function createSignatureForSaldoCheck(params, password) { |
442 | var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex'); | 468 | var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex'); |
443 | var plain = | 469 | var plain = |
444 | params.userName | 470 | params.userName |
445 | + passwordHash | 471 | + passwordHash |
446 | + params.productCode | 472 | + params.productCode |
447 | + params.terminal | 473 | + params.terminal |
448 | + params.transactionType | 474 | + params.transactionType |
449 | + params.reff | 475 | + params.reff |
450 | + params.timeStamp; | 476 | + params.timeStamp; |
451 | 477 | ||
452 | return crypto.createHash('sha1').update(plain).digest().toString('hex'); | 478 | return crypto.createHash('sha1').update(plain).digest().toString('hex'); |
453 | } | 479 | } |
454 | 480 | ||
455 | function createBillNumber(destination) { | 481 | function createBillNumber(destination) { |
456 | return ("0000000000000" + destination).slice(-13); | 482 | return ("0000000000000" + destination).slice(-13); |
457 | } | 483 | } |
458 | 484 | ||
459 | exports.start = start; | 485 | exports.start = start; |
460 | exports.topupRequest = topupRequest; | 486 | exports.topupRequest = topupRequest; |
461 | exports.createSignature = createSignature; | 487 | exports.createSignature = createSignature; |
462 | exports.createBillNumber = createBillNumber; | 488 | exports.createBillNumber = createBillNumber; |