Commit 7663b06b6597003abac328272ac2cd7c60e5d81a
1 parent
e79945d73f
Exists in
master
ready to pretest
Showing 2 changed files with 166 additions and 1 deletions Side-by-side Diff
package.json
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git", |
25 | 25 | "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git", |
26 | 26 | "strftime": "^0.9.2", |
27 | - "winston": "^2.2.0" | |
27 | + "winston": "^2.2.0", | |
28 | + "xml2js": "^0.4.16" | |
28 | 29 | } |
29 | 30 | } |
partner-trustlink.js
... | ... | @@ -0,0 +1,164 @@ |
1 | +var winston = require('winston'); | |
2 | +var request = require('request'); | |
3 | +var strftime = require('strftime'); | |
4 | +var url = require('url'); | |
5 | +var xor = require('base64-xor'); | |
6 | +var http = require('http'); | |
7 | +var xml2js = require('xml2js').parseString; | |
8 | + | |
9 | +var max_retry = 3; | |
10 | +var sleep_before_retry = 2000; | |
11 | + | |
12 | +var config; | |
13 | +var callbackReport; | |
14 | +var aaa; | |
15 | +var logger; | |
16 | +var options; | |
17 | + | |
18 | +function start(_config, _callbackReport, options) { | |
19 | + config = _config; | |
20 | + callbackReport = _callbackReport | |
21 | + | |
22 | + if (options && options.aaa) { | |
23 | + aaa = options.aaa; | |
24 | + } | |
25 | + | |
26 | + if (options && options.logger) { | |
27 | + logger = options.logger; | |
28 | + } else { | |
29 | + logger = new winston.Logger({ | |
30 | + transports: [ | |
31 | + new (winston.transports.Console)() | |
32 | + ] | |
33 | + }); | |
34 | + } | |
35 | + | |
36 | + createReverseReportServer(); | |
37 | +} | |
38 | + | |
39 | +function createReverseReportServer() { | |
40 | + var httpServer = http.createServer(onReverseReport).listen(config.h2h_out.listen_port, function() { | |
41 | + logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); | |
42 | + }); | |
43 | +} | |
44 | + | |
45 | +function onReverseReport(req, res) { | |
46 | + res.end('OK'); | |
47 | + | |
48 | + var qs = url.parse(req.url, true).query; | |
49 | + logger.info('Reverse Report', {qs: qs}); | |
50 | +} | |
51 | + | |
52 | +function calculateSignature(ts, destination, password) { | |
53 | + var a = ts + destination.substr(destination.length - 4); | |
54 | + var b = destination.substr(destination.length - 4).split('').reverse().join('') + password; | |
55 | + | |
56 | + return xor.encode(a,b); | |
57 | +} | |
58 | + | |
59 | +function createXmlPayload(task, userid, password) { | |
60 | + var ts = strftime('%H%M%S', new Date()); | |
61 | + | |
62 | + var signature = calculateSignature(ts, task.destination, password); | |
63 | + | |
64 | + var payload = { | |
65 | + evoucher: [ | |
66 | + {command: 'TOPUP'}, | |
67 | + {product: task.remoteProduct}, | |
68 | + {userid: userid}, | |
69 | + {time: ts}, | |
70 | + {msisdn: task.destination}, | |
71 | + {partner_trxid: task.requestId}, | |
72 | + {signature: signature}, | |
73 | + {trxke: 1}, | |
74 | + ] | |
75 | + }; | |
76 | + | |
77 | + if (logger) { | |
78 | + logger.verbose('Generate xml payload', {payload: payload}); | |
79 | + } | |
80 | + | |
81 | + return "<?xml version=\"1.0\" ?>\n" + xml(payload); | |
82 | +} | |
83 | + | |
84 | +function topupRequest(task, retry) { | |
85 | + if (retry === undefined) { | |
86 | + retry = max_retry; | |
87 | + } | |
88 | + | |
89 | + var payload = createXmlPayload(task, config.globals.userid, config.globals.password); | |
90 | + | |
91 | + var partner = url.parse(config.h2h_out.partner); | |
92 | + | |
93 | + var request_options = { | |
94 | + host: partner.hostname, | |
95 | + path: partner.path, | |
96 | + port: partner.port, | |
97 | + method: "POST", | |
98 | + headers: { | |
99 | + 'Content-Type': 'text/xml', | |
100 | + 'Content-Length': Buffer.byteLength(payload) | |
101 | + } | |
102 | + }; | |
103 | + | |
104 | + var buffer = ""; | |
105 | + | |
106 | + logger.info('Requesting to partner', {request_options: request_options}); | |
107 | + | |
108 | + var req = http.request(request_options, function( res ) { | |
109 | + | |
110 | + logger.info('Status code: ' + res.statusCode ); | |
111 | + var buffer = ""; | |
112 | + res.on( "data", function( data ) { buffer = buffer + data; } ); | |
113 | + res.on( "end", function( data ) { | |
114 | + //directResponseHandler(buffer, task); | |
115 | + logger.info('Got direct response from partner', {resp: buffer}); | |
116 | + }); | |
117 | + | |
118 | + }); | |
119 | + | |
120 | + req.on('error', function(e) { | |
121 | + logger.warn('problem with request: ' + e.message); | |
122 | + callbackReport(task.requestId, '68', e.message); | |
123 | + return; | |
124 | + }); | |
125 | + | |
126 | + logger.verbose('Sending payload to partner', {payload: payload}); | |
127 | + req.write( payload ); | |
128 | + req.end(); | |
129 | +} | |
130 | + | |
131 | +function directResponseHandler(body, task) { | |
132 | + | |
133 | + logger.info('Got direct response'); | |
134 | + | |
135 | + xml2js(body, function (err, result) { | |
136 | + if (err) { | |
137 | + logger.warn('Error parsing xml', {body: body}); | |
138 | + callbackReport(request_id, '68', buffer); | |
139 | + return; | |
140 | + } | |
141 | + | |
142 | + logger.info('Direct response parsed', {result: result}); | |
143 | + | |
144 | + var response_code = '68'; | |
145 | + | |
146 | + var request_id = result.evoucher.partner_trxid[0].trim(); | |
147 | + var message = result.evoucher.message[0].trim(); | |
148 | + var status = result.evoucher.result[0].trim(); | |
149 | + | |
150 | + if (status === 'failed') { | |
151 | + response_code = '40'; | |
152 | + | |
153 | + var new_response_code = responseCodeFromMessage(message); | |
154 | + if (new_response_code) { | |
155 | + response_code = new_response_code; | |
156 | + } | |
157 | + | |
158 | + } | |
159 | + | |
160 | + callbackReport(request_id, response_code, message); | |
161 | + }); | |
162 | +} | |
163 | + | |
164 | +export.start = start; |