Commit 60fa6ddb465ae83e3d3c1895b449f0dcb392ac66

Authored by Adhidarma Hadiwinoto
1 parent 2fbb21dc08
Exists in master

coba ditest

Showing 5 changed files with 273 additions and 0 deletions Inline Diff

File was created 1 node_modules/
2 config.ini
3 config.ini.backup*
4 run.sh
5 admin-cli.js
6 logs/
7
File was created 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);
30
File was created 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 }
33
File was created 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;
179
File was created 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 })
29