Commit c95b7bf57e14e5b06bd885ebeb9aa3c67f2f81b4
1 parent
05158bd372
Exists in
master
beta
Showing 5 changed files with 153 additions and 226 deletions Inline Diff
httppulsakita.js
File was created | 1 | var url = require('url'); | |
2 | var math = require('mathjs'); | ||
3 | var request = require('request'); | ||
4 | var xml = require("xml2js").parseString; | ||
5 | |||
6 | var config; | ||
7 | var callbackReport; | ||
8 | |||
9 | var max_retry = 3; | ||
10 | var sleep_before_retry = 3000; | ||
11 | |||
12 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; | ||
13 | |||
14 | function topupRequest(task, retry) { | ||
15 | if (config.globals.requests_count == undefined) { | ||
16 | config.globals.requests_count = 1; | ||
17 | } else { | ||
18 | config.globals.requests_count++; | ||
19 | } | ||
20 | |||
21 | if (config.globals.active_requests_count == undefined) { | ||
22 | config.globals.active_requests_count = 1; | ||
23 | } else { | ||
24 | config.globals.active_requests_count++; | ||
25 | } | ||
26 | |||
27 | if (config.globals.max_active_requests_count == undefined) { | ||
28 | config.globals.max_active_requests_count = config.globals.active_requests_count; | ||
29 | } else { | ||
30 | config.globals.max_active_requests_count = math.max(config.globals.max_active_requests_count, config.globals.active_requests_count); | ||
31 | } | ||
32 | |||
33 | |||
34 | if (retry === undefined) { | ||
35 | retry = max_retry; | ||
36 | } | ||
37 | |||
38 | var params = { | ||
39 | userid: config.h2h_out.userid, | ||
40 | pwd: config.h2h_out.password, | ||
41 | memberreff: task['requestId'], | ||
42 | produk: task['remoteProduct'], | ||
43 | tujuan: task['destination'] | ||
44 | }; | ||
45 | console.log('PARAMS:'); | ||
46 | console.log(params); | ||
47 | |||
48 | request.post({url: config.h2h_out.partner, form: params}, function(err, httpResponse, httpResponseBody) { | ||
49 | |||
50 | if (error) { | ||
51 | console.log('HTTP Request Error (' + task['requestId'] + '): '); | ||
52 | console.log(error); | ||
53 | |||
54 | if (retry) { | ||
55 | |||
56 | console.log('Retrying trx hit (' + retry + ')'); | ||
57 | setTimeout(function() { | ||
58 | topupRequest(task, retry - 1); | ||
59 | }, sleep_before_retry); | ||
60 | |||
61 | } else { | ||
62 | callbackReport(task['requestId'], '54', 'Gangguan koneksi ke suplier'); | ||
63 | } | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | console.log('Server Response: '); | ||
68 | console.log(httpResponseBody); | ||
69 | |||
70 | xml(httpResponseBody, function(err, result) { | ||
71 | if (err) { | ||
72 | console.log('Gagal parsing XML respon server'); | ||
73 | topupRequest(task, retry - 1); | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | var response_code = result.respon.rc.replace(/^00/, ''); | ||
78 | var token = result.respon.token; | ||
79 | var data = result.respon.data.replace(/ /g, '-'); | ||
80 | var sn = token + '/' + data; | ||
81 | |||
82 | var message = result.respon.pesan.replace(/\n/g, ' '); | ||
83 | message = 'SN=' + sn + '; ' + message; | ||
84 | |||
85 | callbackReport(task['requestId'], response_code, message); | ||
86 | |||
87 | }); | ||
88 | }); | ||
89 | } | ||
90 | |||
91 | function start(_config, _callbackReport) { | ||
92 | config = _config; | ||
93 | callbackReport = _callbackReport | ||
94 | } | ||
95 | |||
96 | function parseSN(message) { | ||
97 | var sn_regex = new RegExp(config.h2h_out.sn_pattern); | ||
98 | var sn_match = message.match(sn_regex); | ||
99 | |||
100 | //console.log('SN MATCH:'); | ||
101 | //console.log(sn_match); | ||
102 | |||
103 | if (sn_match <= 0) { | ||
104 | console.log('SN Not found: ' + message); | ||
105 | return ''; | ||
106 | } | ||
107 | |||
108 | var sn = sn_match[0]; | ||
109 | var sn_remove_patterns = config.h2h_out.sn_remove_patterns.split(config.h2h_out.sn_remove_patterns_separator); | ||
110 | //console.log('SN REMOVE PATTERNS:'); | ||
111 | //console.log (sn_remove_patterns); | ||
112 | |||
113 | var count = sn_remove_patterns.length; | ||
114 | |||
115 | for(var i = 0; i < count; i++) { | ||
116 | sn = sn.replace(sn_remove_patterns[i], ''); | ||
117 | } | ||
118 | |||
119 | return sn.trim(); | ||
120 | } | ||
121 | |||
122 | function parseResult(message) { | ||
123 | var data; | ||
124 | xml(message, function(err, result) { | ||
125 | data = result; | ||
126 | }); | ||
127 | return data; | ||
128 | } | ||
129 | |||
130 | exports.start = start; | ||
131 | exports.topupRequest = topupRequest; | ||
132 | exports.parseResult = parseResult; | ||
133 |
index.js
1 | var iniparser = require('iniparser'); | 1 | var iniparser = require('iniparser'); |
2 | var config = iniparser.parseSync('./config.ini'); | 2 | var config = iniparser.parseSync('./config.ini'); |
3 | 3 | ||
4 | var aaaHost = config.globals.aaa_host; | 4 | var aaaHost = config.globals.aaa_host; |
5 | 5 | ||
6 | HttpServer = require('./httpserver.js'); | 6 | HttpServer = require('./httpserver.js'); |
7 | var httpServer = HttpServer.start(config); | 7 | var httpServer = HttpServer.start(config); |
8 | 8 | ||
9 | var aaa = require('./aaa.js'); | 9 | var aaa = require('./aaa.js'); |
10 | var xmlout = require('./xmlout.js'); | 10 | var partner = require('./httppulsakita.js'); |
11 | 11 | ||
12 | xmlout.start(config, aaa.callbackReport); | 12 | partner.start(config, aaa.callbackReport); |
13 | aaa.start(config, xmlout); | 13 | aaa.start(config, partner); |
14 | 14 |
package.json
1 | { | 1 | { |
2 | "name": "sate24-to-sate24", | 2 | "name": "sate24-to-sate24", |
3 | "version": "0.0.1", | 3 | "version": "0.0.1", |
4 | "description": "ST24 to ST24 H2H OUT", | 4 | "description": "ST24 to ST24 H2H OUT", |
5 | "main": "index.js", | 5 | "main": "index.js", |
6 | "scripts": { | 6 | "scripts": { |
7 | "test": "mocha" | 7 | "test": "mocha" |
8 | }, | 8 | }, |
9 | "repository": { | 9 | "repository": { |
10 | "type": "git", | 10 | "type": "git", |
11 | "url": "git@gitlab.kodesumber.com:reload97/sate24-to-sate24.git" | 11 | "url": "git@gitlab.kodesumber.com:reload97/sate24-to-sate24.git" |
12 | }, | 12 | }, |
13 | "keywords": [ | 13 | "keywords": [ |
14 | "st24", | 14 | "st24", |
15 | "reload97", | 15 | "reload97", |
16 | "ppob", | 16 | "ppob", |
17 | "h2h", | 17 | "h2h", |
18 | "m2m", | 18 | "m2m", |
19 | "xmlrpc" | 19 | "xmlrpc" |
20 | ], | 20 | ], |
21 | "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", | 21 | "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", |
22 | "license": "BSD", | 22 | "license": "BSD", |
23 | "dependencies": { | 23 | "dependencies": { |
24 | "mocha": "~2.2.5", | 24 | "mocha": "~2.2.5", |
25 | "request": "~2.57.0", | 25 | "request": "~2.57.0", |
26 | "strftime": "~0.9.2", | 26 | "strftime": "~0.9.2", |
27 | "iniparser": "~1.0.5", | 27 | "iniparser": "~1.0.5", |
28 | "mathjs": "~1.7.0", | 28 | "mathjs": "~1.7.0", |
29 | "xmlrpc": "~1.3.1" | 29 | "xmlrpc": "~1.3.1", |
30 | "xml2js": "~0.4.9" | ||
30 | } | 31 | } |
31 | } | 32 | } |
32 | 33 |
test.js
1 | var assert = require("assert"); | 1 | var assert = require("assert"); |
2 | 2 | ||
3 | 3 | ||
4 | describe('aaa', function() { | 4 | describe('aaa', function() { |
5 | var aaa = require('./aaa'); | 5 | var aaa = require('./aaa'); |
6 | 6 | ||
7 | describe("#unaliasResponseCode()", function() { | 7 | describe("#unaliasResponseCode()", function() { |
8 | it('should return 68', function() { | 8 | it('should return 68', function() { |
9 | assert.equal('68', aaa.unaliasResponseCode('01', '01:68')); | 9 | assert.equal('68', aaa.unaliasResponseCode('01', '01:68')); |
10 | }); | 10 | }); |
11 | 11 | ||
12 | it('should return 68', function() { | 12 | it('should return 68', function() { |
13 | assert.equal('68', aaa.unaliasResponseCode('68', '01:68')); | 13 | assert.equal('68', aaa.unaliasResponseCode('68', '01:68')); |
14 | }); | 14 | }); |
15 | 15 | ||
16 | it('should return 00', function() { | 16 | it('should return 00', function() { |
17 | assert.equal('00', aaa.unaliasResponseCode('00', '01:68')); | 17 | assert.equal('00', aaa.unaliasResponseCode('00', '01:68')); |
18 | }); | 18 | }); |
19 | 19 | ||
20 | it('should return 40', function() { | 20 | it('should return 40', function() { |
21 | assert.equal('40', aaa.unaliasResponseCode('40', '')); | 21 | assert.equal('40', aaa.unaliasResponseCode('40', '')); |
22 | }); | 22 | }); |
23 | 23 | ||
24 | it('should return 40', function() { | 24 | it('should return 40', function() { |
25 | assert.equal('40', aaa.unaliasResponseCode('40', '')); | 25 | assert.equal('40', aaa.unaliasResponseCode('40', '')); |
26 | }); | 26 | }); |
27 | 27 | ||
28 | it('should return 40', function() { | 28 | it('should return 40', function() { |
29 | assert.equal('40', aaa.unaliasResponseCode('40')); | 29 | assert.equal('40', aaa.unaliasResponseCode('40')); |
30 | }); | 30 | }); |
31 | 31 | ||
32 | }); | 32 | }); |
33 | }); | 33 | }); |
34 | |||
35 | describe('aaa', function() { | ||
36 | var partner = require('./httppulsakita'); | ||
37 | |||
38 | describe("#parseResult()", function() { | ||
39 | message = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><respon><tanggal>2015/6/16 15:43:35</tanggal><idagen>P0039</idagen><refid>AEE15B32987941D89FFF4BC7EF676C13</refid><produk>PLN20</produk><tujuan>14204279369</tujuan><rc>0000</rc><data> </data><token> </token><pesan>#14836 PLN20 ke:14204279369 SUKSES. SN:3520-2887-6627-6699-4826/TestDummyPanjang6955555/P1/7000VA/32,4. \ | ||
40 | Sisa saldo Rp. 5,000,000 - Rp. 18,700 = Rp. 4,981,300</pesan></respon>'; | ||
41 | |||
42 | data = partner.parseResult(message); | ||
43 | console.log(data); | ||
44 | |||
45 | it('should return 2015/6/16 15:43:35', function() { | ||
46 | assert.equal('2015/6/16 15:43:35', data.respon.tanggal); | ||
47 | }); | ||
48 | }); | ||
49 | }); | ||
34 | 50 |
xmlout.js
1 | var xmlrpc = require('xmlrpc'); | File was deleted | |
2 | var url = require('url'); | ||
3 | var math = require('mathjs'); | ||
4 | |||
5 | var config; | ||
6 | var callbackReport; | ||
7 | |||
8 | var max_retry = 2; | ||
9 | var sleep_before_retry = 2000; | ||
10 | |||
11 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; | ||
12 | |||
13 | function topupRequest(task, retry) { | ||
14 | if (config.globals.requests_count == undefined) { | ||
15 | config.globals.requests_count = 1; | ||
16 | } else { | ||
17 | config.globals.requests_count++; | ||
18 | } | ||
19 | |||
20 | if (config.globals.active_requests_count == undefined) { | ||
21 | config.globals.active_requests_count = 1; | ||
22 | } else { | ||
23 | config.globals.active_requests_count++; | ||
24 | } | ||
25 | |||
26 | if (config.globals.max_active_requests_count == undefined) { | ||
27 | config.globals.max_active_requests_count = config.globals.active_requests_count; | ||
28 | } else { | ||
29 | config.globals.max_active_requests_count = math.max(config.globals.max_active_requests_count, config.globals.active_requests_count); | ||
30 | } | ||
31 | |||
32 | |||
33 | if (retry === undefined) { | ||
34 | retry = max_retry; | ||
35 | } | ||
36 | |||
37 | var partnerUrl = url.parse(config.h2h_out.partner); | ||
38 | var clientOptions = { | ||
39 | host: partnerUrl.hostname | ||
40 | , port: partnerUrl.port | ||
41 | , path: partnerUrl.pathname | ||
42 | }; | ||
43 | console.log('XMLRPC client options:'); | ||
44 | console.log(clientOptions); | ||
45 | |||
46 | var client; | ||
47 | if (partnerUrl.protocol == 'https:') { | ||
48 | console.log('Use SSL'); | ||
49 | client = xmlrpc.createSecureClient(clientOptions); | ||
50 | } else { | ||
51 | console.log('Not using SSL'); | ||
52 | client = xmlrpc.createClient(clientOptions); | ||
53 | } | ||
54 | |||
55 | var methodName = 'topUpRequest'; | ||
56 | console.log('methodName: ' + methodName); | ||
57 | |||
58 | var params = { | ||
59 | MSISDN: config.h2h_out.userid, | ||
60 | REQUESTID: task['requestId'], | ||
61 | PIN: config.h2h_out.password, | ||
62 | NOHP: task['destination'], | ||
63 | NOM: task['remoteProduct'] | ||
64 | }; | ||
65 | console.log('PARAMS:'); | ||
66 | console.log(params); | ||
67 | |||
68 | |||
69 | client.methodCall(methodName, [ params ], function (error, value) { | ||
70 | |||
71 | if (config.globals.active_requests_count == undefined) { | ||
72 | config.globals.active_requests_count = 0; | ||
73 | } else { | ||
74 | config.globals.active_requests_count--; | ||
75 | } | ||
76 | |||
77 | // Results of the method response | ||
78 | if (error) { | ||
79 | console.log('XMLRPC Client Error (' + task['requestId'] + '): '); | ||
80 | console.log(error); | ||
81 | |||
82 | if (retry) { | ||
83 | |||
84 | console.log('Retrying topUpRequest (' + retry + ')'); | ||
85 | setTimeout(function() { | ||
86 | topupRequest(task, retry - 1); | ||
87 | }, sleep_before_retry); | ||
88 | |||
89 | } else { | ||
90 | callbackReport(task['requestId'], '40', 'Gangguan koneksi ke suplier'); | ||
91 | } | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | console.log('Method response for \'' + methodName + '\': ') | ||
96 | console.log(value); | ||
97 | |||
98 | if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') { | ||
99 | value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE']; | ||
100 | //console.log('Message with SN: ' + value['MESSAGE']); | ||
101 | } | ||
102 | |||
103 | callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']); | ||
104 | }); | ||
105 | } | ||
106 | |||
107 | function createServer() { | ||
108 | |||
109 | console.log('Creating XML-RPC server on port ' + config.h2h_out.listen_port); | ||
110 | var serverOptions = { | ||
111 | port: config.h2h_out.listen_port | ||
112 | }; | ||
113 | |||
114 | var server = xmlrpc.createServer(serverOptions); | ||
115 | |||
116 | server.on('NotFound', function (method, params) { | ||
117 | console.log(method + ' is not found on our XML-RPC server'); | ||
118 | console.log('params:'); | ||
119 | console.log(params); | ||
120 | }); | ||
121 | |||
122 | server.on('topUpReport', function (err, params, callback) { | ||
123 | console.log('RECEIVE topUpReport, params:'); | ||
124 | console.log(params); | ||
125 | |||
126 | var paramscount = params.length; | ||
127 | for (var i = 0; i < paramscount; i++) { | ||
128 | var value = params[i]; | ||
129 | |||
130 | if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') { | ||
131 | value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE']; | ||
132 | //console.log('Message with SN: ' + value['MESSAGE']); | ||
133 | } | ||
134 | |||
135 | callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']); | ||
136 | } | ||
137 | |||
138 | callback(null, 'ACK REPORT OK'); | ||
139 | }) | ||
140 | |||
141 | } | ||
142 | |||
143 | function checkStatus(task) { | ||
144 | var partnerUrl = url.parse(config.h2h_out.partner); | ||
145 | var clientOptions = { | ||
146 | host: partnerUrl.hostname | ||
147 | , port: partnerUrl.port | ||
148 | , path: partnerUrl.pathname | ||
149 | }; | ||
150 | console.log('XMLRPC client options:'); | ||
151 | console.log(clientOptions); | ||
152 | |||
153 | var client; | ||
154 | if (partnerUrl.protocol == 'https:') { | ||
155 | console.log('Use SSL'); | ||
156 | client = xmlrpc.createSecureClient(clientOptions); | ||
157 | } else { | ||
158 | console.log('Not using SSL'); | ||
159 | client = xmlrpc.createClient(clientOptions); | ||
160 | } | ||
161 | |||
162 | var methodName = 'topUpInquiry'; | ||
163 | console.log('methodName: ' + methodName); | ||
164 | |||
165 | var params = { | ||
166 | MSISDN: config.h2h_out.userid, | ||
167 | REQUESTID: task['requestId'], | ||
168 | PIN: config.h2h_out.password, | ||
169 | NOHP: task['destination'] | ||
170 | }; | ||
171 | console.log('PARAMS:'); | ||
172 | console.log(params); | ||
173 | |||
174 | client.methodCall(methodName, [ params ], function (error, value) { | ||
175 | // Results of the method response | ||
176 | if (error) { | ||
177 | console.log('Error: '); | ||
178 | console.log(error); | ||
179 | return; | ||
180 | } | ||
181 | console.log('Method response for \'' + methodName + '\': ') | ||
182 | console.log(value); | ||
183 | |||
184 | callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']); | ||
185 | }); | ||
186 | } | ||
187 | |||
188 | function start(_config, _callbackReport) { | ||
189 | config = _config; | ||
190 | callbackReport = _callbackReport | ||
191 | |||
192 | createServer(); | ||
193 | } | ||
194 | |||
195 | function parseSN(message) { | ||
196 | var sn_regex = new RegExp(config.h2h_out.sn_pattern); | ||
197 | var sn_match = message.match(sn_regex); | ||
198 | |||
199 | //console.log('SN MATCH:'); | ||
200 | //console.log(sn_match); | ||
201 | |||
202 | if (sn_match <= 0) { | ||
203 | console.log('SN Not found: ' + message); | ||
204 | return ''; | ||
205 | } | ||
206 | |||
207 | var sn = sn_match[0]; | ||
208 | var sn_remove_patterns = config.h2h_out.sn_remove_patterns.split(config.h2h_out.sn_remove_patterns_separator); | ||
209 | //console.log('SN REMOVE PATTERNS:'); | ||
210 | //console.log (sn_remove_patterns); | ||
211 | |||
212 | var count = sn_remove_patterns.length; | ||
213 | |||
214 | for(var i = 0; i < count; i++) { | ||
215 | sn = sn.replace(sn_remove_patterns[i], ''); | ||
216 | } | ||
217 | |||
218 | return sn.trim(); | ||
219 | } | ||
220 | |||
221 | exports.start = start; | ||
222 | exports.topupRequest = topupRequest; | ||
223 | 1 | var xmlrpc = require('xmlrpc'); |