Commit 4bab25b5940df293141215aa38f3bedf994daf74

Authored by Adhidarma Hadiwinoto
1 parent 98bdf8fbf9
Exists in master

GAGAL. Nomor telpon tidak valid = rc14

Showing 1 changed file with 2 additions and 0 deletions Inline Diff

1 var http = require('http'); 1 var http = require('http');
2 var url = require('url'); 2 var url = require('url');
3 var math = require('mathjs'); 3 var math = require('mathjs');
4 var xml = require('xml'); 4 var xml = require('xml');
5 var xml2js = require('xml2js').parseString; 5 var xml2js = require('xml2js').parseString;
6 var strftime = require('strftime'); 6 var strftime = require('strftime');
7 var xor = require('base64-xor'); 7 var xor = require('base64-xor');
8 var request = require('request'); 8 var request = require('request');
9 var winston = require('winston'); 9 var winston = require('winston');
10 10
11 var config; 11 var config;
12 var callbackReport; 12 var callbackReport;
13 var aaa; 13 var aaa;
14 var logger; 14 var logger;
15 15
16 var max_retry = 2; 16 var max_retry = 2;
17 var sleep_before_retry = 2000; 17 var sleep_before_retry = 2000;
18 18
19 var trx_balances = {}; 19 var trx_balances = {};
20 var trx_prices = {}; 20 var trx_prices = {};
21 21
22 function calculateSignature(password, msisdn, timestamp) { 22 function calculateSignature(password, msisdn, timestamp) {
23 var a = timestamp + msisdn.substr(msisdn.length - 4); 23 var a = timestamp + msisdn.substr(msisdn.length - 4);
24 var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password; 24 var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password;
25 25
26 return xor.encode(a,b); 26 return xor.encode(a,b);
27 } 27 }
28 28
29 function createPayload(task) { 29 function createPayload(task) {
30 var timestamp = strftime('%H%M%S'); 30 var timestamp = strftime('%H%M%S');
31 31
32 var payload = { 32 var payload = {
33 pulsamatic: [ 33 pulsamatic: [
34 {command: 'TOPUP'}, 34 {command: 'TOPUP'},
35 {vtype: task['remoteProduct']}, 35 {vtype: task['remoteProduct']},
36 {userid: config.h2h_out.userid}, 36 {userid: config.h2h_out.userid},
37 {time: timestamp}, 37 {time: timestamp},
38 {msisdn: task['destination']}, 38 {msisdn: task['destination']},
39 {trxid: task['requestId']}, 39 {trxid: task['requestId']},
40 {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)} 40 {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)}
41 ] 41 ]
42 }; 42 };
43 43
44 //console.log(payload); 44 //console.log(payload);
45 return "<?xml version=\"1.0\" ?>\n" + xml(payload); 45 return "<?xml version=\"1.0\" ?>\n" + xml(payload);
46 } 46 }
47 47
48 function topupRequest(task, retry) { 48 function topupRequest(task, retry) {
49 49
50 aaa.insertTaskToMongoDb(task); 50 aaa.insertTaskToMongoDb(task);
51 51
52 var payload_xml = createPayload(task); 52 var payload_xml = createPayload(task);
53 var partner = url.parse(config.h2h_out.partner); 53 var partner = url.parse(config.h2h_out.partner);
54 54
55 var request_options = { 55 var request_options = {
56 host: partner.hostname, 56 host: partner.hostname,
57 path: partner.path, 57 path: partner.path,
58 port: partner.port, 58 port: partner.port,
59 method: "POST", 59 method: "POST",
60 headers: { 60 headers: {
61 'Content-Type': 'text/xml', 61 'Content-Type': 'text/xml',
62 'Content-Length': Buffer.byteLength(payload_xml) 62 'Content-Length': Buffer.byteLength(payload_xml)
63 } 63 }
64 }; 64 };
65 65
66 var buffer = ""; 66 var buffer = "";
67 67
68 logger.info('Requesting to partner', {request_options: request_options}); 68 logger.info('Requesting to partner', {request_options: request_options});
69 69
70 var req = http.request(request_options, function( res ) { 70 var req = http.request(request_options, function( res ) {
71 71
72 logger.info('Status code: ' + res.statusCode ); 72 logger.info('Status code: ' + res.statusCode );
73 var buffer = ""; 73 var buffer = "";
74 res.on( "data", function( data ) { buffer = buffer + data; } ); 74 res.on( "data", function( data ) { buffer = buffer + data; } );
75 res.on( "end", function( data ) { 75 res.on( "end", function( data ) {
76 directResponseHandler(buffer, task['requestId']); 76 directResponseHandler(buffer, task['requestId']);
77 }); 77 });
78 78
79 }); 79 });
80 80
81 req.on('error', function(e) { 81 req.on('error', function(e) {
82 logger.warn('problem with request: ' + e.message); 82 logger.warn('problem with request: ' + e.message);
83 callbackReport(task['requestId'], '40', e.message); 83 callbackReport(task['requestId'], '40', e.message);
84 }); 84 });
85 85
86 logger.verbose('Sending payload to partner', {payload: payload_xml}); 86 logger.verbose('Sending payload to partner', {payload: payload_xml});
87 req.write( payload_xml ); 87 req.write( payload_xml );
88 req.end(); 88 req.end();
89 } 89 }
90 90
91 function directResponseHandler(body, request_id) { 91 function directResponseHandler(body, request_id) {
92 logger.info('Got direct response'); 92 logger.info('Got direct response');
93 93
94 xml2js(body, function (err, result) { 94 xml2js(body, function (err, result) {
95 if (err) { 95 if (err) {
96 96
97 if (body == 'Error: MAINTENANCE SYSTEM') { 97 if (body == 'Error: MAINTENANCE SYSTEM') {
98 callbackReport(request_id, '91', body); 98 callbackReport(request_id, '91', body);
99 } else { 99 } else {
100 logger.warn('Error parsing xml', {err: err, body: body}); 100 logger.warn('Error parsing xml', {err: err, body: body});
101 callbackReport(request_id, '40', 'Error parsing xml. ' + err); 101 callbackReport(request_id, '40', 'Error parsing xml. ' + err);
102 } 102 }
103 103
104 return; 104 return;
105 } 105 }
106 106
107 logger.info('Direct response parsed', {result: result}); 107 logger.info('Direct response parsed', {result: result});
108 108
109 var response_code = '68'; 109 var response_code = '68';
110 110
111 //var request_id = result.pulsamatic.partner_trxid[0].trim(); 111 //var request_id = result.pulsamatic.partner_trxid[0].trim();
112 var message = getMessageFromXmlResponse(result); 112 var message = getMessageFromXmlResponse(result);
113 if (!message) { 113 if (!message) {
114 message = body; 114 message = body;
115 } 115 }
116 116
117 var status = getStatusFromXmlResponse(result); 117 var status = getStatusFromXmlResponse(result);
118 if (!status) { 118 if (!status) {
119 status = 'UNKNOWN'; 119 status = 'UNKNOWN';
120 } 120 }
121 121
122 if (status === 'failed') { 122 if (status === 'failed') {
123 response_code = '40'; 123 response_code = '40';
124 124
125 var new_response_code = responseCodeFromMessage(message); 125 var new_response_code = responseCodeFromMessage(message);
126 if (new_response_code) { 126 if (new_response_code) {
127 response_code = new_response_code; 127 response_code = new_response_code;
128 } 128 }
129 129
130 } 130 }
131 131
132 callbackReport(request_id, response_code, message); 132 callbackReport(request_id, response_code, message);
133 }); 133 });
134 } 134 }
135 135
136 function getMessageFromXmlResponse(response) { 136 function getMessageFromXmlResponse(response) {
137 var message = null; 137 var message = null;
138 try { 138 try {
139 message = response.pulsamatic.message[0].trim(); 139 message = response.pulsamatic.message[0].trim();
140 } 140 }
141 catch(e) { 141 catch(e) {
142 logger.warn('Undefined message from response pulsamatic', {response: response}); 142 logger.warn('Undefined message from response pulsamatic', {response: response});
143 } 143 }
144 return message; 144 return message;
145 } 145 }
146 146
147 function getStatusFromXmlResponse(response) { 147 function getStatusFromXmlResponse(response) {
148 var status = null; 148 var status = null;
149 try { 149 try {
150 status = response.pulsamatic.result[0].trim(); 150 status = response.pulsamatic.result[0].trim();
151 } 151 }
152 catch(e) { 152 catch(e) {
153 logger.warn('Undefined status from response', {response: response}); 153 logger.warn('Undefined status from response', {response: response});
154 } 154 }
155 return status; 155 return status;
156 } 156 }
157 157
158 158
159 function responseCodeFromMessage(message) { 159 function responseCodeFromMessage(message) {
160 if (message.indexOf('Jenis produk tidak cocok') >= 0) { 160 if (message.indexOf('Jenis produk tidak cocok') >= 0) {
161 return '14'; 161 return '14';
162 } else if (message.indexOf('GAGAL. Nomor telp salah.') >= 0) { 162 } else if (message.indexOf('GAGAL. Nomor telp salah.') >= 0) {
163 return '14'; 163 return '14';
164 } else if (message.indexOf('GAGAL. Nomor telpon tidak valid') >= 0) {
165 return '14';
164 } else if (message.indexOf('GAGAL. MSISDN tidak ditemukan') >= 0) { 166 } else if (message.indexOf('GAGAL. MSISDN tidak ditemukan') >= 0) {
165 return '14'; 167 return '14';
166 } else if (message.indexOf('GAGAL. Nomor MSISDN sudah tidak aktif') >= 0) { 168 } else if (message.indexOf('GAGAL. Nomor MSISDN sudah tidak aktif') >= 0) {
167 return '14'; 169 return '14';
168 } else if (message.indexOf('GAGAL. Jenis produk ini sedang gangguan.') >= 0) { 170 } else if (message.indexOf('GAGAL. Jenis produk ini sedang gangguan.') >= 0) {
169 return '13'; 171 return '13';
170 } 172 }
171 return; 173 return;
172 } 174 }
173 175
174 function createServer() { 176 function createServer() {
175 177
176 var httpServer = http.createServer(function(req, res) { 178 var httpServer = http.createServer(function(req, res) {
177 //console.log('Got request from partner ("' + req.url + '")'); 179 //console.log('Got request from partner ("' + req.url + '")');
178 var sn; 180 var sn;
179 181
180 res.end('OK'); 182 res.end('OK');
181 183
182 var qs = url.parse(req.url, true).query; 184 var qs = url.parse(req.url, true).query;
183 logger.info('Reverse Report', {qs: qs}); 185 logger.info('Reverse Report', {qs: qs});
184 186
185 var response_code = '68'; 187 var response_code = '68';
186 var request_id = qs.pid; 188 var request_id = qs.pid;
187 var message = qs.msg; 189 var message = qs.msg;
188 190
189 if (qs.code == 2) { 191 if (qs.code == 2) {
190 // gagal 192 // gagal
191 response_code = '40'; 193 response_code = '40';
192 } else if (qs.code == 3) { 194 } else if (qs.code == 3) {
193 // refund 195 // refund
194 response_code = '40'; 196 response_code = '40';
195 } else if (qs.code == 4) { 197 } else if (qs.code == 4) {
196 198
197 response_code = '00'; 199 response_code = '00';
198 sn = qs.sn; 200 sn = qs.sn;
199 if (sn && typeof sn === 'string') { 201 if (sn && typeof sn === 'string') {
200 sn = sn.toUpperCase().replace(/[^A-Z0-9\/]/g, '-').replace(/-+/g, '-').replace(/-+\//g, '/').replace(/^-+/, '').replace(/-+$/, '-'); 202 sn = sn.toUpperCase().replace(/[^A-Z0-9\/]/g, '-').replace(/-+/g, '-').replace(/-+\//g, '/').replace(/^-+/, '').replace(/-+$/, '-');
201 } 203 }
202 204
203 message = 'SN=' + qs.sn + '; ' + message; 205 message = 'SN=' + qs.sn + '; ' + message;
204 } 206 }
205 207
206 if (response_code == '40') { 208 if (response_code == '40') {
207 var new_response_code = responseCodeFromMessage(message); 209 var new_response_code = responseCodeFromMessage(message);
208 if (new_response_code) { 210 if (new_response_code) {
209 response_code = new_response_code; 211 response_code = new_response_code;
210 } 212 }
211 } 213 }
212 214
213 callbackReport(request_id, response_code, message); 215 callbackReport(request_id, response_code, message);
214 }); 216 });
215 217
216 httpServer.listen(config.h2h_out.listen_port, function() { 218 httpServer.listen(config.h2h_out.listen_port, function() {
217 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); 219 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
218 }); 220 });
219 } 221 }
220 222
221 function start(options) { 223 function start(options) {
222 if (!options) { 224 if (!options) {
223 console.log('Undefined options, terminating....'); 225 console.log('Undefined options, terminating....');
224 process.exit(1); 226 process.exit(1);
225 } 227 }
226 228
227 if (options.config) { 229 if (options.config) {
228 config = options.config; 230 config = options.config;
229 } else { 231 } else {
230 console.log('Undefined options.config, terminating....') 232 console.log('Undefined options.config, terminating....')
231 process.exit(1); 233 process.exit(1);
232 } 234 }
233 235
234 if (options.aaa) { 236 if (options.aaa) {
235 aaa = options.aaa; 237 aaa = options.aaa;
236 callbackReport = options.aaa.callbackReportWithPushToMongoDb; 238 callbackReport = options.aaa.callbackReportWithPushToMongoDb;
237 } else { 239 } else {
238 console.log('Undefined options.aaa, terminating....') 240 console.log('Undefined options.aaa, terminating....')
239 process.exit(1); 241 process.exit(1);
240 } 242 }
241 243
242 if (options && options.logger) { 244 if (options && options.logger) {
243 logger = options.logger; 245 logger = options.logger;
244 } else { 246 } else {
245 logger = new winston.Logger({ 247 logger = new winston.Logger({
246 transports: [ 248 transports: [
247 new (winston.transports.Console)() 249 new (winston.transports.Console)()
248 ] 250 ]
249 }); 251 });
250 } 252 }
251 253
252 createServer(); 254 createServer();
253 } 255 }
254 256
255 exports.start = start; 257 exports.start = start;
256 exports.topupRequest = topupRequest; 258 exports.topupRequest = topupRequest;
257 exports.calculateSignature = calculateSignature; 259 exports.calculateSignature = calculateSignature;
258 260