partner-sc.js 13.1 KB
var fs = require('fs');
var https = require('https');
var http = require('http');
var url = require('url');
var request = require('request');
var xml2js = require('xml2js').parseString;
var strftime = require('strftime');
var math = require('mathjs');
var winston = require('winston');
var cekstatus = require('./cekstatus.js');

var config;
var httpServer;
var aaa;
var logger;
var callbackReport;

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

var sleep_before_retry = 30000;

var logTag = __filename.split('/').reverse()[0];

function topupRequest(task) {

    var ts = strftime('%Y%m%d%H%M%S', new Date());
    
    var data = 
        config.h2h_out.userid 
        + '|' + config.h2h_out.password 
        + '|' + task['remoteProduct'] 
        + '|' + task['destination'] + '|0';
    
    var options = {
        url: config.h2h_out.partner,
        qs: {
            ts: ts,
            data: data,
            reffid: task['requestId']
        }
    };
    logger.info('Creating http request', {options: options});

    request(options, function (error, response, body) {
        var responseCode = '40';
        var responseMessage = 'Gateway Error';

        if (error) {
            
            logger.warn('HTTP REQUEST ERROR', error);
            callbackReport(task['requestId'], '89', 'HTTP REQUEST ERROR (' + error + ')');
            
        } else if (response.statusCode != 200) {
            
            var error_message = 'GATEWAY ERROR (HTTP RESPONSE CODE: ' + response.statusCode + ')';
            logger.warn(error_message);
            callbackReport(task['requestId'], '91', error_message);
            
        } else {

            logger.info('DIRECT RESPONSE', {body: body});

            xml2js(body, function (err, result) {
                if (err) {
                    callbackReport(task['requestId'], '40', body);
                } else {
                    var directResponse = result;
                    logger.info(directResponse);
                    
                    try {
                        var result_price;
                        try {
                            result_price = directResponse.Result.Price[0].trim();
                        }
                        catch(err) {
                            result_price = 0;
                        }
                        
                        var result_error_message;
                        try {
                            result_error_message = directResponse.Result.ErrorMsg[0].trim();
                        }
                        catch(err) {
                            result_error_message = '';
                        }
                        
                        var resultCode = directResponse.Result.ResultCode[0].trim();
                        
                        responseMessage = 
                            'ResultCode: ' + resultCode
                            + ' | ErrorMsg: ' + result_error_message
                            + ' | DateTime: ' + directResponse.Result.DateTime[0].trim()
                            + ' | nsm: ' + directResponse.Result.nsm[0].trim()
                            + ' | idpel: ' + directResponse.Result.idpel[0].trim()
                            + ' | reffid: ' + directResponse.Result.reffid[0].trim()
                            + ' | TransID: ' + directResponse.Result.TransID[0].trim()
                            + ' | reff_switching: ' + directResponse.Result.reff_switching[0].trim()
                            + ' | amount_trx: ' + directResponse.Result.amount_trx[0].trim()
                            + ' | token: ' + directResponse.Result.token[0].trim()
                            + ' | PrevBalance: ' + directResponse.Result.PrevBalance[0].trim()
                            + ' | Price: ' + result_price
                            + ' | EndBalance: ' + directResponse.Result.EndBalance[0].trim()
                            ;
                            
                        logger.info('Response message: ' + responseMessage);
                        
                        if (aaa) {
                            // update balance
                            aaa.updateBalance(directResponse.Result.EndBalance[0]);
                        }
                        
                        if (resultCode == '0000') {
                            var nama_pelanggan = directResponse.Result.nama_pel[0].trim();
                            nama_pelanggan =  nama_pelanggan.replace(/-\/-/g, '-');
                            var sn = directResponse.Result.token[0].trim() + '/' + nama_pelanggan + '/' + directResponse.Result.tarif[0].trim() + '/' + directResponse.Result.daya[0].trim() + 'VA/' + directResponse.Result.jml_daya[0].trim();
                            sn = sn.replace(/\s/g, '-');
                            
                            responseMessage = 'SN=' + sn + '; ' + responseMessage;
                            logger.info('New response message: ' + responseMessage);
                        }
                        
                        var pendingResultCode = ['0005', '0012', '0068', '0090', '0063', '0018', '0096'];
                        if (pendingResultCode.indexOf(resultCode) != -1) {
                            callbackReport(task['requestId'], '68', responseMessage);
                            
                            logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
                            setTimeout(function () {
                                cekstatus.advice({trxid: directResponse.Result.TransID[0].trim()}, callbackFromWebReport);
                            }, sleep_before_retry);
                            
                            return;
                        }
                        
                        responseCode = resultCode.replace(/^00/, "");
                        
                        if (result_error_message == 'Inq - APLICATION SERVER RESPONSE TIMEOUT') {
                            responseCode = '91';
                        }                        
                        
                    }
                    catch(err) {
                        responseCode = '40';
                        responseMessage = 'Invalid response from gateway';
                    }
                }
                
                callbackReport(task['requestId'], responseCode, responseMessage);
            });
        }

        //callbackReport(task['requestId'], responseCode, responseMessage);
    });
}

function callbackFromWebReport(status) {
    if (!status) {
        logger.warn('Advice from webreport return empty status');
        return;
    }
    
    logger.info('Got advice result from webreport', {status: status});
    
    var responseCode = '68';
    
    var result_price = 0;
    try {
        result_price = directResponse.Result.Price[0].trim();
    }
    catch(err) {}
    
    var errorMsg = '';
    try {
        errorMsg = status.response.errormsg[0];
    }
    catch(err) {}
    
    var responseMessage = '';
    try {
        responseMessage = 
            'Hasil advice dari webreport '
            + 'ResultCode: ' + status.response.resultcode[0]
    }
    catch(err) {
        logger.warn('Error parsing ResultCode from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | ErrorMsg: ' + errorMsg
    }
    catch(err) {
        logger.warn('Error parsing ErrorMsg from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | TrxDate: ' + status.trxDate;
    }
    catch(err) {
        logger.warn('Error parsing TrxDate from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | UpdateDate: ' + status.updateDate;
    
    }
    catch(err) {
        logger.warn('Error parsing UpdateDate from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | nsm: ' + status.response.nsm[0];
    }
    catch(err) {
        logger.warn('Error parsing nsm from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | idpel: ' + status.response.idpel[0];
    }
    catch(err) {
        logger.warn('Error parsing idpel from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | reffid: ' + status.response.reffid[0].trim();
    }
    catch(err) {
        logger.warn('Error parsing reffid from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | TransID: ' + status.response.transid[0].trim();
    }
    catch(err) {
        logger.warn('Error parsing TransID from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | reff_switching: ' + status.response.reff_switching[0];
    }
    catch(err) {
        logger.warn('Error parsing reff_switching from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | amount_trx: ' + status.response.amount_trx[0];
    }
    catch(err) {
        logger.warn('Error parsing amount_trx from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | token: ' + status.response.token[0];
    }
    catch(err) {
        logger.warn('Error parsing token from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | PrevBalance: ' + status.response.PrevBalance[0];
    }
    catch(err) {
        logger.warn('Error parsing PrevBalance from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | Price: ' + status.amount;
    }
    catch(err) {
        logger.warn('Error parsing Price from webreport advice.', {err: err});
    }
    
    try {
        responseMessage = 
            responseMessage
            + ' | EndBalance: ' + status.response.endbalance[0];
    }
    catch(err) {
        logger.warn('Error parsing EndBalance from webreport advice.', {err: err});
    }
    
    
    if ((status.status == 'S') && (status.response.resultcode[0] == '0000')) {
        responseCode = '00';
        
        var nama_pelanggan = status.response.nama_pel[0] ;
        nama_pelanggan =  nama_pelanggan.replace(/-\/-/g, '-');
        
        var sn = status.response.token[0] + '/' + nama_pelanggan + '/' + status.response.tarif[0] + 'VA' + status.response.jml_daya[0];
        responseMessage = 'SN=' + sn + '; ' + responseMessage;
    
    } else if ((status.status == 'P') || (status.status == 'W')) {
        
        callbackReport(status.response.reffid[0].trim(), '68', responseMessage);
        logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
        
        setTimeout(function () {
            
            cekstatus.advice({trxid: status.trxId,}, callbackFromWebReport);
            
        }, sleep_before_retry);
        return;
        
    } else {
        responseCode = status.response.resultcode[0].replace(/^00/, "");
        if (['00', '05', '12', '68', '90', '63', '18', '96'].indexOf(responseCode) >= 0) {
            responseCode = '40';
        }
    }
    
    
    callbackReport(status.response.reffid[0].trim(), responseCode, responseMessage);
}

function createHttpReportServer() {
    var httpServer = http.createServer(function(request, response) {
        var qs = url.parse(request.url, true).query;
        var path = url.parse(request.url).pathname;
        
        logger.info('Got reverse report from partner', {path: path, qs: qs});
        response.end('OK');
        
        var  trxid;
        try {
            trxid = qs.transid;
        }
        catch(err) {
        }
        
        if (trxid) {
            logger.info('Requesting advice from webreport', {trxid: trxid})
            cekstatus.advice({trxid: trxid}, callbackFromWebReport);
        }
        
    });
    
    httpServer.listen(config.h2h_out.listen_port, function() {
        logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
    });
}

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

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