partner-fm.js 5.33 KB
var xml2js = require('xml2js');
var request = require('request');
var http = require('http');

var aaa;
var _callbackReport;
var config;
var logger;

var xmlBuilder = new xml2js.Builder();

function start(options) {
    if (!options) {
        console.log('Undefined options, terminating....');
        process.exit(1);
    }

    if (options.config) {
        config = options.config;
    } else {
        console.log('Undefined options.config, terminating....')
        process.exit(1);
    }

    if (options.aaa) {
        aaa = options.aaa;
        _callbackReport = options.aaa.callbackReportWithPushToMongoDb;
    } else {
        console.log('Undefined options.aaa, terminating....')
        process.exit(1);
    }

    if (options && options.logger) {
        logger = options.logger;
    } else {
        console.log('Undefined options.logger, terminating....')
        process.exit(1);
    }

    createServer();

    /*
    resendDelay.init({
        config: config,
        topupRequest: topupRequest,
        logger: logger
    });
    */
}

function topupRequest(task) {
    aaa.insertTaskToMongoDb(task);

    var payload = composeTopupStatusMessage(
        config.h2h_out.pin,
        task.remoteProduct,
        task.destination,
        task.requestId
    );

    var reqOpts = {
        url: config.h2h_out.partner,
        method: "POST",
        body: payload,
        headers: {
            'Content-Type': 'text/xml',
            //'Content-Length': Buffer.byteLength(payload)
        }
    };

    logger.verbose('Requesting to partner', {reqOpts: reqOpts, payload: payload});
    /*
    var buffer = "";
    var req = http.request(reqOpts, function( res ) {

        logger.info('Status code: ' + res.statusCode );
        var buffer = "";
        res.on( "data", function( data ) { buffer = buffer + data; } );
        res.on( "end", function( data ) {
            logger.verbose('Got a direct response from partner', {response: buffer, task: task});
            topupResponseHandler(buffer, task.requestId);
        });
    });
    */
    request(reqOpts, function (err, response, body) {
        if (err) {
            var msg = 'Error requesting to partner: ' + err;
            callbackReport(task.requestId, '68', msg);
            return;
        }

        logger.verbose('Got a direct response from partner', {response: body, task: task});
        topupResponseHandler(body, task.requestId, callbackReport);
    });
}

function topupResponseHandler(xmlResponse, _requestId, cb) {
    var xmlParser = xml2js.parseString;
    xmlParser(xmlResponse, function(err, data) {
        var msg;
        var requestId;
        var rc = '68';

        if (_requestId) {
            requestId = _requestId;
        }

        if (err) {
            msg = 'Error parsing xml response: ' + err;

            if (logger) {
                logger.warn(msg, {err: err, response: xmlResponse, task: task});
            } else {
                console.log(msg);
            }
        } else {

            try {
                msg = data.fm.message
            }
            catch(e) {
                msg = 'Unknown message'
            }

            if (data.fm.status == '0') {

                rc = '00';
                msg = modifyMessageWithSn(msg);

            } else if (data.fm.status == '1') {
                rc = '68';
            } else if (data.fm.status == '2') {
                rc = '40';
            } else if (data.fm.status == '3') {
                rc = '40';
            } else {
                rc = '68';
            }

            if (data.fm.refTrxid) {
                requestId = data.fm.refTrxid;
            }

        }

        cb(requestId, rc, msg, xmlResponse)
    });
}

function callbackReport(requestId, responseCode, msg, rawResponse) {
    if (requestId) {
        _callbackReport(requestId, responseCode, msg, null, rawResponse);
    } else {
        logger.warn('Undefined requestId, not sending callbackReport', {rc: responseCode, msg: msg, rawResponse: rawResponse});
    }

}

function getSnFromMessage(msg) {
    try {
        var matches = msg.match(/SN:(\w+)/);
        return matches[1];
    }
    catch(e) {
        return;
    }
}

function modifyMessageWithSn(msg) {
    var sn = getSnFromMessage(msg);
    if (sn) {
        msg = 'SN=' + sn + '; ' + msg;
    }
    return msg;
}

function composeTopupStatusMessage(pin, product, destination, requestId) {
    var data = {fm: {
        command: 'TOPUP',
        pin: pin,
        product: product,
        msisdn: destination,
        refTrxid: requestId
    }};

    return xmlBuilder.buildObject(data);
}

function createServer() {
    var httpServer = http.createServer(function(request, response) {

        logger.info('Got request from partner');

        var body = "";
        req.on('data', function (chunk) {
            body += chunk;
        });

        req.on('end', function () {
            res.writeHead(200);
            res.end('OK');

            topupResponseHandler(body, null, callbackReport);

        });

    });

    httpServer.listen(config.h2h_out.listen_port, function() {
        logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
    });
}

exports.start = start;
exports.topupRequest = topupRequest;
exports.composeTopupStatusMessage = composeTopupStatusMessage;
exports.getSnFromMessage = getSnFromMessage;
exports.modifyMessageWithSn = modifyMessageWithSn;