Commit ed7b35458050219777d371b410afc2a07d17eeb2

Authored by Adhidarma Hadiwinoto
1 parent a097fbf1ce
Exists in master

moment

Showing 1 changed file with 564 additions and 563 deletions Side-by-side Diff

Changes suppressed. Click to show
1   -var fs = require('fs');
2   -var https = require('https');
3   -var http = require('http');
4   -var url = require('url');
5   -var request = require('request');
6   -var xml2js = require('xml2js').parseString;
7   -var strftime = require('strftime');
8   -var math = require('mathjs');
9   -var winston = require('winston');
10   -var cekstatus = require('./cekstatus.js');
11   -var mongoClient = require('mongodb').MongoClient;
12   -var LRU = require('lru-cache');
13   -
14   -var config;
15   -var httpServer;
16   -var aaa;
17   -var logger;
18   -var callbackReport;
19   -var mongodb;
20   -
21   -var tasks = LRU(10000);
22   -
23   -process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
24   -
25   -var sleep_before_retry = 30000;
26   -
27   -var logTag = __filename.split('/').reverse()[0];
28   -
29   -function initMongoClient() {
30   - if (!config.mongodb || !config.mongodb.url) {
31   - return;
32   - }
33   -
34   - try {
35   - var url = config.mongodb.url;
36   -
37   - mongoClient.connect(url, function(err, db) {
38   - if (err) {
39   - logger.warn('Failed to connect to mongodb', {err: err});
40   - return;
41   - }
42   - mongodb = db;
43   - logger.info('MongoDB connected');
44   - });
45   - }
46   - catch(err) {
47   - logger.warn('Exception when connecting to mongodb', {err: err, url: url});
48   - }
49   -
50   -}
51   -
52   -function prepareResultData(result) {
53   - var task;
54   -
55   - var data = {};
56   - data.gateway = config.globals.gateway_name;
57   -
58   - try {
59   - data.requestId = result.reffid[0].trim();
60   -
61   - var key = config.globals.gateway_name + '.rid:' + data.requestId;
62   - task = tasks.get(key);
63   - }
64   - catch(err) { data.requestId = null; }
65   -
66   - try {
67   - data.status = result.ResultCode[0].trim();
68   - }
69   - catch(err) { data.status = '68' }
70   -
71   - try {
72   - data.rcmessage = result.ErrorMsg[0].trim();
73   - }
74   - catch(err) { data.rcmessage = ''; }
75   -
76   - try {
77   - data.resptext = '';
78   - }
79   - catch(err) { data.resptext = ''; }
80   -
81   - try {
82   - data.dt = task.timestamp;
83   - }
84   - catch(err) {
85   - logger.warn('Exception when getting timestamp data, using current timestamp', {err: err, result: result, task: task});
86   - data.dt = strftime('%Y-%m-%d %H:%M:%S', new Date());
87   - }
88   -
89   - try {
90   - data.namapel = result.nama_pel[0].trim();
91   - }
92   - catch(err) { data.namapel = 'UNKNOWN'; }
93   -
94   - try {
95   - data.msn = result.nsm[0].trim();
96   - }
97   - catch(err) { data.msn = 'UNKNOWN'; }
98   -
99   - try {
100   - data.idpel = result.idpel[0].trim();
101   - }
102   - catch(err) { data.idpel = 'UNKNOWN'; }
103   -
104   - try {
105   - data.tarifdaya = result.tarif[0].trim();
106   - }
107   - catch(err) { data.tarifdaya = 'UNKNOWN'; }
108   -
109   - try {
110   - data.admin = parseInt(result.adminfee[0].trim());
111   - }
112   - catch(err) { data.admin = 0; }
113   -
114   - try {
115   - data.adm = parseInt(result.adminfee[0].trim());
116   - }
117   - catch(err) { data.adm = 0; }
118   -
119   - try {
120   - data.hargatotal = parseInt(result.amount_trx[0].trim());
121   - }
122   - catch(err) { data.hargatotal = 0; }
123   -
124   - try {
125   - data.hargapelanggan = data.hargatotal - data.adm;
126   - }
127   - catch(err) { data.hargapelanggan = 0; }
128   -
129   - try {
130   - data.jumlahkwh = result.jml_daya[0].trim();
131   - }
132   - catch(err) { data.jumlahkwh = 0; }
133   -
134   - try {
135   - data.token = result.token[0].trim();
136   - }
137   - catch(err) { data.token = 0; }
138   -
139   - try {
140   - data.ppn = result.ppn_fee[0].trim();
141   - }
142   - catch(err) { data.ppn_fee = 0; }
143   -
144   - try {
145   - data.ppj = result.ppj_fee[0].trim();
146   - }
147   - catch(err) { data.ppj = 0; }
148   -
149   - try {
150   - data.angsuran = result.angsuran_fee[0].trim();
151   - }
152   - catch(err) { data.angsuran = 0; }
153   -
154   - try {
155   - data.meterai = result.materai_fee[0].trim();
156   - }
157   - catch(err) { data.materai_fee = 0; }
158   -
159   - return data;
160   -}
161   -
162   -function saveTokenToMongoDb(result) {
163   - if (!mongodb) {
164   - return;
165   - }
166   -
167   - if (!config.mongodb) {
168   - return;
169   - }
170   -
171   - if (!config.mongodb.collection) {
172   - return;
173   - }
174   -
175   - data = prepareResultData(result);
176   -
177   - try {
178   - mongodb.collection(config.mongodb.collection).insertOne(data);
179   - }
180   - catch(err) {
181   - logger.warn('Error when inserting data to mongodb', {err: err, data: data});
182   - }
183   -}
184   -
185   -function putTaskToCache(task) {
186   - var key = config.globals.gateway_name + '.rid:' + task.requestId;
187   -
188   - try {
189   - tasks.set(key, task);
190   - }
191   - catch(err) {
192   - logger.warn('Error writing to task to cache', {err: err, key: key, task: task});
193   - }
194   -}
195   -
196   -function topupRequest(task) {
197   - putTaskToCache(task);
198   -
199   - var ts = strftime('%Y%m%d%H%M%S', new Date());
200   -
201   - var data =
202   - config.h2h_out.userid
203   - + '|' + config.h2h_out.password
204   - + '|' + task['remoteProduct']
205   - + '|' + task['destination'] + '|0';
206   -
207   - var options = {
208   - url: config.h2h_out.partner,
209   - qs: {
210   - ts: ts,
211   - data: data,
212   - reffid: task['requestId']
213   - }
214   - };
215   - logger.info('Creating http request', {options: options});
216   -
217   - request(options, function (error, response, body) {
218   - var responseCode = '40';
219   - var responseMessage = 'Gateway Error';
220   -
221   - if (error) {
222   -
223   - logger.warn('HTTP REQUEST ERROR', error);
224   - callbackReport(task['requestId'], '89', 'HTTP REQUEST ERROR (' + error + ')');
225   -
226   - } else if (response.statusCode != 200) {
227   -
228   - var error_message = 'GATEWAY ERROR (HTTP RESPONSE CODE: ' + response.statusCode + ')';
229   - logger.warn(error_message);
230   - callbackReport(task['requestId'], '91', error_message);
231   -
232   - } else {
233   -
234   - logger.info('DIRECT RESPONSE', {body: body});
235   -
236   - xml2js(body, function (err, result) {
237   - if (err) {
238   - callbackReport(task['requestId'], '40', body);
239   - } else {
240   - var directResponse = result;
241   - logger.info(directResponse);
242   -
243   - saveTokenToMongoDb(directResponse.Result);
244   -
245   - try {
246   - var result_price;
247   - try {
248   - result_price = directResponse.Result.Price[0].trim();
249   - }
250   - catch(err) {
251   - result_price = 0;
252   - }
253   -
254   - var result_error_message;
255   - try {
256   - result_error_message = directResponse.Result.ErrorMsg[0].trim();
257   - }
258   - catch(err) {
259   - result_error_message = '';
260   - }
261   -
262   - var resultCode = directResponse.Result.ResultCode[0].trim();
263   -
264   - responseMessage =
265   - 'ResultCode: ' + resultCode
266   - + ' | ErrorMsg: ' + result_error_message
267   - + ' | DateTime: ' + directResponse.Result.DateTime[0].trim()
268   - + ' | nsm: ' + directResponse.Result.nsm[0].trim()
269   - + ' | idpel: ' + directResponse.Result.idpel[0].trim()
270   - + ' | reffid: ' + directResponse.Result.reffid[0].trim()
271   - + ' | TransID: ' + directResponse.Result.TransID[0].trim()
272   - + ' | reff_switching: ' + directResponse.Result.reff_switching[0].trim()
273   - + ' | amount_trx: ' + directResponse.Result.amount_trx[0].trim()
274   - + ' | token: ' + directResponse.Result.token[0].trim()
275   - + ' | PrevBalance: ' + directResponse.Result.PrevBalance[0].trim()
276   - + ' | Price: ' + result_price
277   - + ' | EndBalance: ' + directResponse.Result.EndBalance[0].trim()
278   - ;
279   -
280   - logger.info('Response message: ' + responseMessage);
281   -
282   - if (aaa) {
283   - // update balance
284   - aaa.updateBalance(directResponse.Result.EndBalance[0]);
285   - }
286   -
287   - if (resultCode == '0000') {
288   - var nama_pelanggan = directResponse.Result.nama_pel[0].trim();
289   - nama_pelanggan = nama_pelanggan.replace(/-\/-/g, '-');
290   - var sn = directResponse.Result.token[0].trim() + '/' + nama_pelanggan + '/' + directResponse.Result.tarif[0].trim() + 'VA/' + directResponse.Result.jml_daya[0].trim();
291   - sn = sn.replace(/\s/g, '-');
292   -
293   - responseMessage = 'SN=' + sn + '; ' + responseMessage;
294   - logger.info('New response message: ' + responseMessage);
295   - }
296   -
297   - var pendingResultCode = ['0005', '0012', '0068', '0090', '0063', '0018', '0096'];
298   - if (pendingResultCode.indexOf(resultCode) != -1) {
299   - callbackReport(task['requestId'], '68', responseMessage);
300   -
301   - logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
302   - setTimeout(function () {
303   - cekstatus.advice({trxid: directResponse.Result.TransID[0].trim()}, callbackFromWebReport);
304   - }, sleep_before_retry);
305   -
306   - return;
307   - }
308   -
309   - responseCode = resultCode.replace(/^00/, "");
310   -
311   - if (result_error_message == 'Inq - APLICATION SERVER RESPONSE TIMEOUT') {
312   - responseCode = '91';
313   - }
314   -
315   - }
316   - catch(err) {
317   - responseCode = '40';
318   - responseMessage = 'Invalid response from gateway';
319   - }
320   - }
321   -
322   - callbackReport(task['requestId'], responseCode, responseMessage);
323   - });
324   - }
325   -
326   - //callbackReport(task['requestId'], responseCode, responseMessage);
327   - });
328   -}
329   -
330   -function callbackFromWebReport(status) {
331   - if (!status) {
332   - logger.warn('Advice from webreport return empty status');
333   - return;
334   - }
335   -
336   - logger.info('Got advice result from webreport', {status: status});
337   -
338   - var responseCode = '68';
339   -
340   - var result_price = 0;
341   - try {
342   - result_price = directResponse.Result.Price[0].trim();
343   - }
344   - catch(err) {}
345   -
346   - var errorMsg = '';
347   - try {
348   - errorMsg = status.response.errormsg[0];
349   - }
350   - catch(err) {}
351   -
352   - var responseMessage = '';
353   - try {
354   - responseMessage =
355   - 'Hasil advice dari webreport '
356   - + 'ResultCode: ' + status.response.resultcode[0]
357   - }
358   - catch(err) {
359   - logger.warn('Error parsing ResultCode from webreport advice.', {err: err});
360   - }
361   -
362   - try {
363   - responseMessage =
364   - responseMessage
365   - + ' | ErrorMsg: ' + errorMsg
366   - }
367   - catch(err) {
368   - logger.warn('Error parsing ErrorMsg from webreport advice.', {err: err});
369   - }
370   -
371   - try {
372   - responseMessage =
373   - responseMessage
374   - + ' | TrxDate: ' + status.trxDate;
375   - }
376   - catch(err) {
377   - logger.warn('Error parsing TrxDate from webreport advice.', {err: err});
378   - }
379   -
380   - try {
381   - responseMessage =
382   - responseMessage
383   - + ' | UpdateDate: ' + status.updateDate;
384   -
385   - }
386   - catch(err) {
387   - logger.warn('Error parsing UpdateDate from webreport advice.', {err: err});
388   - }
389   -
390   - try {
391   - responseMessage =
392   - responseMessage
393   - + ' | nsm: ' + status.response.nsm[0];
394   - }
395   - catch(err) {
396   - logger.warn('Error parsing nsm from webreport advice.', {err: err});
397   - }
398   -
399   - try {
400   - responseMessage =
401   - responseMessage
402   - + ' | idpel: ' + status.response.idpel[0];
403   - }
404   - catch(err) {
405   - logger.warn('Error parsing idpel from webreport advice.', {err: err});
406   - }
407   -
408   - try {
409   - responseMessage =
410   - responseMessage
411   - + ' | reffid: ' + status.response.reffid[0].trim();
412   - }
413   - catch(err) {
414   - logger.warn('Error parsing reffid from webreport advice.', {err: err});
415   - }
416   -
417   - try {
418   - responseMessage =
419   - responseMessage
420   - + ' | TransID: ' + status.response.transid[0].trim();
421   - }
422   - catch(err) {
423   - logger.warn('Error parsing TransID from webreport advice.', {err: err});
424   - }
425   -
426   - try {
427   - responseMessage =
428   - responseMessage
429   - + ' | reff_switching: ' + status.response.reff_switching[0];
430   - }
431   - catch(err) {
432   - logger.warn('Error parsing reff_switching from webreport advice.', {err: err});
433   - }
434   -
435   - try {
436   - responseMessage =
437   - responseMessage
438   - + ' | amount_trx: ' + status.response.amount_trx[0];
439   - }
440   - catch(err) {
441   - logger.warn('Error parsing amount_trx from webreport advice.', {err: err});
442   - }
443   -
444   - try {
445   - responseMessage =
446   - responseMessage
447   - + ' | token: ' + status.response.token[0];
448   - }
449   - catch(err) {
450   - logger.warn('Error parsing token from webreport advice.', {err: err});
451   - }
452   -
453   - try {
454   - responseMessage =
455   - responseMessage
456   - + ' | PrevBalance: ' + status.response.prevbalance[0];
457   - }
458   - catch(err) {
459   - logger.warn('Error parsing PrevBalance from webreport advice.', {err: err});
460   - }
461   -
462   - try {
463   - responseMessage =
464   - responseMessage
465   - + ' | Price: ' + status.amount;
466   - }
467   - catch(err) {
468   - logger.warn('Error parsing Price from webreport advice.', {err: err});
469   - }
470   -
471   - try {
472   - responseMessage =
473   - responseMessage
474   - + ' | EndBalance: ' + status.response.endbalance[0];
475   - }
476   - catch(err) {
477   - logger.warn('Error parsing EndBalance from webreport advice.', {err: err});
478   - }
479   -
480   -
481   - if ((status.status == 'S') && (status.response.resultcode[0] == '0000')) {
482   - responseCode = '00';
483   -
484   - var nama_pelanggan = status.response.nama_pel[0] ;
485   - nama_pelanggan = nama_pelanggan.replace(/-\/-/g, '-');
486   -
487   - var sn = status.response.token[0] + '/' + nama_pelanggan + '/' + status.response.tarif[0] + 'VA/' + status.response.jml_daya[0];
488   - responseMessage = 'SN=' + sn + '; ' + responseMessage;
489   -
490   - } else if ((status.status == 'P') || (status.status == 'W')) {
491   -
492   - callbackReport(status.response.reffid[0].trim(), '68', responseMessage);
493   - logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
494   -
495   - setTimeout(function () {
496   -
497   - cekstatus.advice({trxid: status.trxId,}, callbackFromWebReport);
498   -
499   - }, sleep_before_retry);
500   - return;
501   -
502   - } else {
503   - responseCode = status.response.resultcode[0].replace(/^00/, "");
504   - if (['00', '05', '12', '68', '90', '63', '18', '96'].indexOf(responseCode) >= 0) {
505   - responseCode = '40';
506   - }
507   - }
508   -
509   -
510   - callbackReport(status.response.reffid[0].trim(), responseCode, responseMessage);
511   -}
512   -
513   -function createHttpReportServer() {
514   - var httpServer = http.createServer(function(request, response) {
515   - var qs = url.parse(request.url, true).query;
516   - var path = url.parse(request.url).pathname;
517   -
518   - logger.info('Got reverse report from partner', {path: path, qs: qs});
519   - response.end('OK');
520   -
521   - var trxid;
522   - try {
523   - trxid = qs.transid;
524   - }
525   - catch(err) {
526   - }
527   -
528   - if (trxid) {
529   - logger.info('Requesting advice from webreport', {trxid: trxid})
530   - cekstatus.advice({trxid: trxid}, callbackFromWebReport);
531   - }
532   -
533   - });
534   -
535   - httpServer.listen(config.h2h_out.listen_port, function() {
536   - logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
537   - });
538   -}
539   -
540   -function start(_config, _callbackReport, options) {
541   - config = _config;
542   - callbackReport = _callbackReport;
543   -
544   - if (options && options.aaa) {
545   - aaa = options.aaa;
546   - }
547   -
548   - if (options && options.logger) {
549   - logger = options.logger;
550   - } else {
551   - logger = new winston.Logger({
552   - transports: [
553   - new (winston.transports.Console)()
554   - ]
555   - });
556   - }
557   -
558   - createHttpReportServer();
559   - initMongoClient();
560   -}
561   -
562   -exports.start = start;
563   -exports.topupRequest = topupRequest;
  1 +var fs = require('fs');
  2 +var https = require('https');
  3 +var http = require('http');
  4 +var url = require('url');
  5 +var request = require('request');
  6 +var xml2js = require('xml2js').parseString;
  7 +var strftime = require('strftime');
  8 +var math = require('mathjs');
  9 +var winston = require('winston');
  10 +var cekstatus = require('./cekstatus.js');
  11 +var mongoClient = require('mongodb').MongoClient;
  12 +var LRU = require('lru-cache');
  13 +
  14 +var config;
  15 +var httpServer;
  16 +var aaa;
  17 +var logger;
  18 +var callbackReport;
  19 +var mongodb;
  20 +
  21 +var tasks = LRU(10000);
  22 +
  23 +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  24 +
  25 +var sleep_before_retry = 30000;
  26 +
  27 +var logTag = __filename.split('/').reverse()[0];
  28 +
  29 +function initMongoClient() {
  30 + if (!config.mongodb || !config.mongodb.url) {
  31 + return;
  32 + }
  33 +
  34 + try {
  35 + var url = config.mongodb.url;
  36 +
  37 + mongoClient.connect(url, function(err, db) {
  38 + if (err) {
  39 + logger.warn('Failed to connect to mongodb', {err: err});
  40 + return;
  41 + }
  42 + mongodb = db;
  43 + logger.info('MongoDB connected');
  44 + });
  45 + }
  46 + catch(err) {
  47 + logger.warn('Exception when connecting to mongodb', {err: err, url: url});
  48 + }
  49 +
  50 +}
  51 +
  52 +function prepareResultData(result) {
  53 + var task;
  54 +
  55 + var data = {};
  56 + data.gateway = config.globals.gateway_name;
  57 +
  58 + try {
  59 + data.requestId = result.reffid[0].trim();
  60 +
  61 + var key = config.globals.gateway_name + '.rid:' + data.requestId;
  62 + task = tasks.get(key);
  63 + }
  64 + catch(err) { data.requestId = null; }
  65 +
  66 + try {
  67 + data.status = result.ResultCode[0].trim();
  68 + }
  69 + catch(err) { data.status = '68' }
  70 +
  71 + try {
  72 + data.rcmessage = result.ErrorMsg[0].trim();
  73 + }
  74 + catch(err) { data.rcmessage = ''; }
  75 +
  76 + try {
  77 + data.resptext = '';
  78 + }
  79 + catch(err) { data.resptext = ''; }
  80 +
  81 + try {
  82 + var ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss')
  83 + data.dt = ts;
  84 + }
  85 + catch(err) {
  86 + logger.warn('Exception when getting timestamp data, using current timestamp', {err: err, result: result, task: task});
  87 + data.dt = strftime('%Y-%m-%d %H:%M:%S', new Date());
  88 + }
  89 +
  90 + try {
  91 + data.namapel = result.nama_pel[0].trim();
  92 + }
  93 + catch(err) { data.namapel = 'UNKNOWN'; }
  94 +
  95 + try {
  96 + data.msn = result.nsm[0].trim();
  97 + }
  98 + catch(err) { data.msn = 'UNKNOWN'; }
  99 +
  100 + try {
  101 + data.idpel = result.idpel[0].trim();
  102 + }
  103 + catch(err) { data.idpel = 'UNKNOWN'; }
  104 +
  105 + try {
  106 + data.tarifdaya = result.tarif[0].trim();
  107 + }
  108 + catch(err) { data.tarifdaya = 'UNKNOWN'; }
  109 +
  110 + try {
  111 + data.admin = parseInt(result.adminfee[0].trim());
  112 + }
  113 + catch(err) { data.admin = 0; }
  114 +
  115 + try {
  116 + data.adm = parseInt(result.adminfee[0].trim());
  117 + }
  118 + catch(err) { data.adm = 0; }
  119 +
  120 + try {
  121 + data.hargatotal = parseInt(result.amount_trx[0].trim());
  122 + }
  123 + catch(err) { data.hargatotal = 0; }
  124 +
  125 + try {
  126 + data.hargapelanggan = data.hargatotal - data.adm;
  127 + }
  128 + catch(err) { data.hargapelanggan = 0; }
  129 +
  130 + try {
  131 + data.jumlahkwh = result.jml_daya[0].trim();
  132 + }
  133 + catch(err) { data.jumlahkwh = 0; }
  134 +
  135 + try {
  136 + data.token = result.token[0].trim();
  137 + }
  138 + catch(err) { data.token = 0; }
  139 +
  140 + try {
  141 + data.ppn = result.ppn_fee[0].trim();
  142 + }
  143 + catch(err) { data.ppn_fee = 0; }
  144 +
  145 + try {
  146 + data.ppj = result.ppj_fee[0].trim();
  147 + }
  148 + catch(err) { data.ppj = 0; }
  149 +
  150 + try {
  151 + data.angsuran = result.angsuran_fee[0].trim();
  152 + }
  153 + catch(err) { data.angsuran = 0; }
  154 +
  155 + try {
  156 + data.meterai = result.materai_fee[0].trim();
  157 + }
  158 + catch(err) { data.materai_fee = 0; }
  159 +
  160 + return data;
  161 +}
  162 +
  163 +function saveTokenToMongoDb(result) {
  164 + if (!mongodb) {
  165 + return;
  166 + }
  167 +
  168 + if (!config.mongodb) {
  169 + return;
  170 + }
  171 +
  172 + if (!config.mongodb.collection) {
  173 + return;
  174 + }
  175 +
  176 + data = prepareResultData(result);
  177 +
  178 + try {
  179 + mongodb.collection(config.mongodb.collection).insertOne(data);
  180 + }
  181 + catch(err) {
  182 + logger.warn('Error when inserting data to mongodb', {err: err, data: data});
  183 + }
  184 +}
  185 +
  186 +function putTaskToCache(task) {
  187 + var key = config.globals.gateway_name + '.rid:' + task.requestId;
  188 +
  189 + try {
  190 + tasks.set(key, task);
  191 + }
  192 + catch(err) {
  193 + logger.warn('Error writing to task to cache', {err: err, key: key, task: task});
  194 + }
  195 +}
  196 +
  197 +function topupRequest(task) {
  198 + putTaskToCache(task);
  199 +
  200 + var ts = strftime('%Y%m%d%H%M%S', new Date());
  201 +
  202 + var data =
  203 + config.h2h_out.userid
  204 + + '|' + config.h2h_out.password
  205 + + '|' + task['remoteProduct']
  206 + + '|' + task['destination'] + '|0';
  207 +
  208 + var options = {
  209 + url: config.h2h_out.partner,
  210 + qs: {
  211 + ts: ts,
  212 + data: data,
  213 + reffid: task['requestId']
  214 + }
  215 + };
  216 + logger.info('Creating http request', {options: options});
  217 +
  218 + request(options, function (error, response, body) {
  219 + var responseCode = '40';
  220 + var responseMessage = 'Gateway Error';
  221 +
  222 + if (error) {
  223 +
  224 + logger.warn('HTTP REQUEST ERROR', error);
  225 + callbackReport(task['requestId'], '89', 'HTTP REQUEST ERROR (' + error + ')');
  226 +
  227 + } else if (response.statusCode != 200) {
  228 +
  229 + var error_message = 'GATEWAY ERROR (HTTP RESPONSE CODE: ' + response.statusCode + ')';
  230 + logger.warn(error_message);
  231 + callbackReport(task['requestId'], '91', error_message);
  232 +
  233 + } else {
  234 +
  235 + logger.info('DIRECT RESPONSE', {body: body});
  236 +
  237 + xml2js(body, function (err, result) {
  238 + if (err) {
  239 + callbackReport(task['requestId'], '40', body);
  240 + } else {
  241 + var directResponse = result;
  242 + logger.info(directResponse);
  243 +
  244 + saveTokenToMongoDb(directResponse.Result);
  245 +
  246 + try {
  247 + var result_price;
  248 + try {
  249 + result_price = directResponse.Result.Price[0].trim();
  250 + }
  251 + catch(err) {
  252 + result_price = 0;
  253 + }
  254 +
  255 + var result_error_message;
  256 + try {
  257 + result_error_message = directResponse.Result.ErrorMsg[0].trim();
  258 + }
  259 + catch(err) {
  260 + result_error_message = '';
  261 + }
  262 +
  263 + var resultCode = directResponse.Result.ResultCode[0].trim();
  264 +
  265 + responseMessage =
  266 + 'ResultCode: ' + resultCode
  267 + + ' | ErrorMsg: ' + result_error_message
  268 + + ' | DateTime: ' + directResponse.Result.DateTime[0].trim()
  269 + + ' | nsm: ' + directResponse.Result.nsm[0].trim()
  270 + + ' | idpel: ' + directResponse.Result.idpel[0].trim()
  271 + + ' | reffid: ' + directResponse.Result.reffid[0].trim()
  272 + + ' | TransID: ' + directResponse.Result.TransID[0].trim()
  273 + + ' | reff_switching: ' + directResponse.Result.reff_switching[0].trim()
  274 + + ' | amount_trx: ' + directResponse.Result.amount_trx[0].trim()
  275 + + ' | token: ' + directResponse.Result.token[0].trim()
  276 + + ' | PrevBalance: ' + directResponse.Result.PrevBalance[0].trim()
  277 + + ' | Price: ' + result_price
  278 + + ' | EndBalance: ' + directResponse.Result.EndBalance[0].trim()
  279 + ;
  280 +
  281 + logger.info('Response message: ' + responseMessage);
  282 +
  283 + if (aaa) {
  284 + // update balance
  285 + aaa.updateBalance(directResponse.Result.EndBalance[0]);
  286 + }
  287 +
  288 + if (resultCode == '0000') {
  289 + var nama_pelanggan = directResponse.Result.nama_pel[0].trim();
  290 + nama_pelanggan = nama_pelanggan.replace(/-\/-/g, '-');
  291 + var sn = directResponse.Result.token[0].trim() + '/' + nama_pelanggan + '/' + directResponse.Result.tarif[0].trim() + 'VA/' + directResponse.Result.jml_daya[0].trim();
  292 + sn = sn.replace(/\s/g, '-');
  293 +
  294 + responseMessage = 'SN=' + sn + '; ' + responseMessage;
  295 + logger.info('New response message: ' + responseMessage);
  296 + }
  297 +
  298 + var pendingResultCode = ['0005', '0012', '0068', '0090', '0063', '0018', '0096'];
  299 + if (pendingResultCode.indexOf(resultCode) != -1) {
  300 + callbackReport(task['requestId'], '68', responseMessage);
  301 +
  302 + logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
  303 + setTimeout(function () {
  304 + cekstatus.advice({trxid: directResponse.Result.TransID[0].trim()}, callbackFromWebReport);
  305 + }, sleep_before_retry);
  306 +
  307 + return;
  308 + }
  309 +
  310 + responseCode = resultCode.replace(/^00/, "");
  311 +
  312 + if (result_error_message == 'Inq - APLICATION SERVER RESPONSE TIMEOUT') {
  313 + responseCode = '91';
  314 + }
  315 +
  316 + }
  317 + catch(err) {
  318 + responseCode = '40';
  319 + responseMessage = 'Invalid response from gateway';
  320 + }
  321 + }
  322 +
  323 + callbackReport(task['requestId'], responseCode, responseMessage);
  324 + });
  325 + }
  326 +
  327 + //callbackReport(task['requestId'], responseCode, responseMessage);
  328 + });
  329 +}
  330 +
  331 +function callbackFromWebReport(status) {
  332 + if (!status) {
  333 + logger.warn('Advice from webreport return empty status');
  334 + return;
  335 + }
  336 +
  337 + logger.info('Got advice result from webreport', {status: status});
  338 +
  339 + var responseCode = '68';
  340 +
  341 + var result_price = 0;
  342 + try {
  343 + result_price = directResponse.Result.Price[0].trim();
  344 + }
  345 + catch(err) {}
  346 +
  347 + var errorMsg = '';
  348 + try {
  349 + errorMsg = status.response.errormsg[0];
  350 + }
  351 + catch(err) {}
  352 +
  353 + var responseMessage = '';
  354 + try {
  355 + responseMessage =
  356 + 'Hasil advice dari webreport '
  357 + + 'ResultCode: ' + status.response.resultcode[0]
  358 + }
  359 + catch(err) {
  360 + logger.warn('Error parsing ResultCode from webreport advice.', {err: err});
  361 + }
  362 +
  363 + try {
  364 + responseMessage =
  365 + responseMessage
  366 + + ' | ErrorMsg: ' + errorMsg
  367 + }
  368 + catch(err) {
  369 + logger.warn('Error parsing ErrorMsg from webreport advice.', {err: err});
  370 + }
  371 +
  372 + try {
  373 + responseMessage =
  374 + responseMessage
  375 + + ' | TrxDate: ' + status.trxDate;
  376 + }
  377 + catch(err) {
  378 + logger.warn('Error parsing TrxDate from webreport advice.', {err: err});
  379 + }
  380 +
  381 + try {
  382 + responseMessage =
  383 + responseMessage
  384 + + ' | UpdateDate: ' + status.updateDate;
  385 +
  386 + }
  387 + catch(err) {
  388 + logger.warn('Error parsing UpdateDate from webreport advice.', {err: err});
  389 + }
  390 +
  391 + try {
  392 + responseMessage =
  393 + responseMessage
  394 + + ' | nsm: ' + status.response.nsm[0];
  395 + }
  396 + catch(err) {
  397 + logger.warn('Error parsing nsm from webreport advice.', {err: err});
  398 + }
  399 +
  400 + try {
  401 + responseMessage =
  402 + responseMessage
  403 + + ' | idpel: ' + status.response.idpel[0];
  404 + }
  405 + catch(err) {
  406 + logger.warn('Error parsing idpel from webreport advice.', {err: err});
  407 + }
  408 +
  409 + try {
  410 + responseMessage =
  411 + responseMessage
  412 + + ' | reffid: ' + status.response.reffid[0].trim();
  413 + }
  414 + catch(err) {
  415 + logger.warn('Error parsing reffid from webreport advice.', {err: err});
  416 + }
  417 +
  418 + try {
  419 + responseMessage =
  420 + responseMessage
  421 + + ' | TransID: ' + status.response.transid[0].trim();
  422 + }
  423 + catch(err) {
  424 + logger.warn('Error parsing TransID from webreport advice.', {err: err});
  425 + }
  426 +
  427 + try {
  428 + responseMessage =
  429 + responseMessage
  430 + + ' | reff_switching: ' + status.response.reff_switching[0];
  431 + }
  432 + catch(err) {
  433 + logger.warn('Error parsing reff_switching from webreport advice.', {err: err});
  434 + }
  435 +
  436 + try {
  437 + responseMessage =
  438 + responseMessage
  439 + + ' | amount_trx: ' + status.response.amount_trx[0];
  440 + }
  441 + catch(err) {
  442 + logger.warn('Error parsing amount_trx from webreport advice.', {err: err});
  443 + }
  444 +
  445 + try {
  446 + responseMessage =
  447 + responseMessage
  448 + + ' | token: ' + status.response.token[0];
  449 + }
  450 + catch(err) {
  451 + logger.warn('Error parsing token from webreport advice.', {err: err});
  452 + }
  453 +
  454 + try {
  455 + responseMessage =
  456 + responseMessage
  457 + + ' | PrevBalance: ' + status.response.prevbalance[0];
  458 + }
  459 + catch(err) {
  460 + logger.warn('Error parsing PrevBalance from webreport advice.', {err: err});
  461 + }
  462 +
  463 + try {
  464 + responseMessage =
  465 + responseMessage
  466 + + ' | Price: ' + status.amount;
  467 + }
  468 + catch(err) {
  469 + logger.warn('Error parsing Price from webreport advice.', {err: err});
  470 + }
  471 +
  472 + try {
  473 + responseMessage =
  474 + responseMessage
  475 + + ' | EndBalance: ' + status.response.endbalance[0];
  476 + }
  477 + catch(err) {
  478 + logger.warn('Error parsing EndBalance from webreport advice.', {err: err});
  479 + }
  480 +
  481 +
  482 + if ((status.status == 'S') && (status.response.resultcode[0] == '0000')) {
  483 + responseCode = '00';
  484 +
  485 + var nama_pelanggan = status.response.nama_pel[0] ;
  486 + nama_pelanggan = nama_pelanggan.replace(/-\/-/g, '-');
  487 +
  488 + var sn = status.response.token[0] + '/' + nama_pelanggan + '/' + status.response.tarif[0] + 'VA/' + status.response.jml_daya[0];
  489 + responseMessage = 'SN=' + sn + '; ' + responseMessage;
  490 +
  491 + } else if ((status.status == 'P') || (status.status == 'W')) {
  492 +
  493 + callbackReport(status.response.reffid[0].trim(), '68', responseMessage);
  494 + logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
  495 +
  496 + setTimeout(function () {
  497 +
  498 + cekstatus.advice({trxid: status.trxId,}, callbackFromWebReport);
  499 +
  500 + }, sleep_before_retry);
  501 + return;
  502 +
  503 + } else {
  504 + responseCode = status.response.resultcode[0].replace(/^00/, "");
  505 + if (['00', '05', '12', '68', '90', '63', '18', '96'].indexOf(responseCode) >= 0) {
  506 + responseCode = '40';
  507 + }
  508 + }
  509 +
  510 +
  511 + callbackReport(status.response.reffid[0].trim(), responseCode, responseMessage);
  512 +}
  513 +
  514 +function createHttpReportServer() {
  515 + var httpServer = http.createServer(function(request, response) {
  516 + var qs = url.parse(request.url, true).query;
  517 + var path = url.parse(request.url).pathname;
  518 +
  519 + logger.info('Got reverse report from partner', {path: path, qs: qs});
  520 + response.end('OK');
  521 +
  522 + var trxid;
  523 + try {
  524 + trxid = qs.transid;
  525 + }
  526 + catch(err) {
  527 + }
  528 +
  529 + if (trxid) {
  530 + logger.info('Requesting advice from webreport', {trxid: trxid})
  531 + cekstatus.advice({trxid: trxid}, callbackFromWebReport);
  532 + }
  533 +
  534 + });
  535 +
  536 + httpServer.listen(config.h2h_out.listen_port, function() {
  537 + logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
  538 + });
  539 +}
  540 +
  541 +function start(_config, _callbackReport, options) {
  542 + config = _config;
  543 + callbackReport = _callbackReport;
  544 +
  545 + if (options && options.aaa) {
  546 + aaa = options.aaa;
  547 + }
  548 +
  549 + if (options && options.logger) {
  550 + logger = options.logger;
  551 + } else {
  552 + logger = new winston.Logger({
  553 + transports: [
  554 + new (winston.transports.Console)()
  555 + ]
  556 + });
  557 + }
  558 +
  559 + createHttpReportServer();
  560 + initMongoClient();
  561 +}
  562 +
  563 +exports.start = start;
  564 +exports.topupRequest = topupRequest;