Commit 6bdc8c9087ff9af724e10d2ddb192161bb5b7eac
1 parent
ba13f67f80
Exists in
master
buang yg gak perlu
Showing 1 changed file with 1 additions and 197 deletions Inline Diff
partner-trugee.js
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 | 9 | ||
10 | var config; | 10 | var config; |
11 | var callbackReport; | 11 | var callbackReport; |
12 | 12 | ||
13 | var max_retry = 2; | 13 | var max_retry = 2; |
14 | var sleep_before_retry = 2000; | 14 | var sleep_before_retry = 2000; |
15 | 15 | ||
16 | var trx_balances = {}; | 16 | var trx_balances = {}; |
17 | var trx_prices = {}; | 17 | var trx_prices = {}; |
18 | 18 | ||
19 | function calculateSignature(password, msisdn, timestamp) { | 19 | function calculateSignature(password, msisdn, timestamp) { |
20 | var a = timestamp + msisdn.substr(msisdn.length - 4); | 20 | var a = timestamp + msisdn.substr(msisdn.length - 4); |
21 | var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password; | 21 | var b = msisdn.substr(msisdn.length - 4).split('').reverse().join('') + password; |
22 | 22 | ||
23 | return xor.encode(a,b); | 23 | return xor.encode(a,b); |
24 | } | 24 | } |
25 | 25 | ||
26 | /** | ||
27 | * Kalkulasi signature untuk cek balance | ||
28 | * | ||
29 | * @deprecated | ||
30 | */ | ||
31 | function calculateBalanceSignature(userid, password, timestamp) { | ||
32 | var a = '0000' + timestamp; | ||
33 | var b = userid.substr(0, 4) + password; | ||
34 | |||
35 | return xor.encode(a,b); | ||
36 | } | ||
37 | |||
38 | |||
39 | function createPayload(task) { | 26 | function createPayload(task) { |
40 | var timestamp = strftime('%H%M%S'); | 27 | var timestamp = strftime('%H%M%S'); |
41 | 28 | ||
42 | var payload = { | 29 | var payload = { |
43 | pulsamatic: [ | 30 | pulsamatic: [ |
44 | {command: 'TOPUP'}, | 31 | {command: 'TOPUP'}, |
45 | {vtype: task['remoteProduct']}, | 32 | {vtype: task['remoteProduct']}, |
46 | {userid: config.h2h_out.userid}, | 33 | {userid: config.h2h_out.userid}, |
47 | {time: timestamp}, | 34 | {time: timestamp}, |
48 | {msisdn: task['destination']}, | 35 | {msisdn: task['destination']}, |
49 | {trxid: task['requestId']}, | 36 | {trxid: task['requestId']}, |
50 | {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)} | 37 | {sign: calculateSignature(config.h2h_out.password, task['destination'], timestamp)} |
51 | ] | 38 | ] |
52 | }; | 39 | }; |
53 | 40 | ||
54 | console.log(payload); | 41 | console.log(payload); |
55 | return "<?xml version=\"1.0\" ?>\n" + xml(payload); | 42 | return "<?xml version=\"1.0\" ?>\n" + xml(payload); |
56 | } | 43 | } |
57 | 44 | ||
58 | function topupRequest(task, retry) { | 45 | function topupRequest(task, retry) { |
59 | //balanceCheck(); | ||
60 | |||
61 | var payload_xml = createPayload(task); | ||
62 | //console.log(payload_xml); | ||
63 | 46 | ||
47 | var payload_xml = createPayload(task); | ||
64 | var partner = url.parse(config.h2h_out.partner); | 48 | var partner = url.parse(config.h2h_out.partner); |
65 | 49 | ||
66 | var request_options = { | 50 | var request_options = { |
67 | host: partner.hostname, | 51 | host: partner.hostname, |
68 | path: partner.path, | 52 | path: partner.path, |
69 | port: partner.port, | 53 | port: partner.port, |
70 | method: "POST", | 54 | method: "POST", |
71 | headers: { | 55 | headers: { |
72 | 'Content-Type': 'text/xml', | 56 | 'Content-Type': 'text/xml', |
73 | 'Content-Length': Buffer.byteLength(payload_xml) | 57 | 'Content-Length': Buffer.byteLength(payload_xml) |
74 | } | 58 | } |
75 | }; | 59 | }; |
76 | 60 | ||
77 | var buffer = ""; | 61 | var buffer = ""; |
78 | var req = http.request(request_options, function( res ) { | 62 | var req = http.request(request_options, function( res ) { |
79 | 63 | ||
80 | console.log('Status code: ' + res.statusCode ); | 64 | console.log('Status code: ' + res.statusCode ); |
81 | var buffer = ""; | 65 | var buffer = ""; |
82 | res.on( "data", function( data ) { buffer = buffer + data; } ); | 66 | res.on( "data", function( data ) { buffer = buffer + data; } ); |
83 | res.on( "end", function( data ) { | 67 | res.on( "end", function( data ) { |
84 | directResponseHandler(buffer, task['requestId']); | 68 | directResponseHandler(buffer, task['requestId']); |
85 | }); | 69 | }); |
86 | 70 | ||
87 | }); | 71 | }); |
88 | 72 | ||
89 | req.on('error', function(e) { | 73 | req.on('error', function(e) { |
90 | console.log('problem with request: ' + e.message); | 74 | console.log('problem with request: ' + e.message); |
91 | callbackReport(task['requestId'], '40', e.message); | 75 | callbackReport(task['requestId'], '40', e.message); |
92 | }); | 76 | }); |
93 | 77 | ||
94 | req.write( payload_xml ); | 78 | req.write( payload_xml ); |
95 | req.end(); | 79 | req.end(); |
96 | } | 80 | } |
97 | 81 | ||
98 | function directResponseHandler(body, request_id) { | 82 | function directResponseHandler(body, request_id) { |
99 | xml2js(body, function (err, result) { | 83 | xml2js(body, function (err, result) { |
100 | if (err) { | 84 | if (err) { |
101 | console.log(body); | 85 | console.log(body); |
102 | callbackReport(request_id, '40', buffer); | 86 | callbackReport(request_id, '40', buffer); |
103 | return; | 87 | return; |
104 | } | 88 | } |
105 | console.log(result); | 89 | console.log(result); |
106 | 90 | ||
107 | var response_code = '68'; | 91 | var response_code = '68'; |
108 | 92 | ||
109 | var request_id = result.pulsamatic.partner_trxid[0].trim(); | 93 | var request_id = result.pulsamatic.partner_trxid[0].trim(); |
110 | var message = result.pulsamatic.message[0].trim(); | 94 | var message = result.pulsamatic.message[0].trim(); |
111 | 95 | ||
112 | callbackReport(request_id, response_code, message); | 96 | callbackReport(request_id, response_code, message); |
113 | }); | 97 | }); |
114 | 98 | ||
115 | } | 99 | } |
116 | 100 | ||
117 | function topupResponseHandler(body, request_id) { | ||
118 | console.log(body); | ||
119 | return; | ||
120 | xml2js(body, function (err, result) { | ||
121 | if (err) { | ||
122 | console.log(body); | ||
123 | callbackReport(request_id, '40', buffer); | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | console.log(result); | ||
128 | |||
129 | request_id = result.datacell.ref_trxid[0].trim(); | ||
130 | |||
131 | var response_code = '68'; | ||
132 | |||
133 | var message = ''; | ||
134 | try { | ||
135 | if (result.datacell.message && result.datacell.message.length > 0) { | ||
136 | message = result.datacell.message[0].trim(); | ||
137 | } else if (result.datacell.msg && result.datacell.msg.length > 0) { | ||
138 | message = result.datacell.msg[0].trim(); | ||
139 | } | ||
140 | } | ||
141 | catch(err) { | ||
142 | message = 'exception saat parsing message'; | ||
143 | } | ||
144 | |||
145 | if (result.datacell.resultcode && result.datacell.resultcode[0] == '999') { | ||
146 | response_code = '40'; | ||
147 | } | ||
148 | |||
149 | if (message.indexOf('Nomor tujuan salah') >= 0) { | ||
150 | response_code = '14'; | ||
151 | } else if (message.indexOf('*GAGAL, transaksi yang sama sudah ada dalam 10 menit') >= 0) { | ||
152 | response_code = '55'; | ||
153 | } else if (message.indexOf('saldo sdh dikembalikan') >= 0) { | ||
154 | response_code = '40' | ||
155 | } else if (message.indexOf('Trx dpt diulang') >= 0) { | ||
156 | response_code = '40' | ||
157 | } else if (message.indexOf('SUKSES SN Operator:') >= 0) { | ||
158 | response_code = '00'; | ||
159 | |||
160 | var sn = parseSN(message); | ||
161 | console.log ('SN Operator: ' + sn); | ||
162 | |||
163 | if (sn) { | ||
164 | message = 'SN=' + sn + '; ' + message; | ||
165 | } else { | ||
166 | message = 'SN belum didapat. ' + message; | ||
167 | response_code = '68'; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | |||
172 | var price = priceFromMessage(message); | ||
173 | if (price != null) { | ||
174 | console.log('Harga: ' + price); | ||
175 | trx_prices[request_id] = price; | ||
176 | setTimeout(deleteTrxPrice, 3 * 24 * 3600 * 1000, request_id); | ||
177 | } else if (response_code == '00' && trx_prices[request_id] !== undefined) { | ||
178 | price = trx_prices[request_id]; | ||
179 | console.log('Harga: ' + price); | ||
180 | message = message + ' -- Harga: ' + price; | ||
181 | } | ||
182 | |||
183 | var balance = balanceFromMessage(message); | ||
184 | if (balance != null) { | ||
185 | console.log('Saldo: ' + balance); | ||
186 | trx_balances[request_id] = balance; | ||
187 | setTimeout(deleteTrxBalance, 3 * 24 * 3600 * 1000, request_id); | ||
188 | } else if (response_code == '00' && trx_balances[request_id] !== undefined) { | ||
189 | balance = trx_balances[request_id]; | ||
190 | console.log('Saldo: ' + balance); | ||
191 | message = message + ' -- Saldo: ' + balance; | ||
192 | } | ||
193 | |||
194 | callbackReport(request_id, response_code, message); | ||
195 | }); | ||
196 | } | ||
197 | |||
198 | function deleteTrxPrice(request_id) { | ||
199 | delete trx_prices[request_id]; | ||
200 | } | ||
201 | |||
202 | function deleteTrxBalance(request_id) { | ||
203 | delete trx_balances[request_id]; | ||
204 | } | ||
205 | |||
206 | function parseSN(message) { | ||
207 | var results = message.match(/SN Operator: .+ SN Kami/); | ||
208 | if (!results || results.length <= 0) { | ||
209 | return ''; | ||
210 | } | ||
211 | |||
212 | var result = results[0]; | ||
213 | result = result.replace('SN Operator:', ''); | ||
214 | result = result.replace('SN Kami', ''); | ||
215 | result = result.trim(); | ||
216 | |||
217 | if (result == '00') { | ||
218 | result = ''; | ||
219 | } | ||
220 | |||
221 | return result; | ||
222 | } | ||
223 | |||
224 | function createServer() { | 101 | function createServer() { |
225 | 102 | ||
226 | var httpServer = http.createServer(function(req, res) { | 103 | var httpServer = http.createServer(function(req, res) { |
227 | //console.log('Got request from partner ("' + req.url + '")'); | 104 | //console.log('Got request from partner ("' + req.url + '")'); |
228 | 105 | ||
229 | res.end('OK'); | 106 | res.end('OK'); |
230 | 107 | ||
231 | var qs = url.parse(req.url, true).query; | 108 | var qs = url.parse(req.url, true).query; |
232 | console.log(qs); | 109 | console.log(qs); |
233 | 110 | ||
234 | var response_code = '68'; | 111 | var response_code = '68'; |
235 | var request_id = qs.pid; | 112 | var request_id = qs.pid; |
236 | var message = qs.msg; | 113 | var message = qs.msg; |
237 | 114 | ||
238 | if (message.indexOf('REFUND') >= 0) { | 115 | if (message.indexOf('REFUND') >= 0) { |
239 | response_code = '40'; | 116 | response_code = '40'; |
240 | } | 117 | } |
241 | 118 | ||
242 | callbackReport(request_id, response_code, message); | 119 | callbackReport(request_id, response_code, message); |
243 | }); | 120 | }); |
244 | 121 | ||
245 | httpServer.listen(config.h2h_out.listen_port, function() { | 122 | httpServer.listen(config.h2h_out.listen_port, function() { |
246 | console.log('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); | 123 | console.log('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); |
247 | }); | 124 | }); |
248 | } | 125 | } |
249 | 126 | ||
250 | function balanceCheck() { | ||
251 | var timestamp = strftime('%H%M%S'); | ||
252 | |||
253 | var payload = { | ||
254 | datacell: [ | ||
255 | {perintah: 'saldo'}, | ||
256 | {userid: config.h2h_out.userid}, | ||
257 | {time: timestamp}, | ||
258 | {sgn: calculateBalanceSignature(config.h2h_out.userid, config.h2h_out.password, timestamp)} | ||
259 | ] | ||
260 | }; | ||
261 | |||
262 | var postRequest = { | ||
263 | host: "202.152.62.2", | ||
264 | path: "/RELOAD97.php", | ||
265 | port: 7713, | ||
266 | method: "POST", | ||
267 | headers: { | ||
268 | 'Content-Type': 'text/xml', | ||
269 | 'Content-Length': Buffer.byteLength(payload_xml) | ||
270 | } | ||
271 | }; | ||
272 | |||
273 | var buffer = ""; | ||
274 | var req = http.request( postRequest, function( res ) { | ||
275 | |||
276 | console.log('Status code: ' + res.statusCode ); | ||
277 | var buffer = ""; | ||
278 | res.on( "data", function( data ) { buffer = buffer + data; } ); | ||
279 | res.on( "end", function( data ) { | ||
280 | console.log('CHECK BALANCE RESULT:'); | ||
281 | console.log(buffer); | ||
282 | }); | ||
283 | |||
284 | }); | ||
285 | |||
286 | req.on('error', function(e) { | ||
287 | console.log('problem with request: ' + e.message); | ||
288 | }); | ||
289 | |||
290 | req.write( payload_xml ); | ||
291 | req.end(); | ||
292 | |||
293 | } | ||
294 | |||
295 | function balanceFromMessage(message) { | ||
296 | var matches = message.match(/Saldo: Rp (\d+)/); | ||
297 | |||
298 | if (!matches) { | ||
299 | return null; | ||
300 | } | ||
301 | if (matches.length < 2) { | ||
302 | return null; | ||
303 | } | ||
304 | |||
305 | return matches[1]; | ||
306 | } | ||
307 | |||
308 | function priceFromMessage(message) { | ||
309 | var matches = message.match(/Harga: (\d+)/); | ||
310 | |||
311 | if (!matches) { | ||
312 | return null; | ||
313 | } | ||
314 | if (matches.length < 2) { | ||
315 | return null; | ||
316 | } | ||
317 | |||
318 | return matches[1]; | ||
319 | } | ||
320 | |||
321 | function start(_config, _callbackReport) { | 127 | function start(_config, _callbackReport) { |
322 | config = _config; | 128 | config = _config; |
323 | callbackReport = _callbackReport | 129 | callbackReport = _callbackReport |
324 | 130 | ||
325 | createServer(); | 131 | createServer(); |
326 | } | 132 | } |
327 | 133 | ||
328 | exports.start = start; | 134 | exports.start = start; |
329 | exports.topupRequest = topupRequest; | 135 | exports.topupRequest = topupRequest; |
330 | exports.balanceFromMessage = balanceFromMessage; | ||
331 | exports.priceFromMessage = priceFromMessage; | ||
332 | exports.calculateSignature = calculateSignature; | 136 | exports.calculateSignature = calculateSignature; |