partner-kospinjasa.js 7.98 KB
var winston = require('winston');
var soap = require('soap');
var crypto = require('crypto');
var strftime = require('strftime');
var fs = require("fs");
var whiskers = require("whiskers");
var http = require("http");
var url = require("url");

process.chdir(__dirname);
var soapTemplate = fs.readFileSync("message.xml");

var max_retry = 10;
var sleep_before_retry = 5000;

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

function topupRequest(task, retry) {
    if (retry === undefined) {
        retry = max_retry;
    }

    var remoteProduct = task.remoteProduct.split(',');
    var params = {
        userName: config.h2h_out.userid,
        productCode: remoteProduct[0] ,
        terminal: 'H2HIPN10',
        transactionType: '50',
        billNumber: createBillNumber(task.destination),
        amount: remoteProduct[1],
        bit61: createBillNumber(task.destination),
        reff: task.requestId,
        timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date())
    }

    var signature = createSignature(params, config.h2h_out.password);
    params.signature = signature;

    //topupRequestSoapDIY(task, params, retry);
    topupRequestSoap(task, params, retry);
}

function topupRequestSoap(task, params, retry) {

    soap.createClient(config.h2h_out.partner, function(err, soapClient) {

        var _params = {
            userName: params.userName,
            signature: params.signature,
            productCode: params.productCode,
            terminal: params.terminal,
            transactionType: params.transactionType,
            billNumber: params.billNumber,
            amount: params.amount,
            bit61: params.bit61,
            reff: params.reff,
            timeStamp: params.timeStamp
        }

        logger.info('Requesting to service', {url: config.h2h_out.partner, params: _params});

        soapClient.apih2h.apih2hPort.billpayment({ inputCheck: _params }, function(err, result) {
            logger.verbose(
                'Got response',
                {
                    lastEndpoint: soapClient.lastEndpoint,
                    lastRequest: soapClient.lastRequest,
                    lastMessage: soapClient.lastMessage,
                    lastResponse: soapClient.lastResponse,
                }
            );

            if (err) {
                logger.warn('Error requesting service', {err: err});
                callbackReport(task.requestId, '68', 'something wrong');
                return;
            }

            topupResponseHandler(task, result);
        });
    });
}

function topupResponseHandler(task, response) {
    var st24rc = '68';
    var st24message = response.outputParameter.resultDesc.$value;

    if ( response.outputParameter.resultCode.$value == '001' ) {
        // product disabled
        st24rc = '13';
    }
    else if ( response.outputParameter.resultCode.$value == '002' ) {
        // prodcode disable
        st24rc = '13';
    }
    else if ( response.outputParameter.resultCode.$value == '003' ) {
        // duplicate reff
        st24rc = '55';
    }
    else if ( response.outputParameter.resultCode.$value == '004' ) {
        // not enough balance
        st24rc = '40';
    }
    else if ( response.outputParameter.resultCode.$value == '005' ) {
        // username blocked
        st24rc = '40';
    }
    else if ( response.outputParameter.resultCode.$value == '006' ) {
        // not exists username
        st24rc = '40';
    }
    else if ( response.outputParameter.resultCode.$value == '011' ) {
        // invalid request
        st24rc = '40'
    }
    else if ( response.outputParameter.resultCode.$value == '012' ) {
        // no route to host
        st24rc = '40'
    }
    else if ( response.outputParameter.resultCode.$value == '013' ) {
        // invalid signature
        st24rc = '40'
    }
    else if ( response.outputParameter.bit39.$value == '06' ) {
        st24rc = '40';
        st24message = 'Error Transaksi ditolak karena terjadi error di H2H dengan response code diluar daftar ini. Silahkan hubungi H2H';
    }
    else if ( response.outputParameter.bit39.$value == '12' ) {
        st24rc = '40';
        st24message = 'Invalid Transaction Transaksi ditolak karena flow transaksi tidak valid';
    }
    else if ( response.outputParameter.bit39.$value == '13' ) {
        st24rc = '13';
        st24message = 'Invalid voucher nominal';
    }
    else if ( response.outputParameter.bit39.$value == '14' ) {
        st24rc = '14';
        st24message = 'MSISDN tidak ditemukan';
    }
    else if ( response.outputParameter.bit39.$value == '30' ) {
        st24rc = '40';
        st24message = 'Format Error';
    }
    else if ( response.outputParameter.bit39.$value == '31' ) {
        st24rc = '40';
        st24message = 'Kode bank tidak terdaftar';
    }
    else if ( response.outputParameter.bit39.$value == '63' ) {
        st24rc = '40';
        st24message = 'Reversal denied';
    }
    else if ( response.outputParameter.bit39.$value == '68' ) {
        st24rc = '68';
        st24message = 'Transaksi sedang dalam proses';
    }
    else if ( response.outputParameter.bit39.$value == '69' ) {
        st24rc = '68';
        st24message = 'Respon Ok lebih dari 24 detik';
    }
    else if ( response.outputParameter.bit39.$value == '70' ) {
        st24rc = '13';
        st24message = 'Voucher out of stock';
    }
    else if ( response.outputParameter.bit39.$value == '79' ) {
        st24rc = '14';
        st24message = 'Phone number is blocked by Telkomsel';
    }
    else if ( response.outputParameter.bit39.$value == '81' ) {
        st24rc = '14';
        st24message = 'Phone number is expired';
    }
    else if ( response.outputParameter.bit39.$value == '89' ) {
        st24rc = '40';
        st24message = 'Link to billing provider is down';
    }
    else if ( response.outputParameter.bit39.$value == '91' ) {
        st24rc = '40';
        st24message = 'Database problem';
    }
    else if ( response.outputParameter.bit39.$value == '92' ) {
        st24rc = '40';
        st24message = 'Unable to route transaction';
    }
    else if ( response.outputParameter.bit39.$value == '94' ) {
        st24rc = '40';
        st24message = 'Duplicate reversal request';
    }

    var message =
        response.outputParameter.resultCode.$value
        + " " + response.outputParameter.resultDesc.$value
        + "; " + response.outputParameter.bit39.$value
        ;

    if (response.outputParameter.resultDesc.$value != st24message) {
        var message = message + " " + st24message;
    }

    logger.info('Got result: ' + message, {result: result});
    callbackReport(task.requestId, st24rc, st24message);
}

function topupRequestRetry(task) {
    task.retry--;

    if (task.retry > 0) {
        logger.info('Retrying in ' +  sleepBeforeRetry + 's');
        setTimeout(topupRequest, sleepBeforeRetry * 1000, task, task.retry);
    }
    else {
        logger.warn('Maximum retry for pending status exceeded', {task: task});
    }
}


function createSignature(params, password) {
    var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex');
    var plain =
        params.userName
        + passwordHash
        + params.productCode
        + params.terminal
        + params.transactionType
        + params.billNumber
        + params.amount
        + params.reff
        + params.timeStamp;

    return crypto.createHash('sha1').update(plain).digest().toString('hex');
}

function createBillNumber(destination) {
    return ("0000000000000" + destination).slice(-13);
}

exports.start = start;
exports.topupRequest = topupRequest;
exports.createSignature = createSignature;
exports.createBillNumber = createBillNumber;