Commit 452ab957965e76610b6257bb2bb96707e51fbe69

Authored by Adhidarma Hadiwinoto
1 parent 1a1c2058c6
Exists in master

penanganan data tidak ditemukan

Showing 1 changed file with 6 additions and 3 deletions Inline Diff

1 "use strict"; 1 "use strict";
2 2
3 const http = require('http'); 3 const http = require('http');
4 http.globalAgent.maxSockets = Infinity; 4 http.globalAgent.maxSockets = Infinity;
5 5
6 const request = require('request'); 6 const request = require('request');
7 const resendDelay = require('sate24/resend-delay') 7 const resendDelay = require('sate24/resend-delay')
8 8
9 var config; 9 var config;
10 var aaa; 10 var aaa;
11 var logger; 11 var logger;
12 12
13 function start(options) { 13 function start(options) {
14 if (!options) { 14 if (!options) {
15 console.log('Undefined options, terminating....'); 15 console.log('Undefined options, terminating....');
16 process.exit(1); 16 process.exit(1);
17 } 17 }
18 18
19 if (options.config) { 19 if (options.config) {
20 config = options.config; 20 config = options.config;
21 } else { 21 } else {
22 console.log('Undefined options.config, terminating....') 22 console.log('Undefined options.config, terminating....')
23 process.exit(1); 23 process.exit(1);
24 } 24 }
25 25
26 if (options.aaa) { 26 if (options.aaa) {
27 aaa = options.aaa; 27 aaa = options.aaa;
28 } else { 28 } else {
29 console.log('Undefined options.aaa, terminating....') 29 console.log('Undefined options.aaa, terminating....')
30 process.exit(1); 30 process.exit(1);
31 } 31 }
32 32
33 if (options && options.logger) { 33 if (options && options.logger) {
34 logger = options.logger; 34 logger = options.logger;
35 } else { 35 } else {
36 console.log('Undefined options.logger, terminating....') 36 console.log('Undefined options.logger, terminating....')
37 process.exit(1); 37 process.exit(1);
38 } 38 }
39 39
40 resendDelay.init({config: config, logger: logger, topupRequest: topupAdvice}); 40 resendDelay.init({config: config, logger: logger, topupRequest: topupAdvice});
41 } 41 }
42 42
43 function callbackReport(requestId, rc, message, options) { 43 function callbackReport(requestId, rc, message, options) {
44 if (rc == '68') { 44 if (rc == '68') {
45 resendDelay.register(options.task); 45 resendDelay.register(options.task);
46 } else { 46 } else {
47 resendDelay.cancel(options.task) 47 resendDelay.cancel(options.task)
48 } 48 }
49 49
50 aaa.callbackReportWithPushToMongoDb(requestId, rc, message); 50 aaa.callbackReportWithPushToMongoDb(requestId, rc, message);
51 } 51 }
52 52
53 function splitRemoteProduct(remoteProduct) { 53 function splitRemoteProduct(remoteProduct) {
54 return remoteProduct.replace(/^\s+|\s+$/gm,'').split(/[\/\W]+/); 54 return remoteProduct.replace(/^\s+|\s+$/gm,'').split(/[\/\W]+/);
55 } 55 }
56 56
57 function topupRequest(task) { 57 function topupRequest(task) {
58 aaa.insertTaskToMongoDb(task); 58 aaa.insertTaskToMongoDb(task);
59 59
60 const remoteProduct = splitRemoteProduct(task.remoteProduct); 60 const remoteProduct = splitRemoteProduct(task.remoteProduct);
61 61
62 if (remoteProduct.length < 4) { 62 if (remoteProduct.length < 4) {
63 callbackReport(task.requestId, '40', 'INTERNAL_MSG: Invalid remoteProduct', task) 63 callbackReport(task.requestId, '40', 'INTERNAL_MSG: Invalid remoteProduct', task)
64 return; 64 return;
65 } 65 }
66 66
67 let pathParams = { 67 let pathParams = {
68 request_type: "purchase", 68 request_type: "purchase",
69 noid: config.h2h_out.noid, 69 noid: config.h2h_out.noid,
70 token: config.h2h_out.token, 70 token: config.h2h_out.token,
71 product: remoteProduct[0], 71 product: remoteProduct[0],
72 product_type: remoteProduct[1], 72 product_type: remoteProduct[1],
73 id_pel: task.destination, 73 id_pel: task.destination,
74 nominal: remoteProduct[2], 74 nominal: remoteProduct[2],
75 admin: remoteProduct[3], 75 admin: remoteProduct[3],
76 trace_id: task.requestId 76 trace_id: task.requestId
77 } 77 }
78 78
79 const requestOptions = { 79 const requestOptions = {
80 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPath(pathParams).replace(/^\/+/, '') 80 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPath(pathParams).replace(/^\/+/, '')
81 } 81 }
82 82
83 logger.verbose('Requeting to partner', {requestOptions: requestOptions}); 83 logger.verbose('Requeting to partner', {requestOptions: requestOptions});
84 request(requestOptions, function(error, response, body) { 84 request(requestOptions, function(error, response, body) {
85 if (error) { 85 if (error) {
86 let rc = '68'; 86 let rc = '68';
87 87
88 if (!error.syscall == 'connect') { 88 if (!error.syscall == 'connect') {
89 rc = '91'; 89 rc = '91';
90 } 90 }
91 91
92 logger.warn('Error requesting to partner', {task: task, rc: rc, error: error}); 92 logger.warn('Error requesting to partner', {task: task, rc: rc, error: error});
93 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting to partner. ' + error, {task: task}); 93 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting to partner. ' + error, {task: task});
94 return; 94 return;
95 } 95 }
96 96
97 if (response.statusCode != 200) { 97 if (response.statusCode != 200) {
98 let rc = '68'; 98 let rc = '68';
99 99
100 logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode}); 100 logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode});
101 callbackReport(task.requestId, rc, 'INTERNAL_MSG: HTTP status code ' + response.statusCode, {task: task}); 101 callbackReport(task.requestId, rc, 'INTERNAL_MSG: HTTP status code ' + response.statusCode, {task: task});
102 return; 102 return;
103 } 103 }
104 104
105 if (!body) { 105 if (!body) {
106 let rc = '68'; 106 let rc = '68';
107 107
108 logger.warn('Missing response body', {task: task, responseBody: body}); 108 logger.warn('Missing response body', {task: task, responseBody: body});
109 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Missing response body', {task: task}); 109 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Missing response body', {task: task});
110 return; 110 return;
111 } 111 }
112 112
113 if (body.trim() == 'invalid specs') { 113 if (body.trim() == 'invalid specs') {
114 let rc = '40'; 114 let rc = '40';
115 115
116 logger.warn('Invalid specs', {task: task, responseBody: body}); 116 logger.warn('Invalid specs', {task: task, responseBody: body});
117 callbackReport(task.requestId, rc, body); 117 callbackReport(task.requestId, rc, body);
118 return; 118 return;
119 } 119 }
120 120
121 logger.verbose('Got response from partner', {task: task, responseBody: body}); 121 logger.verbose('Got response from partner', {task: task, responseBody: body});
122 122
123 const responseData = parseResponseBody(body); 123 const responseData = parseResponseBody(body);
124 logger.verbose('Response body parsed as json value', {responseData: responseData}); 124 logger.verbose('Response body parsed as json value', {responseData: responseData});
125 const data = responseDataProcessor(responseData); 125 const data = responseDataProcessor(responseData);
126 126
127 if (data.balance && aaa.updateBalance) { 127 if (data.balance && aaa.updateBalance) {
128 aaa.updateBalance(data.balance); 128 aaa.updateBalance(data.balance);
129 } 129 }
130 130
131 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task}); 131 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task});
132 }) 132 })
133 133
134 } 134 }
135 135
136 function topupAdvice(task) { 136 function topupAdvice(task) {
137 137
138 let pathParams = { 138 let pathParams = {
139 noid: config.h2h_out.noid, 139 noid: config.h2h_out.noid,
140 token: config.h2h_out.token, 140 token: config.h2h_out.token,
141 trace_id: task.requestId 141 trace_id: task.requestId
142 } 142 }
143 143
144 const requestOptions = { 144 const requestOptions = {
145 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPathAdvice(pathParams).replace(/^\/+/, '') 145 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPathAdvice(pathParams).replace(/^\/+/, '')
146 } 146 }
147 147
148 logger.verbose('Requeting advice to partner', {requestOptions: requestOptions}); 148 logger.verbose('Requeting advice to partner', {requestOptions: requestOptions});
149 request(requestOptions, function(error, response, body) { 149 request(requestOptions, function(error, response, body) {
150 if (error) { 150 if (error) {
151 let rc = '68'; 151 let rc = '68';
152 152
153 logger.warn('Error requesting to advice partner', {task: task, rc: rc, error: error}); 153 logger.warn('Error requesting to advice partner', {task: task, rc: rc, error: error});
154 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting advice to partner. ' + error, {task: task}); 154 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting advice to partner. ' + error, {task: task});
155 return; 155 return;
156 } 156 }
157 157
158 if (response.statusCode != 200) { 158 if (response.statusCode != 200) {
159 let rc = '68'; 159 let rc = '68';
160 160
161 logger.warn('Advice HTTP status code is not 200', {task: task, http_status_code: response.statusCode}); 161 logger.warn('Advice HTTP status code is not 200', {task: task, http_status_code: response.statusCode});
162 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Advice HTTP status code ' + response.statusCode, {task: task}); 162 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Advice HTTP status code ' + response.statusCode, {task: task});
163 return; 163 return;
164 } 164 }
165 165
166 if (!body) { 166 if (!body) {
167 let rc = '68'; 167 let rc = '68';
168 168
169 logger.warn('Missing advice response body', {task: task, responseBody: body}); 169 logger.warn('Missing advice response body', {task: task, responseBody: body});
170 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Missing advice response body', {task: task}); 170 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Missing advice response body', {task: task});
171 return; 171 return;
172 } 172 }
173 173
174 if (body.trim() == 'invalid specs') { 174 if (body.trim() == 'invalid specs') {
175 let rc = '68';
176
177 logger.warn('Invalid specs', {task: task, responseBody: body}); 175 logger.warn('Invalid specs', {task: task, responseBody: body});
178 callbackReport(task.requestId, rc, body); 176 callbackReport(task.requestId, '68', body);
177 return;
178 }
179 else if (body.trim() == 'data tidak ditemukan') {
180 logger.warn(body, {task: task, responseBody: body});
181 callbackReport(task.requestId, '40', body);
179 return; 182 return;
180 } 183 }
181 184
182 logger.verbose('Got advice response from partner', {task: task, responseBody: body}); 185 logger.verbose('Got advice response from partner', {task: task, responseBody: body});
183 186
184 const responseData = parseResponseBody(body); 187 const responseData = parseResponseBody(body);
185 logger.verbose('Advice response body parsed as json value', {responseData: responseData}); 188 logger.verbose('Advice response body parsed as json value', {responseData: responseData});
186 const data = responseDataProcessor(responseData); 189 const data = responseDataProcessor(responseData);
187 190
188 if (data.balance && aaa.updateBalance) { 191 if (data.balance && aaa.updateBalance) {
189 aaa.updateBalance(data.balance); 192 aaa.updateBalance(data.balance);
190 } 193 }
191 194
192 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task}); 195 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task});
193 }) 196 })
194 197
195 } 198 }
196 199
197 function createUrlPath(options) { 200 function createUrlPath(options) {
198 let urlPath = [ 201 let urlPath = [
199 "get", 202 "get",
200 options.request_type || "purchase", 203 options.request_type || "purchase",
201 "json", 204 "json",
202 options.noid, 205 options.noid,
203 options.token, 206 options.token,
204 options.product, 207 options.product,
205 options.product_type, 208 options.product_type,
206 options.id_pel, 209 options.id_pel,
207 options.nominal || 0, 210 options.nominal || 0,
208 options.admin || 0, 211 options.admin || 0,
209 options.trace_id 212 options.trace_id
210 ].join('/'); 213 ].join('/');
211 214
212 return '/' + urlPath; 215 return '/' + urlPath;
213 } 216 }
214 217
215 function createUrlPathAdvice(options) { 218 function createUrlPathAdvice(options) {
216 // pattern: /get/advice/json/[noid]/[token]/[traceid] 219 // pattern: /get/advice/json/[noid]/[token]/[traceid]
217 220
218 let urlPath = [ 221 let urlPath = [
219 "get", 222 "get",
220 "advice", 223 "advice",
221 "json", 224 "json",
222 options.noid, 225 options.noid,
223 options.token, 226 options.token,
224 options.trace_id 227 options.trace_id
225 ].join('/'); 228 ].join('/');
226 229
227 return '/' + urlPath; 230 return '/' + urlPath;
228 } 231 }
229 232
230 function parseResponseBody(body) { 233 function parseResponseBody(body) {
231 let data; 234 let data;
232 235
233 try { 236 try {
234 data = JSON.parse(body); 237 data = JSON.parse(body);
235 } 238 }
236 catch(e) { 239 catch(e) {
237 if (logger) { 240 if (logger) {
238 logger.warn('Exception on parsing result body: ' + e); 241 logger.warn('Exception on parsing result body: ' + e);
239 return; 242 return;
240 } 243 }
241 } 244 }
242 245
243 return data; 246 return data;
244 } 247 }
245 248
246 function responseDataProcessor(responseData) { 249 function responseDataProcessor(responseData) {
247 let retval = { 250 let retval = {
248 rc: '68', 251 rc: '68',
249 sn: '', 252 sn: '',
250 responseMessage: '', 253 responseMessage: '',
251 combinedMessage: '', 254 combinedMessage: '',
252 amount: 0, 255 amount: 0,
253 balance: 0, 256 balance: 0,
254 saldo: 0, 257 saldo: 0,
255 ts: '', 258 ts: '',
256 loadTime: 0, 259 loadTime: 0,
257 product: '', 260 product: '',
258 productType: '' 261 productType: ''
259 } 262 }
260 263
261 let combinedMessage = []; 264 let combinedMessage = [];
262 265
263 if (responseData.response_code == '0000') { 266 if (responseData.response_code == '0000') {
264 retval.rc = '00'; 267 retval.rc = '00';
265 } 268 }
266 else if (responseData.response_code == '0010') { 269 else if (responseData.response_code == '0010') {
267 retval.rc = '14'; 270 retval.rc = '14';
268 } 271 }
269 else if (responseData.response_code == '0021') { 272 else if (responseData.response_code == '0021') {
270 retval.rc = '14'; 273 retval.rc = '14';
271 } 274 }
272 else if (['9990','0099','0068','0063','0005','9997','9999','9998','9990','0600','1003'].indexOf(responseData.response_code) >= 0) { 275 else if (['9990','0099','0068','0063','0005','9997','9999','9998','9990','0600','1003'].indexOf(responseData.response_code) >= 0) {
273 retval.rc = '68'; 276 retval.rc = '68';
274 } 277 }
275 else { 278 else {
276 retval.rc = '40'; 279 retval.rc = '40';
277 } 280 }
278 281
279 if (responseData.response_code) { 282 if (responseData.response_code) {
280 combinedMessage.push(responseData.response_code); 283 combinedMessage.push(responseData.response_code);
281 } 284 }
282 285
283 if (responseData.product) { 286 if (responseData.product) {
284 combinedMessage.push(responseData.product) 287 combinedMessage.push(responseData.product)
285 } 288 }
286 289
287 if (responseData.produk_tipe) { 290 if (responseData.produk_tipe) {
288 combinedMessage.push(responseData.produk_tipe) 291 combinedMessage.push(responseData.produk_tipe)
289 } 292 }
290 293
291 if (responseData.idpel) { 294 if (responseData.idpel) {
292 combinedMessage.push(responseData.idpel) 295 combinedMessage.push(responseData.idpel)
293 } 296 }
294 297
295 retval.responseMessage = responseData.response_message || ''; 298 retval.responseMessage = responseData.response_message || '';
296 if (retval.responseMessage) { 299 if (retval.responseMessage) {
297 combinedMessage.push(retval.responseMessage); 300 combinedMessage.push(retval.responseMessage);
298 } 301 }
299 302
300 if (responseData.detail) { 303 if (responseData.detail) {
301 retval.sn = responseData.detail.voucherSerialNumber || ''; 304 retval.sn = responseData.detail.voucherSerialNumber || '';
302 } 305 }
303 306
304 retval.amount = responseData.amount || 0; 307 retval.amount = responseData.amount || 0;
305 combinedMessage.push('Amount: ' + retval.amount); 308 combinedMessage.push('Amount: ' + retval.amount);
306 309
307 retval.balance = responseData.saldo || 0; 310 retval.balance = responseData.saldo || 0;
308 retval.saldo = retval.balance; 311 retval.saldo = retval.balance;
309 combinedMessage.push('Balance: ' + retval.balance); 312 combinedMessage.push('Balance: ' + retval.balance);
310 313
311 retval.ts = responseData.waktu || ''; 314 retval.ts = responseData.waktu || '';
312 combinedMessage.push(retval.ts); 315 combinedMessage.push(retval.ts);
313 316
314 retval.loadTime = responseData.loadTime || ''; 317 retval.loadTime = responseData.loadTime || '';
315 combinedMessage.push('Load time: ' + retval.loadTime); 318 combinedMessage.push('Load time: ' + retval.loadTime);
316 319
317 retval.combinedMessage = combinedMessage.join(' | '); 320 retval.combinedMessage = combinedMessage.join(' | ');
318 321
319 if (retval.sn) { 322 if (retval.sn) {
320 retval.combinedMessage = 'SN=' + retval.sn + '; ' + retval.combinedMessage; 323 retval.combinedMessage = 'SN=' + retval.sn + '; ' + retval.combinedMessage;
321 } 324 }
322 325
323 return retval; 326 return retval;
324 } 327 }
325 328
326 exports.start = start; 329 exports.start = start;
327 exports.topupRequest = topupRequest; 330 exports.topupRequest = topupRequest;
328 exports.topupAdvice = topupAdvice; 331 exports.topupAdvice = topupAdvice;
329 exports.createUrlPath = createUrlPath; 332 exports.createUrlPath = createUrlPath;
330 exports.createUrlPathAdvice = createUrlPathAdvice; 333 exports.createUrlPathAdvice = createUrlPathAdvice;
331 exports.parseResponseBody = parseResponseBody; 334 exports.parseResponseBody = parseResponseBody;
332 exports.responseDataProcessor = responseDataProcessor; 335 exports.responseDataProcessor = responseDataProcessor;