Commit c5e243b292688ebd12d76587132e08164d9d8728

Authored by Adhidarma Hadiwinoto
1 parent 0dbce6884a
Exists in master

topup jika tidak ada data

Showing 1 changed file with 5 additions and 0 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 /* 155 /*
156 var sn = getSNFromMessage(message); 156 var sn = getSNFromMessage(message);
157 message = 'SN=' + sn + '; ' + message; 157 message = 'SN=' + sn + '; ' + message;
158 */ 158 */
159 159
160 response_code = '68'; 160 response_code = '68';
161 } 161 }
162 else if (message.indexOf('GAGAL') >= 0) { 162 else if (message.indexOf('GAGAL') >= 0) {
163 response_code = '40'; 163 response_code = '40';
164 } 164 }
165 else { 165 else {
166 response_code = '68'; 166 response_code = '68';
167 } 167 }
168 168
169 callbackReport(request_id, response_code, message); 169 callbackReport(request_id, response_code, message);
170 }); 170 });
171 } 171 }
172 172
173 function getSNFromMessage(message) { 173 function getSNFromMessage(message) {
174 try { 174 try {
175 var sn_match = message.match(/SN=(\w+)/); 175 var sn_match = message.match(/SN=(\w+)/);
176 return sn_match[1].trim(); 176 return sn_match[1].trim();
177 } 177 }
178 catch(e) { 178 catch(e) {
179 return; 179 return;
180 } 180 }
181 } 181 }
182 182
183 function topupRequest(task, retry) { 183 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); 184 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) { 185 redisClient.get(key, function(err, data) {
186 if (err) { 186 if (err) {
187 callbackReport(task.requestId, '40', 'Gagal cek anti transaksi duplikat (redis error)'); 187 callbackReport(task.requestId, '40', 'Gagal cek anti transaksi duplikat (redis error)');
188 return; 188 return;
189 } 189 }
190 190
191 if (!data) { 191 if (!data) {
192 logger.verbose('Belum ada trx dengan tujuan dan denom yang sama pada hari ini. Lanjutkan.');
192 193
193 redisClient.set(key, JSON.stringify(task)); 194 redisClient.set(key, JSON.stringify(task));
194 redisClient.expire(key, 3600 * 24 * 2); 195 redisClient.expire(key, 3600 * 24 * 2);
195 196
197 topupRequestHit(task, retry);
198
196 } else { 199 } else {
197 200
198 try { 201 try {
199 var taskOnRedis = JSON.parse(data); 202 var taskOnRedis = JSON.parse(data);
200 if (task.requestId == taskOnRedis.requestId) { 203 if (task.requestId == taskOnRedis.requestId) {
204 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId jg sama. Lanjutkan.')
201 topupRequestHit(task, retry); 205 topupRequestHit(task, retry);
202 } else { 206 } else {
207 logger.verbose('Sudah ada trx dengan tujuan dan denom yg sama, requestId tidak sama. Batalkan.')
203 callbackReport(task.requestId, '55', 'Transaksi duplikat') 208 callbackReport(task.requestId, '55', 'Transaksi duplikat')
204 } 209 }
205 } 210 }
206 catch(errJSONParse) { 211 catch(errJSONParse) {
207 callbackReport(task.requestId, '68', "error parsing json"); 212 callbackReport(task.requestId, '68', "error parsing json");
208 } 213 }
209 } 214 }
210 215
211 }); 216 });
212 } 217 }
213 218
214 function createRedisClient() { 219 function createRedisClient() {
215 try { 220 try {
216 redisClient = redis.createClient(config.globals.redis_port, config.globals.redis_host); 221 redisClient = redis.createClient(config.globals.redis_port, config.globals.redis_host);
217 } catch(err) { 222 } catch(err) {
218 logger.info("Error creating redis client"); 223 logger.info("Error creating redis client");
219 } 224 }
220 } 225 }
221 226
222 exports.start = start; 227 exports.start = start;
223 exports.topupRequest = topupRequest; 228 exports.topupRequest = topupRequest;
224 exports.calculateSignature = calculateSignature; 229 exports.calculateSignature = calculateSignature;
225 230