Commit 60fa6ddb465ae83e3d3c1895b449f0dcb392ac66

Authored by Adhidarma Hadiwinoto
1 parent 2fbb21dc08
Exists in master

coba ditest

Showing 5 changed files with 273 additions and 0 deletions Side-by-side Diff

... ... @@ -0,0 +1,6 @@
  1 +node_modules/
  2 +config.ini
  3 +config.ini.backup*
  4 +run.sh
  5 +admin-cli.js
  6 +logs/
... ... @@ -0,0 +1,29 @@
  1 +var fs = require('fs');
  2 +var ini = require('ini');
  3 +var expresso = require('sate24-expresso');
  4 +var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8'));
  5 +
  6 +process.chdir(__dirname);
  7 +
  8 +var logDirectory = __dirname + '/logs';
  9 +fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);
  10 +
  11 +var logger = require('sate24/logger.js').start();
  12 +var HttpServer = require('sate24/httpserver.js');
  13 +var aaa = require('sate24/aaa.js');
  14 +var partner = require('./partner-fm.js');
  15 +
  16 +var matrix = aaa.prepareMatrix();
  17 +
  18 +var options = {
  19 + 'aaa': aaa,
  20 + 'logger': logger,
  21 + 'config': config,
  22 + 'matrix': matrix,
  23 +}
  24 +
  25 +var httpServer = HttpServer.start(config, options);
  26 +
  27 +partner.start(config, aaa.callbackReport, options);
  28 +aaa.start(config, partner, options);
  29 +expresso.start(options);
... ... @@ -0,0 +1,32 @@
  1 +{
  2 + "name": "sate24-to-fm-bp",
  3 + "version": "1.0.0",
  4 + "description": "ST24 H2H-OUT to FM based on belanjapulsa.com",
  5 + "main": "index.js",
  6 + "scripts": {
  7 + "test": "mocha"
  8 + },
  9 + "repository": {
  10 + "type": "git",
  11 + "url": "git@gitlab.kodesumber.com:reload97/sate24-to-fm-bp.git"
  12 + },
  13 + "keywords": [
  14 + "st24",
  15 + "reload97",
  16 + "r97",
  17 + "ppob",
  18 + "fm",
  19 + "flashmachine"
  20 + ],
  21 + "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
  22 + "license": "ISC",
  23 + "dependencies": {
  24 + "request": "^2.74.0",
  25 + "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git",
  26 + "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git",
  27 + "xml2js": "^0.4.17"
  28 + },
  29 + "devDependencies": {
  30 + "should": "^11.1.0"
  31 + }
  32 +}
... ... @@ -0,0 +1,178 @@
  1 +var xml2js = require('xml2js');
  2 +
  3 +var aaa;
  4 +var _callbackReport;
  5 +var config;
  6 +var logger;
  7 +
  8 +var xmlBuilder = new xml2js.Builder();
  9 +
  10 +function start(options) {
  11 + if (!options) {
  12 + console.log('Undefined options, terminating....');
  13 + process.exit(1);
  14 + }
  15 +
  16 + if (options.config) {
  17 + config = options.config;
  18 + } else {
  19 + console.log('Undefined options.config, terminating....')
  20 + process.exit(1);
  21 + }
  22 +
  23 + if (options.aaa) {
  24 + aaa = options.aaa;
  25 + _callbackReport = options.aaa.callbackReportWithPushToMongoDb;
  26 + } else {
  27 + console.log('Undefined options.aaa, terminating....')
  28 + process.exit(1);
  29 + }
  30 +
  31 + if (options && options.logger) {
  32 + logger = options.logger;
  33 + } else {
  34 + console.log('Undefined options.logger, terminating....')
  35 + process.exit(1);
  36 + }
  37 +
  38 + createServer();
  39 +
  40 + /*
  41 + resendDelay.init({
  42 + config: config,
  43 + topupRequest: topupRequest,
  44 + logger: logger
  45 + });
  46 + */
  47 +}
  48 +
  49 +function topupRequest(task) {
  50 + aaa.insertTaskToMongoDb(task);
  51 +
  52 + var payload = composeTopupStatusMessage(
  53 + config.h2h_out.pin,
  54 + task.remoteProduct,
  55 + task.destination,
  56 + task.requestId
  57 + );
  58 +
  59 + var reqOpts = {
  60 + url: config.h2h_out.partner_url,
  61 + method: "POST",
  62 + headers: {
  63 + 'Content-Type': 'text/xml',
  64 + 'Content-Length': Buffer.byteLength(payload)
  65 + }
  66 + }
  67 +
  68 + logger.verbose('Requesting to partner', {reqOpts: reqOpts, payload: payload});
  69 + var buffer = "";
  70 + var req = http.request(reqOpts, function( res ) {
  71 +
  72 + logger.info('Status code: ' + res.statusCode );
  73 + var buffer = "";
  74 + res.on( "data", function( data ) { buffer = buffer + data; } );
  75 + res.on( "end", function( data ) {
  76 + logger.verbose('Got a direct response from partner', {response: buffer, task: task});
  77 + topupResponseHandler(buffer, task.requestId);
  78 + });
  79 + });
  80 +}
  81 +
  82 +function topupResponseHandler(xmlResponse, _requestId, cb) {
  83 + var xmlParser = xml2js.parseString;
  84 + xmlParser(xmlResponse, function(err, data) {
  85 + var msg;
  86 + var requestId;
  87 + var rc = '68';
  88 +
  89 + if (_requestId) {
  90 + requestId = _requestId;
  91 + }
  92 +
  93 + if (err) {
  94 + msg = 'Error parsing xml response: ' + err;
  95 +
  96 + if (logger) {
  97 + logger.warn(msg, {err: err, response: xmlResponse, task: task});
  98 + } else {
  99 + console.log(msg);
  100 + }
  101 + } else {
  102 +
  103 + try {
  104 + msg = data.fm.message
  105 + }
  106 + catch(e) {
  107 + msg = 'Unknown message'
  108 + }
  109 +
  110 + if (data.fm.status == '0') {
  111 +
  112 + rc = '00';
  113 + msg = modifyMessageWithSn(msg);
  114 +
  115 + } else if (data.fm.status == '1') {
  116 + rc = '68';
  117 + } else if (data.fm.status == '2') {
  118 + rc = '40';
  119 + } else if (data.fm.status == '3') {
  120 + rc = '40';
  121 + } else {
  122 + rc = '68';
  123 + }
  124 +
  125 + if (data.fm.refTrxid) {
  126 + requestId = data.fm.refTrxid;
  127 + }
  128 +
  129 + }
  130 +
  131 + cb(requestId, rc, msg, xmlResponse)
  132 + });
  133 +}
  134 +
  135 +function callbackReport(requestId, responseCode, msg, rawResponse) {
  136 + if (requestId) {
  137 + _callbackReport(requestId, responseCode, msg, null, rawResponse);
  138 + } else {
  139 + logger.warn('Undefined requestId, not sending callbackReport', {rc: responseCode, msg: msg, rawResponse: rawResponse});
  140 + }
  141 +
  142 +}
  143 +
  144 +function getSnFromMessage(msg) {
  145 + try {
  146 + var matches = msg.match(/SN:(\w+)/);
  147 + return matches[1];
  148 + }
  149 + catch(e) {
  150 + return;
  151 + }
  152 +}
  153 +
  154 +function modifyMessageWithSn(msg) {
  155 + var sn = getSnFromMessage(msg);
  156 + if (sn) {
  157 + msg = 'SN=' + sn + '; ' + msg;
  158 + }
  159 + return msg;
  160 +}
  161 +
  162 +function composeTopupStatusMessage(pin, product, destination, requestId) {
  163 + var data = {fm: {
  164 + command: 'TOPUP',
  165 + pin: pin,
  166 + product: product,
  167 + msisdn: destination,
  168 + refTrxid: requestId
  169 + }}
  170 +
  171 + return xmlBuilder.buildObject(data);
  172 +}
  173 +
  174 +exports.start = start;
  175 +exports.topupRequest = topupRequest;
  176 +exports.composeTopupStatusMessage = composeTopupStatusMessage;
  177 +exports.getSnFromMessage = getSnFromMessage;
  178 +exports.modifyMessageWithSn = modifyMessageWithSn;
... ... @@ -0,0 +1,28 @@
  1 +var should = require('should');
  2 +var crypto = require('crypto');
  3 +
  4 +describe('#partner', function () {
  5 + var partner = require('./partner-fm')
  6 +
  7 + describe('#composeTopupStatusMessage', function() {
  8 + it('should return correct xml message', function() {
  9 + var msg = partner.composeTopupStatusMessage('1234', 'S10', '08120812', '2345');
  10 + crypto.createHash('sha256').update(msg, 'utf8').digest().toString('hex').should.equal('1b926cb9101d9b172ae12206d0c10d4800b553f3d9f2e320fe526c7effb11985');
  11 + })
  12 + });
  13 +
  14 + describe('#getSnFromMessage', function() {
  15 + it('should return correct sn', function() {
  16 + partner.getSnFromMessage('S10.081300000000 berhasil, SN:123456789').should.equal('123456789');
  17 + });
  18 + })
  19 +
  20 + describe('#modifyMessageWithSn', function() {
  21 + it('should return correct sn', function() {
  22 + partner.modifyMessageWithSn('S10.081300000000 berhasil.').should.equal('S10.081300000000 berhasil.');
  23 + partner.modifyMessageWithSn('S10.081300000000 berhasil, SN:').should.equal('S10.081300000000 berhasil, SN:');
  24 + partner.modifyMessageWithSn('S10.081300000000 berhasil, SN:123456789').should.equal('SN=123456789; S10.081300000000 berhasil, SN:123456789');
  25 + partner.modifyMessageWithSn('S10.081300000000 berhasil, SN:123456789. Berita tambahan').should.equal('SN=123456789; S10.081300000000 berhasil, SN:123456789. Berita tambahan');
  26 + });
  27 + });
  28 +})