Commit cce5494939b351f03ea53f8f0164b74707d16ba4

Authored by Adhidarma Hadiwinoto
1 parent 6f81d756b4
Exists in master

coba parse

Showing 1 changed file with 14 additions and 1 deletions Inline Diff

1 var http = require('http'); 1 var http = require('http');
2 var url = require('url'); 2 var url = require('url');
3 var math = require('mathjs'); 3 var math = require('mathjs');
4 var xml = require('xml'); 4 var xml = require('xml');
5 var xml2js = require('xml2js').parseString; 5 var xml2js = require('xml2js').parseString;
6 var strftime = require('strftime'); 6 var strftime = require('strftime');
7 var xor = require('base64-xor'); 7 var xor = require('base64-xor');
8 var request = require('request'); 8 var request = require('request');
9 9
10 var config; 10 var config;
11 var callbackReport; 11 var callbackReport;
12 12
13 var max_retry = 2; 13 var max_retry = 2;
14 var sleep_before_retry = 2000; 14 var sleep_before_retry = 2000;
15 15
16 var trx_balances = {}; 16 var trx_balances = {};
17 var trx_prices = {}; 17 var trx_prices = {};
18 18
19 function calculateSignature(password, msisdn, timestamp) { 19 function calculateSignature(password, msisdn, timestamp) {
20 var a = timestamp + msisdn.substr(msisdn.length - 4); 20 var a = timestamp + msisdn.substr(msisdn.length - 4);
21 var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password; 21 var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password;
22 22
23 return xor.encode(a,b); 23 return xor.encode(a,b);
24 } 24 }
25 25
26 /** 26 /**
27 * Kalkulasi signature untuk cek balance 27 * Kalkulasi signature untuk cek balance
28 * 28 *
29 * @deprecated 29 * @deprecated
30 */ 30 */
31 function calculateBalanceSignature(userid, password, timestamp) { 31 function calculateBalanceSignature(userid, password, timestamp) {
32 var a = '0000' + timestamp; 32 var a = '0000' + timestamp;
33 var b = userid.substr(0, 4) + password; 33 var b = userid.substr(0, 4) + password;
34 34
35 return xor.encode(a,b); 35 return xor.encode(a,b);
36 } 36 }
37 37
38 38
39 function createPayload(task) { 39 function createPayload(task) {
40 var timestamp = strftime('%H%M%S'); 40 var timestamp = strftime('%H%M%S');
41 41
42 var payload = { 42 var payload = {
43 pulsamatic: [ 43 pulsamatic: [
44 {command: 'TOPUP'}, 44 {command: 'TOPUP'},
45 {vtype: task['remoteProduct']}, 45 {vtype: task['remoteProduct']},
46 {userid: config.h2h_out.userid}, 46 {userid: config.h2h_out.userid},
47 {time: timestamp}, 47 {time: timestamp},
48 {msisdn: task['destination']}, 48 {msisdn: task['destination']},
49 {trxid: task['requestId']}, 49 {trxid: task['requestId']},
50 {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)} 50 {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)}
51 ] 51 ]
52 }; 52 };
53 53
54 console.log(payload); 54 console.log(payload);
55 return "<?xml version=\"1.0\" ?>\n" + xml(payload); 55 return "<?xml version=\"1.0\" ?>\n" + xml(payload);
56 } 56 }
57 57
58 function topupRequest(task, retry) { 58 function topupRequest(task, retry) {
59 //balanceCheck(); 59 //balanceCheck();
60 60
61 var payload_xml = createPayload(task); 61 var payload_xml = createPayload(task);
62 //console.log(payload_xml); 62 //console.log(payload_xml);
63 63
64 var partner = url.parse(config.h2h_out.partner); 64 var partner = url.parse(config.h2h_out.partner);
65 65
66 var request_options = { 66 var request_options = {
67 host: partner.hostname, 67 host: partner.hostname,
68 path: partner.path, 68 path: partner.path,
69 port: partner.port, 69 port: partner.port,
70 method: "POST", 70 method: "POST",
71 headers: { 71 headers: {
72 'Content-Type': 'text/xml', 72 'Content-Type': 'text/xml',
73 'Content-Length': Buffer.byteLength(payload_xml) 73 'Content-Length': Buffer.byteLength(payload_xml)
74 } 74 }
75 }; 75 };
76 76
77 var buffer = ""; 77 var buffer = "";
78 var req = http.request(request_options, function( res ) { 78 var req = http.request(request_options, function( res ) {
79 79
80 console.log('Status code: ' + res.statusCode ); 80 console.log('Status code: ' + res.statusCode );
81 var buffer = ""; 81 var buffer = "";
82 res.on( "data", function( data ) { buffer = buffer + data; } ); 82 res.on( "data", function( data ) { buffer = buffer + data; } );
83 res.on( "end", function( data ) { 83 res.on( "end", function( data ) {
84 topupResponseHandler(buffer); 84 directResponseHandler(buffer, task['requestId']);
85 }); 85 });
86 86
87 }); 87 });
88 88
89 req.on('error', function(e) { 89 req.on('error', function(e) {
90 console.log('problem with request: ' + e.message); 90 console.log('problem with request: ' + e.message);
91 callbackReport(task['requestId'], '40', e.message); 91 callbackReport(task['requestId'], '40', e.message);
92 }); 92 });
93 93
94 req.write( payload_xml ); 94 req.write( payload_xml );
95 req.end(); 95 req.end();
96 } 96 }
97 97
98 function directResponseHandler(body, request_id) {
99 xml2js(body, function (err, result) {
100 if (err) {
101 console.log(body);
102 callbackReport(request_id, '40', buffer);
103 return;
104 }
105 console.log(result);
106 //request_id = result.pulsamatic.trxid;
107 };
108
109 }
110
98 function topupResponseHandler(body, request_id) { 111 function topupResponseHandler(body, request_id) {
99 console.log(body); 112 console.log(body);
100 return; 113 return;
101 xml2js(body, function (err, result) { 114 xml2js(body, function (err, result) {
102 if (err) { 115 if (err) {
103 console.log(body); 116 console.log(body);
104 callbackReport(request_id, '40', buffer); 117 callbackReport(request_id, '40', buffer);
105 return; 118 return;
106 } 119 }
107 120
108 console.log(result); 121 console.log(result);
109 122
110 request_id = result.datacell.ref_trxid[0].trim(); 123 request_id = result.datacell.ref_trxid[0].trim();
111 124
112 var response_code = '68'; 125 var response_code = '68';
113 126
114 var message = ''; 127 var message = '';
115 try { 128 try {
116 if (result.datacell.message && result.datacell.message.length > 0) { 129 if (result.datacell.message && result.datacell.message.length > 0) {
117 message = result.datacell.message[0].trim(); 130 message = result.datacell.message[0].trim();
118 } else if (result.datacell.msg && result.datacell.msg.length > 0) { 131 } else if (result.datacell.msg && result.datacell.msg.length > 0) {
119 message = result.datacell.msg[0].trim(); 132 message = result.datacell.msg[0].trim();
120 } 133 }
121 } 134 }
122 catch(err) { 135 catch(err) {
123 message = 'exception saat parsing message'; 136 message = 'exception saat parsing message';
124 } 137 }
125 138
126 if (result.datacell.resultcode && result.datacell.resultcode[0] == '999') { 139 if (result.datacell.resultcode && result.datacell.resultcode[0] == '999') {
127 response_code = '40'; 140 response_code = '40';
128 } 141 }
129 142
130 if (message.indexOf('Nomor tujuan salah') >= 0) { 143 if (message.indexOf('Nomor tujuan salah') >= 0) {
131 response_code = '14'; 144 response_code = '14';
132 } else if (message.indexOf('*GAGAL, transaksi yang sama sudah ada dalam 10 menit') >= 0) { 145 } else if (message.indexOf('*GAGAL, transaksi yang sama sudah ada dalam 10 menit') >= 0) {
133 response_code = '55'; 146 response_code = '55';
134 } else if (message.indexOf('saldo sdh dikembalikan') >= 0) { 147 } else if (message.indexOf('saldo sdh dikembalikan') >= 0) {
135 response_code = '40' 148 response_code = '40'
136 } else if (message.indexOf('Trx dpt diulang') >= 0) { 149 } else if (message.indexOf('Trx dpt diulang') >= 0) {
137 response_code = '40' 150 response_code = '40'
138 } else if (message.indexOf('SUKSES SN Operator:') >= 0) { 151 } else if (message.indexOf('SUKSES SN Operator:') >= 0) {
139 response_code = '00'; 152 response_code = '00';
140 153
141 var sn = parseSN(message); 154 var sn = parseSN(message);
142 console.log ('SN Operator: ' + sn); 155 console.log ('SN Operator: ' + sn);
143 156
144 if (sn) { 157 if (sn) {
145 message = 'SN=' + sn + '; ' + message; 158 message = 'SN=' + sn + '; ' + message;
146 } else { 159 } else {
147 message = 'SN belum didapat. ' + message; 160 message = 'SN belum didapat. ' + message;
148 response_code = '68'; 161 response_code = '68';
149 } 162 }
150 } 163 }
151 164
152 165
153 var price = priceFromMessage(message); 166 var price = priceFromMessage(message);
154 if (price != null) { 167 if (price != null) {
155 console.log('Harga: ' + price); 168 console.log('Harga: ' + price);
156 trx_prices[request_id] = price; 169 trx_prices[request_id] = price;
157 setTimeout(deleteTrxPrice, 3 * 24 * 3600 * 1000, request_id); 170 setTimeout(deleteTrxPrice, 3 * 24 * 3600 * 1000, request_id);
158 } else if (response_code == '00' && trx_prices[request_id] !== undefined) { 171 } else if (response_code == '00' && trx_prices[request_id] !== undefined) {
159 price = trx_prices[request_id]; 172 price = trx_prices[request_id];
160 console.log('Harga: ' + price); 173 console.log('Harga: ' + price);
161 message = message + ' -- Harga: ' + price; 174 message = message + ' -- Harga: ' + price;
162 } 175 }
163 176
164 var balance = balanceFromMessage(message); 177 var balance = balanceFromMessage(message);
165 if (balance != null) { 178 if (balance != null) {
166 console.log('Saldo: ' + balance); 179 console.log('Saldo: ' + balance);
167 trx_balances[request_id] = balance; 180 trx_balances[request_id] = balance;
168 setTimeout(deleteTrxBalance, 3 * 24 * 3600 * 1000, request_id); 181 setTimeout(deleteTrxBalance, 3 * 24 * 3600 * 1000, request_id);
169 } else if (response_code == '00' && trx_balances[request_id] !== undefined) { 182 } else if (response_code == '00' && trx_balances[request_id] !== undefined) {
170 balance = trx_balances[request_id]; 183 balance = trx_balances[request_id];
171 console.log('Saldo: ' + balance); 184 console.log('Saldo: ' + balance);
172 message = message + ' -- Saldo: ' + balance; 185 message = message + ' -- Saldo: ' + balance;
173 } 186 }
174 187
175 callbackReport(request_id, response_code, message); 188 callbackReport(request_id, response_code, message);
176 }); 189 });
177 } 190 }
178 191
179 function deleteTrxPrice(request_id) { 192 function deleteTrxPrice(request_id) {
180 delete trx_prices[request_id]; 193 delete trx_prices[request_id];
181 } 194 }
182 195
183 function deleteTrxBalance(request_id) { 196 function deleteTrxBalance(request_id) {
184 delete trx_balances[request_id]; 197 delete trx_balances[request_id];
185 } 198 }
186 199
187 function parseSN(message) { 200 function parseSN(message) {
188 var results = message.match(/SN Operator: .+ SN Kami/); 201 var results = message.match(/SN Operator: .+ SN Kami/);
189 if (!results || results.length <= 0) { 202 if (!results || results.length <= 0) {
190 return ''; 203 return '';
191 } 204 }
192 205
193 var result = results[0]; 206 var result = results[0];
194 result = result.replace('SN Operator:', ''); 207 result = result.replace('SN Operator:', '');
195 result = result.replace('SN Kami', ''); 208 result = result.replace('SN Kami', '');
196 result = result.trim(); 209 result = result.trim();
197 210
198 if (result == '00') { 211 if (result == '00') {
199 result = ''; 212 result = '';
200 } 213 }
201 214
202 return result; 215 return result;
203 } 216 }
204 217
205 function createServer() { 218 function createServer() {
206 219
207 var httpServer = http.createServer(function(req, res) { 220 var httpServer = http.createServer(function(req, res) {
208 var parsed_url = url.parse(req.url, true, true); 221 var parsed_url = url.parse(req.url, true, true);
209 222
210 console.log('Got request from partner ("' + req.url + '")'); 223 console.log('Got request from partner ("' + req.url + '")');
211 224
212 var body = ""; 225 var body = "";
213 req.on('data', function (chunk) { 226 req.on('data', function (chunk) {
214 body += chunk; 227 body += chunk;
215 }); 228 });
216 229
217 req.on('end', function () { 230 req.on('end', function () {
218 res.writeHead(200); 231 res.writeHead(200);
219 res.end('OK'); 232 res.end('OK');
220 233
221 //console.log(body); 234 //console.log(body);
222 235
223 if (parsed_url.pathname == '/sn') { 236 if (parsed_url.pathname == '/sn') {
224 console.log('Reverse report -- SN'); 237 console.log('Reverse report -- SN');
225 topupResponseHandler(body); 238 topupResponseHandler(body);
226 239
227 } else if (parsed_url.pathname = '/refund') { 240 } else if (parsed_url.pathname = '/refund') {
228 console.log('Reverse report -- REFUND'); 241 console.log('Reverse report -- REFUND');
229 callbackReport(parsed_url.query.ref_trxid, '40', parsed_url.query.message); 242 callbackReport(parsed_url.query.ref_trxid, '40', parsed_url.query.message);
230 243
231 } else { 244 } else {
232 console.log('Reverse report -- UNKNOWN'); 245 console.log('Reverse report -- UNKNOWN');
233 console.log('Ignore unknown request on reverse url'); 246 console.log('Ignore unknown request on reverse url');
234 } 247 }
235 }); 248 });
236 }); 249 });
237 250
238 httpServer.listen(config.h2h_out.listen_port, function() { 251 httpServer.listen(config.h2h_out.listen_port, function() {
239 console.log('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); 252 console.log('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
240 }); 253 });
241 } 254 }
242 255
243 function balanceCheck() { 256 function balanceCheck() {
244 var timestamp = strftime('%H%M%S'); 257 var timestamp = strftime('%H%M%S');
245 258
246 var payload = { 259 var payload = {
247 datacell: [ 260 datacell: [
248 {perintah: 'saldo'}, 261 {perintah: 'saldo'},
249 {userid: config.h2h_out.userid}, 262 {userid: config.h2h_out.userid},
250 {time: timestamp}, 263 {time: timestamp},
251 {sgn: calculateBalanceSignature(config.h2h_out.userid, config.h2h_out.password, timestamp)} 264 {sgn: calculateBalanceSignature(config.h2h_out.userid, config.h2h_out.password, timestamp)}
252 ] 265 ]
253 }; 266 };
254 267
255 var postRequest = { 268 var postRequest = {
256 host: "202.152.62.2", 269 host: "202.152.62.2",
257 path: "/RELOAD97.php", 270 path: "/RELOAD97.php",
258 port: 7713, 271 port: 7713,
259 method: "POST", 272 method: "POST",
260 headers: { 273 headers: {
261 'Content-Type': 'text/xml', 274 'Content-Type': 'text/xml',
262 'Content-Length': Buffer.byteLength(payload_xml) 275 'Content-Length': Buffer.byteLength(payload_xml)
263 } 276 }
264 }; 277 };
265 278
266 var buffer = ""; 279 var buffer = "";
267 var req = http.request( postRequest, function( res ) { 280 var req = http.request( postRequest, function( res ) {
268 281
269 console.log('Status code: ' + res.statusCode ); 282 console.log('Status code: ' + res.statusCode );
270 var buffer = ""; 283 var buffer = "";
271 res.on( "data", function( data ) { buffer = buffer + data; } ); 284 res.on( "data", function( data ) { buffer = buffer + data; } );
272 res.on( "end", function( data ) { 285 res.on( "end", function( data ) {
273 console.log('CHECK BALANCE RESULT:'); 286 console.log('CHECK BALANCE RESULT:');
274 console.log(buffer); 287 console.log(buffer);
275 }); 288 });
276 289
277 }); 290 });
278 291
279 req.on('error', function(e) { 292 req.on('error', function(e) {
280 console.log('problem with request: ' + e.message); 293 console.log('problem with request: ' + e.message);
281 }); 294 });
282 295
283 req.write( payload_xml ); 296 req.write( payload_xml );
284 req.end(); 297 req.end();
285 298
286 } 299 }
287 300
288 function balanceFromMessage(message) { 301 function balanceFromMessage(message) {
289 var matches = message.match(/Saldo: Rp (\d+)/); 302 var matches = message.match(/Saldo: Rp (\d+)/);
290 303
291 if (!matches) { 304 if (!matches) {
292 return null; 305 return null;
293 } 306 }
294 if (matches.length < 2) { 307 if (matches.length < 2) {
295 return null; 308 return null;
296 } 309 }
297 310
298 return matches[1]; 311 return matches[1];
299 } 312 }
300 313
301 function priceFromMessage(message) { 314 function priceFromMessage(message) {
302 var matches = message.match(/Harga: (\d+)/); 315 var matches = message.match(/Harga: (\d+)/);
303 316
304 if (!matches) { 317 if (!matches) {
305 return null; 318 return null;
306 } 319 }
307 if (matches.length < 2) { 320 if (matches.length < 2) {
308 return null; 321 return null;
309 } 322 }
310 323
311 return matches[1]; 324 return matches[1];
312 } 325 }
313 326
314 function start(_config, _callbackReport) { 327 function start(_config, _callbackReport) {
315 config = _config; 328 config = _config;
316 callbackReport = _callbackReport 329 callbackReport = _callbackReport
317 330
318 createServer(); 331 createServer();
319 } 332 }
320 333
321 exports.start = start; 334 exports.start = start;
322 exports.topupRequest = topupRequest; 335 exports.topupRequest = topupRequest;
323 exports.balanceFromMessage = balanceFromMessage; 336 exports.balanceFromMessage = balanceFromMessage;
324 exports.priceFromMessage = priceFromMessage; 337 exports.priceFromMessage = priceFromMessage;
325 exports.calculateSignature = calculateSignature; 338 exports.calculateSignature = calculateSignature;
326 339