partner-irs.js 8.46 KB
var winston = require('winston');
var request = require('request');
var xmlrpc = require('xmlrpc');
var url = require('url');
var http = require('http');
var mongoClient = require('mongodb').MongoClient;
var strftime = require('strftime');
var moment = require('moment');

var max_retry = 6;
var sleep_before_retry = 10000;

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

var config;
var callbackReport;
var aaa;
var logger;
var options;
var mongodb;

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)()
            ]
        });
    }

    createXMLRPCServer();
    initMongoClient();
}

function createXMLRPCServer() {

    logger.info('Creating XML-RPC server on port ' + config.h2h_out.listen_port);
    var serverOptions = {
        port: config.h2h_out.listen_port
    };

    var server = xmlrpc.createServer(serverOptions);

    server.on('NotFound', function (method, params) {
        logger.warn('Unknown method recevied on XMLRPC server', {xmlrpc_method: method, xmlrpc_params: params});
    });

    server.on('topUpReport', function (err, params, callback) {

        logger.info('Got XMLRPC topUpReport request from partner', {xmlrpc_method: 'topUpReport', xmlrpc_params: params});

        var paramscount = params.length;
        for (var i = 0; i < paramscount; i++) {
            var value = params[i];

            var responseTs =  strftime('%Y-%m-%d %H:%M:%S', new Date());
            var dummyTask = { requestId: value.REQUESTID };

            if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') {
                value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE'];
            }

            if (value['RESPONSECODE'] != '00' && value['RESPONSECODE'] != '68') {
                value['RESPONSECODE'] = getResponseCodeByMessage(value['MESSAGE']);
            }

            pushResponseToMongoDb(dummyTask, {ts:  responseTs, supplier: config.globals.gateway_name, raw: JSON.stringify(value), parsed: value}, value['RESPONSECODE']);

            callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']);
        }

        callback(null, 'ACK REPORT OK');
    })
}

function getResponseCodeByMessage(msg) {
    if (msg.indexOf("Trx XL-AXIS NO SALAH") >= 0) {
        return '14';
    }
    else if (msg.indexOf("gagal Nomer salah/Nomer Belum Aktif") >= 0) {
        return '14';
    }
    else if (msg.indexOf("GAGAL NOMER SALAH") >= 0) {
        return '14';
    }
    else if (msg.indexOf("GAGAL NOMER  SALAH") >= 0) {
        return '14';
    }
    else {
        return '40'
    }
}

function topupRequestXMLRPC(task, retry) {
    var partnerUrl = url.parse(config.h2h_out.partner);
    var clientOptions = {
        host: partnerUrl.hostname
        , port: partnerUrl.port
        , path: partnerUrl.pathname
    };
    logger.info('Preparing XMLRPC client options', {options: clientOptions});

    var client;
    if (partnerUrl.protocol == 'https:') {
        client = xmlrpc.createSecureClient(clientOptions);
    } else {
        client = xmlrpc.createClient(clientOptions);
    }

    var params = {
        MSISDN: config.h2h_out.userid,
        REQUESTID: task.requestId,
        PIN: config.h2h_out.password,
        NOHP: task.destination,
        NOM: task.remoteProduct
    };

    var methodName = 'topUpRequest';
    logger.info('Preparing XMLRPC client method', {methodname: methodName, params: params});

    client.methodCall(methodName, [ params ], function (error, value) {
        // Results of the method response
        if (error) {

            logger.warn('XMLRPC Client Error', {requestId: task['requestId'], errorMessage: error});
            var responseTs =  strftime('%Y-%m-%d %H:%M:%S', new Date());
            var dummyValue = {
                MESSAGE: 'GENERATED: XMLRPC Client Error. ' + error,
                RESPONSECODE: '68',
                REQUESTID: task.requestId,
            }

            try {
                dummyValue.HTTP_STATUS = error.res && error.res.statusCode;
                dummyValue.RESPONSEBODY = error.body;
            }
            catch(errRB) {}

            if (retry) {

                dummyValue.MESSAGE = dummyValue.MESSAGE + '. Retrying (' + retry + ')';
                logger.info(dummyValue.MESSAGE);
                setTimeout(function() {
                    topupRequest(task, retry - 1);
                }, sleep_before_retry);

            } else {
                callbackReport(task['requestId'], '68', 'GENERATED: Silahkan resend. Gangguan koneksi ke suplier: ' + error);
            }

            pushResponseToMongoDb(
                task,
                {
                    ts:  responseTs,
                    supplier: config.globals.gateway_name,
                    raw: JSON.stringify(dummyValue),
                    parsed: dummyValue
                },
                '68'
            );
            return;
        }

        logger.info('Got XMLRPC response from partner for', {response_method: methodName, response_message: value});

        var responseTs =  strftime('%Y-%m-%d %H:%M:%S', new Date());

        /*
        if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') {
            value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE'];
        }
        */

        if (value['RESPONSECODE'] != '00' && value['RESPONSECODE'] != '68') {
            value['RESPONSECODE'] = getResponseCodeByMessage(value['MESSAGE']);
        }

        /*
        if (value['RESPONSECODE'] != '00') {
            try {
                value['MESSAGE'] = value['MESSAGE'].replace(/\.;/, ';');
            }
            catch(errReplaceDot) { }

        }
        */

        pushResponseToMongoDb(task, {ts:  responseTs, supplier: config.globals.gateway_name, raw: JSON.stringify(value), parsed: value}, value['RESPONSECODE']);

        callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']);
    });
}

function topupRequest(task, retry) {
    if (retry === undefined || retry === null) {
        task.ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss');
        task.ts_date = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD');

        retry = max_retry;

        insertTaskToMongoDb(task);
    }

    topupRequestXMLRPC(task, retry);
}

function initMongoClient() {
    if (!config.mongodb || !config.mongodb.url) {
        return;
    }

    try {
        var url = config.mongodb.url;

        mongoClient.connect(url, function(err, db) {
            if (err) {
                logger.warn('Failed to connect to mongodb', {err: err});
                return;
            }
            mongodb = db;
            logger.info('MongoDB connected');
        });
    }
    catch(err) {
        logger.warn('Exception when connecting to mongodb', {err: err, url: url});
    }
}

function isMongoReady() {
    if (!config.mongodb) { return; }
    if (!config.mongodb.collection) { return; }
    if (!mongodb) { return; }

    return true;
}

function insertTaskToMongoDb(task) {
    if (!isMongoReady()) { return; }

    task.supplier = config.globals.gateway_name;
    task.rc = '68';

    try {
        mongodb.collection(config.mongodb.collection).insertOne(task);
    }
    catch(err) {
        //logger.warn('Exception when inserting document to mongodb', {err: err, task: task});
    }
}

function pushResponseToMongoDb(task, response, rc) {
    if (!isMongoReady()) { return; }

    try {
        mongodb.collection(config.mongodb.collection).updateOne(
            {requestId: task.requestId},
            {
                $set: {
                    lastResponse: response,
                    supplier: config.globals.gateway_name,
                    rc: rc
                },
                $push: {
                    responses: response
                }
            },
            function(err, result) {
                if (err) {
                    logger.warn('Error when pushing response to mongodb', {err: err, task: task, response: response});
                    return;
                }
            }
        );
    }
    catch(err) {
        logger.warn('Exception when pushing response to mongodb', {err: err, task: task, response: response});
    }
}

exports.start = start;
exports.topupRequest = topupRequest;