Commit 3f8e65bfd8b88d9484bc741a721f78e7612ef82d

Authored by Adhidarma Hadiwinoto
1 parent 31002b52f3
Exists in master

payload trugee

Showing 1 changed file with 334 additions and 0 deletions Side-by-side Diff

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