partner-otomax.js 4.81 KB
"use strict";

var request = require('request');
var crypto = require('crypto');
var url = require('url');
var http = require('http');

var resendDelay = require('sate24/resend-delay');
var taskHistory = require('sate24/task-history');
var antiSameDayDupe = require('sate24/anti-same-day-dupe');

var config;
var aaa;
var logger;


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

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

    taskHistory.init(options);
    antiSameDayDupe.init(options);

    createReverseHttpServer();
}

function callbackReport(requestId, rc, message) {
    if (responseCode != '68' || dontResendDelay) {
        resendDelay.cancel(requestId);
    } else {
        taskHistory.get(requestId, function(err, archivedTask) {
            if (archivedTask) {
                logger.verbose('DEBUG', {archivedTask: archivedTask});
                resendDelay.register(archivedTask);
            }
        });
    }

    options.aaa.callbackReportWithPushToMongoDb(requestId, rc, message);
}

function topupRequest(task) {
    if (!aaa.isTodayTrx(task)) {
        logger.warn('Maaf, transaksi beda hari tidak dapat dilakukan');
        callbackReport(task.requestId, '68', 'Maaf, transaksi beda hari tidak dapat dilakukan');
        resendDelay.cancel(task);
        return;
    }

    aaa.insertTaskToMongoDb(task);
    antiSameDayDupe.check(task, _topupRequest, onSameDayDupe, _topupRequest);
}

function _topupRequest(task) {
    taskHistory.put(task, function() {
        requestToPartner(task);;
    });
}

function requestToPartner(task) {
    let requestOptions = createRequestOptions(task);

    logger.info('Requesting to partner', {task: task, request_options: requestOptions});

    request(requestOptions, function(error, response, body) {
        if (error) {
            logger.warn('Error requesting to partner', {task: task, error: error});
            callbackReport(task.requestId, '68', 'Error requesting to partner. ' + error);
            return;
        }

        if (response.statusCode != 200) {
            logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode});
            callbackReport(task.requestId, '40', 'HTTP status code ' + response.statusCode);
            return;
        }

        logger.verbose('Got response from partner', {task: task, body: body});

        parseMessage(task, body);
    });
}

function parseMessage(task, message) {
    let rc = '68';

    if (message.indexOf('SUKSES') >= 0) {
        rc = '00';
    }
    else if (message.indexOf('GAGAL') >= 0) {
        rc = '40';
    }

    callbackReport(task.requestId, rc, message);
}

function generateSign(userid, remoteProduct, destination, requestId, pin, password) {
    let plain = ["OtomaX", userid, remoteProduct, destination, requestId, pin, password].join("|");
    //let sha1 = crypto.createHash('sha1').update(plain).digest().toString('hex');
    //let buffer = new Buffer(sha1);
    let buffer = crypto.createHash('sha1').update(plain).digest();

    return buffer.toString('base64').replace(/\//g, '_');
}

function createRequestOptions(task) {
    return {
        url: config.h2h_out.partner,
        qs: {
            memberID: config.h2h_out.userid,
            product: task.remoteProduct,
            dest: task.destination,
            refID: task.requestId,
            sign: generateSign(
                config.h2h_out.userid,
                task.remoteProduct,
                task.destination,
                task.requestId,
                config.h2h_out.pin,
                config.h2h_out.password
            )
        }
    };
}

function onSameDayDupe(task) {
    callbackReport(task.requestId, '55', 'Transaksi duplikat dalam satu hari yang sama');
}

function createReverseHttpServer() {
    var httpServer = http.createServer(function(request, response) {
        let qs = url.parse(request.url, true).query;
        logger.verbose('Hit on Reverse HTTP server', {url: request.url, qs: qs});
    });

    httpServer.listen(config.h2h_out.listen_port, function() {
        logger.info('Reverse Report HTTP Server listen on %d', config.h2h_out.listen_port);
    });
}

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