Commit 86e71ad257586dadc9b81a83a5885636975f33ee

Authored by Adhidarma Hadiwinoto
1 parent 4f5d7f25ee
Exists in master

splitRemoteProduct

Showing 2 changed files with 35 additions and 1 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 7
8 var config; 8 var config;
9 var aaa; 9 var aaa;
10 var logger; 10 var logger;
11 11
12 function start(options) { 12 function start(options) {
13 if (!options) { 13 if (!options) {
14 console.log('Undefined options, terminating....'); 14 console.log('Undefined options, terminating....');
15 process.exit(1); 15 process.exit(1);
16 } 16 }
17 17
18 if (options.config) { 18 if (options.config) {
19 config = options.config; 19 config = options.config;
20 } else { 20 } else {
21 console.log('Undefined options.config, terminating....') 21 console.log('Undefined options.config, terminating....')
22 process.exit(1); 22 process.exit(1);
23 } 23 }
24 24
25 if (options.aaa) { 25 if (options.aaa) {
26 aaa = options.aaa; 26 aaa = options.aaa;
27 } else { 27 } else {
28 console.log('Undefined options.aaa, terminating....') 28 console.log('Undefined options.aaa, terminating....')
29 process.exit(1); 29 process.exit(1);
30 } 30 }
31 31
32 if (options && options.logger) { 32 if (options && options.logger) {
33 logger = options.logger; 33 logger = options.logger;
34 } else { 34 } else {
35 console.log('Undefined options.logger, terminating....') 35 console.log('Undefined options.logger, terminating....')
36 process.exit(1); 36 process.exit(1);
37 } 37 }
38 } 38 }
39 39
40 function callbackReport(requestId, rc, message, options) { 40 function callbackReport(requestId, rc, message, options) {
41 aaa.callbackReportWithPushToMongoDb(requestId, rc, message); 41 aaa.callbackReportWithPushToMongoDb(requestId, rc, message);
42 } 42 }
43 43
44 function topupRequest(task) { 44 function topupRequest(task) {
45 aaa.insertTaskToMongoDb(task); 45 aaa.insertTaskToMongoDb(task);
46 _hitTopup(task); 46 _hitTopup(task);
47 } 47 }
48 48
49 function splitRemoteProduct(remoteProduct) {
50 return remoteProduct.replace(/^\s+|\s+$/gm,'').split(/[\/\W]+/);
51 }
52
49 function _hitTopup(task, isCheckStatus) { 53 function _hitTopup(task, isCheckStatus) {
50 54
51 const remoteProduct = task.remoteProduct.split('/'); 55 const remoteProduct = splitRemoteProduct(task.remoteProduct);
56
52 if (remoteProduct.length < 4) { 57 if (remoteProduct.length < 4) {
53 callbackReport(task.requestId, '40', 'INTERNAL_MSG: Invalid remoteProduct', task) 58 callbackReport(task.requestId, '40', 'INTERNAL_MSG: Invalid remoteProduct', task)
54 return; 59 return;
55 } 60 }
56 61
57 let pathParams = { 62 let pathParams = {
58 request_type: "purchase", 63 request_type: "purchase",
59 noid: config.h2h_out.noid, 64 noid: config.h2h_out.noid,
60 token: config.h2h_out.token, 65 token: config.h2h_out.token,
61 product: remoteProduct[0], 66 product: remoteProduct[0],
62 product_type: remoteProduct[1], 67 product_type: remoteProduct[1],
63 id_pel: task.destination, 68 id_pel: task.destination,
64 nominal: remoteProduct[2], 69 nominal: remoteProduct[2],
65 admin: remoteProduct[3], 70 admin: remoteProduct[3],
66 trace_id: task.requestId 71 trace_id: task.requestId
67 } 72 }
68 73
69 const requestOptions = { 74 const requestOptions = {
70 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPath(pathParams).replace(/^\/+/, '') 75 url: config.h2h_out.partner.replace(/\/+$/, '') + '/' + createUrlPath(pathParams).replace(/^\/+/, '')
71 } 76 }
72 77
73 logger.verbose('Requeting to partner', {requestOptions: requestOptions}); 78 logger.verbose('Requeting to partner', {requestOptions: requestOptions});
74 request(requestOptions, function(error, response, body) { 79 request(requestOptions, function(error, response, body) {
75 if (error) { 80 if (error) {
76 let rc = '68'; 81 let rc = '68';
77 82
78 if (!isCheckStatus && (error.syscall == 'connect')) { 83 if (!isCheckStatus && (error.syscall == 'connect')) {
79 rc = '91'; 84 rc = '91';
80 } 85 }
81 86
82 logger.warn('Error requesting to partner', {task: task, rc: rc, error: error}); 87 logger.warn('Error requesting to partner', {task: task, rc: rc, error: error});
83 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting to partner. ' + error, {task: task}); 88 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting to partner. ' + error, {task: task});
84 return; 89 return;
85 } 90 }
86 91
87 if (response.statusCode != 200) { 92 if (response.statusCode != 200) {
88 let rc = '68'; 93 let rc = '68';
89 94
90 logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode}); 95 logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode});
91 callbackReport(task.requestId, rc, 'INTERNAL_MSG: HTTP status code ' + response.statusCode, {task: task}); 96 callbackReport(task.requestId, rc, 'INTERNAL_MSG: HTTP status code ' + response.statusCode, {task: task});
92 return; 97 return;
93 } 98 }
94 99
95 if (!body) { 100 if (!body) {
96 let rc = '68'; 101 let rc = '68';
97 102
98 logger.warn('Error processing response body', {task: task, responseBody: body}); 103 logger.warn('Error processing response body', {task: task, responseBody: body});
99 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error processing response body', {task: task}); 104 callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error processing response body', {task: task});
100 return; 105 return;
101 } 106 }
102 107
103 if (body.trim() == 'invalid specs') { 108 if (body.trim() == 'invalid specs') {
104 let rc = '40'; 109 let rc = '40';
105 110
106 logger.warn('Invalid specs', {task: task, responseBody: body}); 111 logger.warn('Invalid specs', {task: task, responseBody: body});
107 callbackReport(task.requestId, rc, body); 112 callbackReport(task.requestId, rc, body);
108 return; 113 return;
109 } 114 }
110 115
111 logger.verbose('Got response from partner', {task: task, responseBody: body}); 116 logger.verbose('Got response from partner', {task: task, responseBody: body});
112 117
113 const responseData = parseResponseBody(body); 118 const responseData = parseResponseBody(body);
114 logger.verbose('Response body parsed as json value', {responseData: responseData}); 119 logger.verbose('Response body parsed as json value', {responseData: responseData});
115 const data = responseDataProcessor(responseData); 120 const data = responseDataProcessor(responseData);
116 121
117 if (data.balance && aaa.updateBalance) { 122 if (data.balance && aaa.updateBalance) {
118 aaa.updateBalance(data.balance); 123 aaa.updateBalance(data.balance);
119 } 124 }
120 125
121 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task}); 126 callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task});
122 }) 127 })
123 128
124 } 129 }
125 130
126 function createUrlPath(options) { 131 function createUrlPath(options) {
127 let urlPath = [ 132 let urlPath = [
128 "get", 133 "get",
129 options.request_type || "purchase", 134 options.request_type || "purchase",
130 "json", 135 "json",
131 options.noid, 136 options.noid,
132 options.token, 137 options.token,
133 options.product, 138 options.product,
134 options.product_type, 139 options.product_type,
135 options.id_pel, 140 options.id_pel,
136 options.nominal || 0, 141 options.nominal || 0,
137 options.admin || 0, 142 options.admin || 0,
138 options.trace_id 143 options.trace_id
139 ].join('/'); 144 ].join('/');
140 145
141 return '/' + urlPath; 146 return '/' + urlPath;
142 } 147 }
143 148
144 function parseResponseBody(body) { 149 function parseResponseBody(body) {
145 let data; 150 let data;
146 151
147 try { 152 try {
148 data = JSON.parse(body); 153 data = JSON.parse(body);
149 } 154 }
150 catch(e) { 155 catch(e) {
151 if (logger) { 156 if (logger) {
152 logger.warn('Exception on parsing result body: ' + e); 157 logger.warn('Exception on parsing result body: ' + e);
153 return; 158 return;
154 } 159 }
155 } 160 }
156 161
157 return data; 162 return data;
158 } 163 }
159 164
160 function responseDataProcessor(responseData) { 165 function responseDataProcessor(responseData) {
161 let retval = { 166 let retval = {
162 rc: '68', 167 rc: '68',
163 sn: '', 168 sn: '',
164 responseMessage: '', 169 responseMessage: '',
165 combinedMessage: '', 170 combinedMessage: '',
166 amount: 0, 171 amount: 0,
167 balance: 0, 172 balance: 0,
168 saldo: 0, 173 saldo: 0,
169 ts: '', 174 ts: '',
170 loadTime: 0, 175 loadTime: 0,
171 product: '', 176 product: '',
172 productType: '' 177 productType: ''
173 } 178 }
174 179
175 let combinedMessage = []; 180 let combinedMessage = [];
176 181
177 if (responseData.response_code == '0000') { 182 if (responseData.response_code == '0000') {
178 retval.rc = '00'; 183 retval.rc = '00';
179 } 184 }
180 else if (responseData.response_code == '0010') { 185 else if (responseData.response_code == '0010') {
181 retval.rc = '14'; 186 retval.rc = '14';
182 } 187 }
183 else if (responseData.response_code == '0021') { 188 else if (responseData.response_code == '0021') {
184 retval.rc = '14'; 189 retval.rc = '14';
185 } 190 }
186 else if (['9990','0099','0068','0063','0005','9997','9999','9998','9990','0600','1003'].indexOf(responseData.response_code) >= 0) { 191 else if (['9990','0099','0068','0063','0005','9997','9999','9998','9990','0600','1003'].indexOf(responseData.response_code) >= 0) {
187 retval.rc = '68'; 192 retval.rc = '68';
188 } 193 }
189 else { 194 else {
190 retval.rc = '40'; 195 retval.rc = '40';
191 } 196 }
192 197
193 if (responseData.response_code) { 198 if (responseData.response_code) {
194 combinedMessage.push(responseData.response_code); 199 combinedMessage.push(responseData.response_code);
195 } 200 }
196 201
197 if (responseData.product) { 202 if (responseData.product) {
198 combinedMessage.push(responseData.product) 203 combinedMessage.push(responseData.product)
199 } 204 }
200 205
201 if (responseData.produk_tipe) { 206 if (responseData.produk_tipe) {
202 combinedMessage.push(responseData.produk_tipe) 207 combinedMessage.push(responseData.produk_tipe)
203 } 208 }
204 209
205 if (responseData.idpel) { 210 if (responseData.idpel) {
206 combinedMessage.push(responseData.idpel) 211 combinedMessage.push(responseData.idpel)
207 } 212 }
208 213
209 retval.responseMessage = responseData.response_message || ''; 214 retval.responseMessage = responseData.response_message || '';
210 if (retval.responseMessage) { 215 if (retval.responseMessage) {
211 combinedMessage.push(retval.responseMessage); 216 combinedMessage.push(retval.responseMessage);
212 } 217 }
213 218
214 if (responseData.detail) { 219 if (responseData.detail) {
215 retval.sn = responseData.detail.voucherSerialNumber || ''; 220 retval.sn = responseData.detail.voucherSerialNumber || '';
216 } 221 }
217 222
218 retval.amount = responseData.amount || 0; 223 retval.amount = responseData.amount || 0;
219 combinedMessage.push('Amount: ' + retval.amount); 224 combinedMessage.push('Amount: ' + retval.amount);
220 225
221 retval.balance = responseData.saldo || 0; 226 retval.balance = responseData.saldo || 0;
222 retval.saldo = retval.balance; 227 retval.saldo = retval.balance;
223 combinedMessage.push('Balance: ' + retval.balance); 228 combinedMessage.push('Balance: ' + retval.balance);
224 229
225 retval.ts = responseData.waktu || ''; 230 retval.ts = responseData.waktu || '';
226 combinedMessage.push(retval.ts); 231 combinedMessage.push(retval.ts);
227 232
228 retval.loadTime = responseData.loadTime || ''; 233 retval.loadTime = responseData.loadTime || '';
229 combinedMessage.push('Load time: ' + retval.loadTime); 234 combinedMessage.push('Load time: ' + retval.loadTime);
230 235
231 retval.combinedMessage = combinedMessage.join(' | '); 236 retval.combinedMessage = combinedMessage.join(' | ');
232 237
233 if (retval.sn) { 238 if (retval.sn) {
234 retval.combinedMessage = 'SN=' + retval.sn + '; ' + retval.combinedMessage; 239 retval.combinedMessage = 'SN=' + retval.sn + '; ' + retval.combinedMessage;
235 } 240 }
236 241
237 return retval; 242 return retval;
238 } 243 }
239 244
240 exports.start = start; 245 exports.start = start;
241 exports.createUrlPath = createUrlPath; 246 exports.createUrlPath = createUrlPath;
242 exports.parseResponseBody = parseResponseBody; 247 exports.parseResponseBody = parseResponseBody;
243 exports.responseDataProcessor = responseDataProcessor; 248 exports.responseDataProcessor = responseDataProcessor;
244 exports.topupRequest = topupRequest; 249 exports.topupRequest = topupRequest;
250 exports.splitRemoteProduct = splitRemoteProduct;
245 251
1 "use strict"; 1 "use strict";
2 2
3 const should = require("should"); 3 const should = require("should");
4 const partner = require("./partner-bnisp"); 4 const partner = require("./partner-bnisp");
5 5
6 describe("#partner", function() { 6 describe("#partner", function() {
7 describe("#createUrlPath", function() { 7 describe("#createUrlPath", function() {
8 8
9 it('should return correct url path based on example', function() { 9 it('should return correct url path based on example', function() {
10 let options = { 10 let options = {
11 noid: 1002003, 11 noid: 1002003,
12 token: 'CIPY6t6ruy5UuGG0PCqu', 12 token: 'CIPY6t6ruy5UuGG0PCqu',
13 product: 'PULSA', 13 product: 'PULSA',
14 product_type: 'THREE5000', 14 product_type: 'THREE5000',
15 id_pel: '0895385381299', 15 id_pel: '0895385381299',
16 trace_id: 16 16 trace_id: 16
17 } 17 }
18 18
19 partner.createUrlPath(options).should.equal('/get/purchase/json/1002003/CIPY6t6ruy5UuGG0PCqu/PULSA/THREE5000/0895385381299/0/0/16') 19 partner.createUrlPath(options).should.equal('/get/purchase/json/1002003/CIPY6t6ruy5UuGG0PCqu/PULSA/THREE5000/0895385381299/0/0/16')
20 }) 20 })
21 21
22 }) 22 })
23 23
24 const responseBody = '{"trxId":"064024","response_code":"0000","response_message":"SUKSES","detail":{"jmlTagihan":"1","kodeThree":"012001","nilaiPulsa":"000000005000","noHp":"0895385381299","transactionId":"0612143023138365102 ","voucherSerialNumber":"20170612143620980249"},"reff":"20170612143620980249","loadTime":"0.0107","tipe_request":"purchase","prv":"hpay","userID":"1002003","idpel":"0895385381299","product":"PULSA","produk":"PULSA","product_detail":"THREE5000","produk_tipe":"THREE5000","traceId":16,"tagihan":5050,"total_tagihan":5050,"amount":5050,"saldo":94950,"waktu":"2017-07-17 18:43:32"}'; 24 const responseBody = '{"trxId":"064024","response_code":"0000","response_message":"SUKSES","detail":{"jmlTagihan":"1","kodeThree":"012001","nilaiPulsa":"000000005000","noHp":"0895385381299","transactionId":"0612143023138365102 ","voucherSerialNumber":"20170612143620980249"},"reff":"20170612143620980249","loadTime":"0.0107","tipe_request":"purchase","prv":"hpay","userID":"1002003","idpel":"0895385381299","product":"PULSA","produk":"PULSA","product_detail":"THREE5000","produk_tipe":"THREE5000","traceId":16,"tagihan":5050,"total_tagihan":5050,"amount":5050,"saldo":94950,"waktu":"2017-07-17 18:43:32"}';
25 const responseData = partner.parseResponseBody(responseBody); 25 const responseData = partner.parseResponseBody(responseBody);
26 26
27 describe('#parseResponseBody', function() { 27 describe('#parseResponseBody', function() {
28 28
29 it('should return correct response code', function() { 29 it('should return correct response code', function() {
30 responseData.response_code.should.equal('0000'); 30 responseData.response_code.should.equal('0000');
31 }) 31 })
32 32
33 it('should return correct voucher serial number', function() { 33 it('should return correct voucher serial number', function() {
34 responseData.detail.voucherSerialNumber.should.equal('20170612143620980249'); 34 responseData.detail.voucherSerialNumber.should.equal('20170612143620980249');
35 }) 35 })
36 }) 36 })
37 37
38 describe('#responseDataProcessor', function() { 38 describe('#responseDataProcessor', function() {
39 const processed = partner.responseDataProcessor(responseData); 39 const processed = partner.responseDataProcessor(responseData);
40 40
41 it('should return correct rc', function() { 41 it('should return correct rc', function() {
42 processed.rc.should.equal('00'); 42 processed.rc.should.equal('00');
43 }) 43 })
44 44
45 it('should return correct sn', function() { 45 it('should return correct sn', function() {
46 processed.sn.should.equal('20170612143620980249'); 46 processed.sn.should.equal('20170612143620980249');
47 }) 47 })
48 48
49 it('should return correct amount', function() { 49 it('should return correct amount', function() {
50 processed.amount.should.equal(5050); 50 processed.amount.should.equal(5050);
51 }) 51 })
52 52
53 it('should return correct balance', function() { 53 it('should return correct balance', function() {
54 processed.balance.should.equal(94950); 54 processed.balance.should.equal(94950);
55 }) 55 })
56 }) 56 })
57
58 describe('#splitRemoteProduct', function() {
59 it ('should return correctly using space as separator', function() {
60 const remoteProduct = 'PULSA THREE5000 0 0';
61 partner.splitRemoteProduct(remoteProduct)[0].should.equal('PULSA');
62 partner.splitRemoteProduct(remoteProduct)[1].should.equal('THREE5000');
63 partner.splitRemoteProduct(remoteProduct)[2].should.equal('0');
64 partner.splitRemoteProduct(remoteProduct)[3].should.equal('0');
65 })
66
67 it ('should return correctly using comma as separator', function() {
68 const remoteProduct = 'PULSA,THREE5000,0,0';
69 partner.splitRemoteProduct(remoteProduct)[0].should.equal('PULSA');
70 partner.splitRemoteProduct(remoteProduct)[1].should.equal('THREE5000');
71 partner.splitRemoteProduct(remoteProduct)[2].should.equal('0');
72 partner.splitRemoteProduct(remoteProduct)[3].should.equal('0');
73 })
74
75 it ('should return correctly using slash as separator', function() {
76 const remoteProduct = 'PULSA/THREE5000/0/0';
77 partner.splitRemoteProduct(remoteProduct)[0].should.equal('PULSA');
78 partner.splitRemoteProduct(remoteProduct)[1].should.equal('THREE5000');
79 partner.splitRemoteProduct(remoteProduct)[2].should.equal('0');
80 partner.splitRemoteProduct(remoteProduct)[3].should.equal('0');
81 })
82
83
84 })
57 }) 85 })
58 86