diff --git a/package.json b/package.json index 96739c5..65d2b15 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git", "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git", "strftime": "^0.9.2", - "winston": "^2.2.0" + "winston": "^2.2.0", + "xml2js": "^0.4.16" } } diff --git a/partner-trustlink.js b/partner-trustlink.js new file mode 100644 index 0000000..75eb3a0 --- /dev/null +++ b/partner-trustlink.js @@ -0,0 +1,164 @@ +var winston = require('winston'); +var request = require('request'); +var strftime = require('strftime'); +var url = require('url'); +var xor = require('base64-xor'); +var http = require('http'); +var xml2js = require('xml2js').parseString; + +var max_retry = 3; +var sleep_before_retry = 2000; + +var config; +var callbackReport; +var aaa; +var logger; +var options; + +function start(_config, _callbackReport, options) { + config = _config; + callbackReport = _callbackReport + + if (options && options.aaa) { + aaa = options.aaa; + } + + if (options && options.logger) { + logger = options.logger; + } else { + logger = new winston.Logger({ + transports: [ + new (winston.transports.Console)() + ] + }); + } + + createReverseReportServer(); +} + +function createReverseReportServer() { + var httpServer = http.createServer(onReverseReport).listen(config.h2h_out.listen_port, function() { + logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); + }); +} + +function onReverseReport(req, res) { + res.end('OK'); + + var qs = url.parse(req.url, true).query; + logger.info('Reverse Report', {qs: qs}); +} + +function calculateSignature(ts, destination, password) { + var a = ts + destination.substr(destination.length - 4); + var b = destination.substr(destination.length - 4).split('').reverse().join('') + password; + + return xor.encode(a,b); +} + +function createXmlPayload(task, userid, password) { + var ts = strftime('%H%M%S', new Date()); + + var signature = calculateSignature(ts, task.destination, password); + + var payload = { + evoucher: [ + {command: 'TOPUP'}, + {product: task.remoteProduct}, + {userid: userid}, + {time: ts}, + {msisdn: task.destination}, + {partner_trxid: task.requestId}, + {signature: signature}, + {trxke: 1}, + ] + }; + + if (logger) { + logger.verbose('Generate xml payload', {payload: payload}); + } + + return "<?xml version=\"1.0\" ?>\n" + xml(payload); +} + +function topupRequest(task, retry) { + if (retry === undefined) { + retry = max_retry; + } + + var payload = createXmlPayload(task, config.globals.userid, config.globals.password); + + var partner = url.parse(config.h2h_out.partner); + + var request_options = { + host: partner.hostname, + path: partner.path, + port: partner.port, + method: "POST", + headers: { + 'Content-Type': 'text/xml', + 'Content-Length': Buffer.byteLength(payload) + } + }; + + var buffer = ""; + + logger.info('Requesting to partner', {request_options: request_options}); + + var req = http.request(request_options, function( res ) { + + logger.info('Status code: ' + res.statusCode ); + var buffer = ""; + res.on( "data", function( data ) { buffer = buffer + data; } ); + res.on( "end", function( data ) { + //directResponseHandler(buffer, task); + logger.info('Got direct response from partner', {resp: buffer}); + }); + + }); + + req.on('error', function(e) { + logger.warn('problem with request: ' + e.message); + callbackReport(task.requestId, '68', e.message); + return; + }); + + logger.verbose('Sending payload to partner', {payload: payload}); + req.write( payload ); + req.end(); +} + +function directResponseHandler(body, task) { + + logger.info('Got direct response'); + + xml2js(body, function (err, result) { + if (err) { + logger.warn('Error parsing xml', {body: body}); + callbackReport(request_id, '68', buffer); + return; + } + + logger.info('Direct response parsed', {result: result}); + + var response_code = '68'; + + var request_id = result.evoucher.partner_trxid[0].trim(); + var message = result.evoucher.message[0].trim(); + var status = result.evoucher.result[0].trim(); + + if (status === 'failed') { + response_code = '40'; + + var new_response_code = responseCodeFromMessage(message); + if (new_response_code) { + response_code = new_response_code; + } + + } + + callbackReport(request_id, response_code, message); + }); +} + +export.start = start;