Commit 9b181554eaa22a99b0039b5a028934e323eefc18

Authored by Adhidarma Hadiwinoto
1 parent c5e243b292
Exists in master

Sukses 00

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

partner-trustlink.js
1 var winston = require('winston'); 1 var winston = require('winston');
2 var request = require('request'); 2 var request = require('request');
3 var strftime = require('strftime'); 3 var strftime = require('strftime');
4 var url = require('url'); 4 var url = require('url');
5 var xor = require('base64-xor'); 5 var xor = require('base64-xor');
6 var http = require('http'); 6 var http = require('http');
7 var xml = require('xml'); 7 var xml = require('xml');
8 var xml2js = require('xml2js').parseString; 8 var xml2js = require('xml2js').parseString;
9 var redis = require('redis'); 9 var redis = require('redis');
10 10
11 var max_retry = 0; 11 var max_retry = 0;
12 var sleep_before_retry = 2000; 12 var sleep_before_retry = 2000;
13 13
14 var config; 14 var config;
15 var callbackReport; 15 var callbackReport;
16 var aaa; 16 var aaa;
17 var logger; 17 var logger;
18 var options; 18 var options;
19 var redisClient; 19 var redisClient;
20 20
21 function start(_config, _callbackReport, options) { 21 function start(_config, _callbackReport, options) {
22 config = _config; 22 config = _config;
23 callbackReport = _callbackReport 23 callbackReport = _callbackReport
24 24
25 if (options && options.aaa) { 25 if (options && options.aaa) {
26 aaa = options.aaa; 26 aaa = options.aaa;
27 } 27 }
28 28
29 if (options && options.logger) { 29 if (options && options.logger) {
30 logger = options.logger; 30 logger = options.logger;
31 } else { 31 } else {
32 logger = new winston.Logger({ 32 logger = new winston.Logger({
33 transports: [ 33 transports: [
34 new (winston.transports.Console)() 34 new (winston.transports.Console)()
35 ] 35 ]
36 }); 36 });
37 } 37 }
38 38
39 createRedisClient(); 39 createRedisClient();
40 createReverseReportServer(); 40 createReverseReportServer();
41 } 41 }
42 42
43 function createReverseReportServer() { 43 function createReverseReportServer() {
44 var httpServer = http.createServer(onReverseReport).listen(config.h2h_out.listen_port, function() { 44 var httpServer = http.createServer(onReverseReport).listen(config.h2h_out.listen_port, function() {
45 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); 45 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
46 }); 46 });
47 } 47 }
48 48
49 function onReverseReport(req, res) { 49 function onReverseReport(req, res) {
50 res.end('OK'); 50 res.end('OK');
51 51
52 var qs = url.parse(req.url, true).query; 52 var qs = url.parse(req.url, true).query;
53 logger.info('Reverse Report', {qs: qs}); 53 logger.info('Reverse Report', {qs: qs});
54 } 54 }
55 55
56 function calculateSignature(ts, destination, password) { 56 function calculateSignature(ts, destination, password) {
57 var a = ts + destination.substr(destination.length - 4); 57 var a = ts + destination.substr(destination.length - 4);
58 var b = destination.substr(destination.length - 4).split('').reverse().join('') + password; 58 var b = destination.substr(destination.length - 4).split('').reverse().join('') + password;
59 59
60 return xor.encode(a,b); 60 return xor.encode(a,b);
61 } 61 }
62 62
63 function createXmlPayload(task, userid, password) { 63 function createXmlPayload(task, userid, password) {
64 var ts = strftime('%H%M%S', new Date()); 64 var ts = strftime('%H%M%S', new Date());
65 65
66 var signature = calculateSignature(ts, task.destination, password); 66 var signature = calculateSignature(ts, task.destination, password);
67 67
68 var payload = { 68 var payload = {
69 evoucher: [ 69 evoucher: [
70 {command: 'TOPUP'}, 70 {command: 'TOPUP'},
71 {product: task.remoteProduct}, 71 {product: task.remoteProduct},
72 {userid: userid}, 72 {userid: userid},
73 {time: ts}, 73 {time: ts},
74 {msisdn: task.destination}, 74 {msisdn: task.destination},
75 {partner_trxid: task.requestId}, 75 {partner_trxid: task.requestId},
76 {signature: signature}, 76 {signature: signature},
77 {trxke: 1}, 77 {trxke: 1},
78 ] 78 ]
79 }; 79 };
80 80
81 if (logger) { 81 if (logger) {
82 logger.verbose('Generate xml payload', {payload: payload}); 82 logger.verbose('Generate xml payload', {payload: payload});
83 } 83 }
84 84
85 return "<?xml version=\"1.0\" ?>\n" + xml(payload); 85 return "<?xml version=\"1.0\" ?>\n" + xml(payload);
86 } 86 }
87 87
88 function topupRequestHit(task, retry) { 88 function topupRequestHit(task, retry) {
89 if (retry === undefined) { 89 if (retry === undefined) {
90 retry = max_retry; 90 retry = max_retry;
91 } 91 }
92 92
93 var payload = createXmlPayload(task, config.h2h_out.userid, config.h2h_out.password); 93 var payload = createXmlPayload(task, config.h2h_out.userid, config.h2h_out.password);
94 94
95 var partner = url.parse(config.h2h_out.partner); 95 var partner = url.parse(config.h2h_out.partner);
96 96
97 var request_options = { 97 var request_options = {
98 host: partner.hostname, 98 host: partner.hostname,
99 path: partner.path, 99 path: partner.path,
100 port: partner.port, 100 port: partner.port,
101 method: "POST", 101 method: "POST",
102 headers: { 102 headers: {
103 'Content-Type': 'text/xml', 103 'Content-Type': 'text/xml',
104 'Content-Length': Buffer.byteLength(payload) 104 'Content-Length': Buffer.byteLength(payload)
105 } 105 }
106 }; 106 };
107 107
108 var buffer = ""; 108 var buffer = "";
109 109
110 logger.info('Requesting to partner', {request_options: request_options}); 110 logger.info('Requesting to partner', {request_options: request_options});
111 111
112 var req = http.request(request_options, function( res ) { 112 var req = http.request(request_options, function( res ) {
113 113
114 logger.verbose('Status code: ' + res.statusCode ); 114 logger.verbose('Status code: ' + res.statusCode );
115 var buffer = ""; 115 var buffer = "";
116 res.on( "data", function( data ) { buffer = buffer + data; } ); 116 res.on( "data", function( data ) { buffer = buffer + data; } );
117 res.on( "end", function( data ) { 117 res.on( "end", function( data ) {
118 logger.verbose('Got direct response from partner', {resp: buffer}); 118 logger.verbose('Got direct response from partner', {resp: buffer});
119 directResponseHandler(buffer, task); 119 directResponseHandler(buffer, task);
120 }); 120 });
121 121
122 }); 122 });
123 123
124 req.on('error', function(e) { 124 req.on('error', function(e) {
125 logger.warn('problem with request: ' + e.message); 125 logger.warn('problem with request: ' + e.message);
126 callbackReport(task.requestId, '68', e.message); 126 callbackReport(task.requestId, '68', e.message);
127 return; 127 return;
128 }); 128 });
129 129
130 logger.verbose('Sending payload to partner', {payload: payload}); 130 logger.verbose('Sending payload to partner', {payload: payload});
131 req.write( payload ); 131 req.write( payload );
132 req.end(); 132 req.end();
133 } 133 }
134 134
135 function directResponseHandler(body, task) { 135 function directResponseHandler(body, task) {
136 136
137 logger.info('Got direct response'); 137 logger.info('Got direct response');
138 138
139 xml2js(body, function (err, result) { 139 xml2js(body, function (err, result) {
140 if (err) { 140 if (err) {
141 logger.warn('Error parsing xml', {body: body}); 141 logger.warn('Error parsing xml', {body: body});
142 callbackReport(task.requestId, '68', buffer); 142 callbackReport(task.requestId, '68', buffer);
143 return; 143 return;
144 } 144 }
145 145
146 logger.info('Direct response parsed', {result: result}); 146 logger.info('Direct response parsed', {result: result});
147 147
148 var response_code = '68'; 148 var response_code = '68';
149 149
150 var request_id = task.requestId; 150 var request_id = task.requestId;
151 var status = result.evoucher.result[0].trim(); 151 var status = result.evoucher.result[0].trim();
152 var message = result.evoucher.value[0].string[0].trim(); 152 var message = result.evoucher.value[0].string[0].trim();
153 153
154 if (message.indexOf('SUKSES') >= 0) { 154 if (message.indexOf('SUKSES') >= 0) {
155 /*
156 var sn = getSNFromMessage(message); 155 var sn = getSNFromMessage(message);
157 message = 'SN=' + sn + '; ' + message; 156 message = 'SN=' + sn + '; ' + message;
158 */
159 157
160 response_code = '68'; 158 response_code = '00';
161 } 159 }
162 else if (message.indexOf('GAGAL') >= 0) { 160 else if (message.indexOf('GAGAL') >= 0) {
163 response_code = '40'; 161 response_code = '40';
164 } 162 }
165 else { 163 else {
166 response_code = '68'; 164 response_code = '68';
167 } 165 }
168 166
169 callbackReport(request_id, response_code, message); 167 callbackReport(request_id, response_code, message);
170 }); 168 });
171 } 169 }
172 170
173 function getSNFromMessage(message) { 171 function getSNFromMessage(message) {
174 try { 172 try {
175 var sn_match = message.match(/SN=(\w+)/); 173 var sn_match = message.match(/SN=(\w+)/);
176 return sn_match[1].trim(); 174 return sn_match[1].trim();
177 } 175 }
178 catch(e) { 176 catch(e) {
179 return; 177 return;
180 } 178 }
181 } 179 }
182 180
183 function topupRequest(task, retry) { 181 function topupRequest(task, retry) {
184 var key = 'DUPCHECK.gw:' + config.globals.gateway_name + '.prod:' + task.remoteProduct + '.dest:' + task.destination + '.date:' + strftime('%Y%m%d', new Date); 182 var key = 'DUPCHECK.gw:' + config.globals.gateway_name + '.prod:' + task.remoteProduct + '.dest:' + task.destination + '.date:' + strftime('%Y%m%d', new Date);
185 redisClient.get(key, function(err, data) { 183 redisClient.get(key, function(err, data) {
186 if (err) { 184 if (err) {
187 callbackReport(task.requestId, '40', 'Gagal cek anti transaksi duplikat (redis error)'); 185 callbackReport(task.requestId, '40', 'Gagal cek anti transaksi duplikat (redis error)');
188 return; 186 return;
189 } 187 }
190 188
191 if (!data) { 189 if (!data) {
192 logger.verbose('Belum ada trx dengan tujuan dan denom yang sama pada hari ini. Lanjutkan.'); 190 logger.verbose('Belum ada trx dengan tujuan dan denom yang sama pada hari ini. Lanjutkan.');
193 191
194 redisClient.set(key, JSON.stringify(task)); 192 redisClient.set(key, JSON.stringify(task));
195 redisClient.expire(key, 3600 * 24 * 2); 193 redisClient.expire(key, 3600 * 24 * 2);
196 194
197 topupRequestHit(task, retry); 195 topupRequestHit(task, retry);
198 196
199 } else { 197 } else {
200 198
201 try { 199 try {
202 var taskOnRedis = JSON.parse(data); 200 var taskOnRedis = JSON.parse(data);
203 if (task.requestId == taskOnRedis.requestId) { 201 if (task.requestId == taskOnRedis.requestId) {
204 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId jg sama. Lanjutkan.') 202 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId jg sama. Lanjutkan.')
205 topupRequestHit(task, retry); 203 topupRequestHit(task, retry);
206 } else { 204 } else {
207 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId tidak sama. Batalkan.') 205 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId tidak sama. Batalkan.')
208 callbackReport(task.requestId, '55', 'Transaksi duplikat') 206 callbackReport(task.requestId, '55', 'Transaksi duplikat')
209 } 207 }
210 } 208 }
211 catch(errJSONParse) { 209 catch(errJSONParse) {
212 callbackReport(task.requestId, '68', "error parsing json"); 210 callbackReport(task.requestId, '68', "error parsing json");
213 } 211 }
214 } 212 }
215 213
216 }); 214 });
217 } 215 }
218 216
219 function createRedisClient() { 217 function createRedisClient() {
220 try { 218 try {
221 redisClient = redis.createClient(config.globals.redis_port, config.globals.redis_host); 219 redisClient = redis.createClient(config.globals.redis_port, config.globals.redis_host);
222 } catch(err) { 220 } catch(err) {
223 logger.info("Error creating redis client"); 221 logger.info("Error creating redis client");
224 } 222 }
225 } 223 }
226 224
227 exports.start = start; 225 exports.start = start;
228 exports.topupRequest = topupRequest; 226 exports.topupRequest = topupRequest;
229 exports.calculateSignature = calculateSignature; 227 exports.calculateSignature = calculateSignature;
230 228