Commit 6df0e4bb8647c1b8ba4568ec25cd8a24aa6d8572

Authored by Adhidarma Hadiwinoto
1 parent 8ec1a4b454
Exists in master

perbaikan test sn

Showing 2 changed files with 5 additions and 3 deletions Inline Diff

1 var winston = require('winston'); 1 var winston = require('winston');
2 var crypto = require('crypto'); 2 var crypto = require('crypto');
3 var xml = require('xml'); 3 var xml = require('xml');
4 var url = require('url'); 4 var url = require('url');
5 var http = require('http'); 5 var http = require('http');
6 var xml2js = require('xml2js').parseString; 6 var xml2js = require('xml2js').parseString;
7 7
8 var config; 8 var config;
9 var callbackReport; 9 var callbackReport;
10 var aaa; 10 var aaa;
11 var logger; 11 var logger;
12 var options; 12 var options;
13 13
14 var maxRetry = 10; 14 var maxRetry = 10;
15 var sleepBeforeRetry = 30; 15 var sleepBeforeRetry = 30;
16 16
17 function start(_config, _callbackReport, options) { 17 function start(_config, _callbackReport, options) {
18 config = _config; 18 config = _config;
19 callbackReport = _callbackReport 19 callbackReport = _callbackReport
20 20
21 if (options && options.aaa) { 21 if (options && options.aaa) {
22 aaa = options.aaa; 22 aaa = options.aaa;
23 } 23 }
24 24
25 if (options && options.logger) { 25 if (options && options.logger) {
26 logger = options.logger; 26 logger = options.logger;
27 } else { 27 } else {
28 logger = new winston.Logger({ 28 logger = new winston.Logger({
29 transports: [ 29 transports: [
30 new (winston.transports.Console)() 30 new (winston.transports.Console)()
31 ] 31 ]
32 }); 32 });
33 } 33 }
34 } 34 }
35 35
36 function calculateSignature(params) { 36 function calculateSignature(params) {
37 var passwordHash = crypto.createHash('sha1').update(params.password).digest().toString('hex'); 37 var passwordHash = crypto.createHash('sha1').update(params.password).digest().toString('hex');
38 var plain = params.trxtype + params.prdcode + params.value + params.msisdn + params.trxid + params.uid + passwordHash; 38 var plain = params.trxtype + params.prdcode + params.value + params.msisdn + params.trxid + params.uid + passwordHash;
39 var signature = crypto.createHash('sha256').update(plain).digest().toString('hex'); 39 var signature = crypto.createHash('sha256').update(plain).digest().toString('hex');
40 40
41 try { 41 try {
42 logger.verbose('Signature calculated', {plain: plain, signature: signature}); 42 logger.verbose('Signature calculated', {plain: plain, signature: signature});
43 } 43 }
44 catch(err) {} 44 catch(err) {}
45 45
46 return signature; 46 return signature;
47 } 47 }
48 48
49 function createXmlPayload(params) { 49 function createXmlPayload(params) {
50 var payload = "<?xml version=\"1.0\" ?>\n" + xml({ 50 var payload = "<?xml version=\"1.0\" ?>\n" + xml({
51 ciwaru: [ 51 ciwaru: [
52 {trxtype: params.trxtype}, 52 {trxtype: params.trxtype},
53 {prdcode: params.prdcode}, 53 {prdcode: params.prdcode},
54 {value: params.value}, 54 {value: params.value},
55 {msisdn: params.msisdn}, 55 {msisdn: params.msisdn},
56 {trxid: params.trxid}, 56 {trxid: params.trxid},
57 {uid: params.uid}, 57 {uid: params.uid},
58 {hash: calculateSignature(params)} 58 {hash: calculateSignature(params)}
59 ] 59 ]
60 }); 60 });
61 61
62 logger.verbose("Payload: " + payload); 62 try { logger.verbose("Payload: " + payload); }
63 catch(errLog) {}
64
63 return payload; 65 return payload;
64 } 66 }
65 67
66 function getSNFromMessage(message) { 68 function getSNFromMessage(message) {
67 try { 69 try {
68 var sn_match = message.match(/SN: (\w+)/); 70 var sn_match = message.match(/SN: (\w+)/);
69 return sn_match[1]; 71 return sn_match[1];
70 } 72 }
71 catch(err) { 73 catch(err) {
72 return ''; 74 return '';
73 } 75 }
74 } 76 }
75 77
76 function hasSuccessKeywords(message) { 78 function hasSuccessKeywords(message) {
77 var keywords = ['SUKSES', 'Finish']; 79 var keywords = ['SUKSES', 'Finish'];
78 80
79 var count = keywords.length; 81 var count = keywords.length;
80 for (var i=0; i < count; i++) { 82 for (var i=0; i < count; i++) {
81 if (message.indexOf(keywords[i]) >= 0) { 83 if (message.indexOf(keywords[i]) >= 0) {
82 return true; 84 return true;
83 } 85 }
84 } 86 }
85 return false; 87 return false;
86 } 88 }
87 89
88 function supplierRcToST24Rc(rc) { 90 function supplierRcToST24Rc(rc) {
89 var rcs = { 91 var rcs = {
90 '0001': '40', 92 '0001': '40',
91 '0019': '13', // produk tidak tersedia 93 '0019': '13', // produk tidak tersedia
92 } 94 }
93 95
94 if (rcs[rc]) { 96 if (rcs[rc]) {
95 return rcs[rc]; 97 return rcs[rc];
96 } else { 98 } else {
97 return; 99 return;
98 } 100 }
99 } 101 }
100 102
101 function topupResponseHandler(body, task) { 103 function topupResponseHandler(body, task) {
102 //logger.info('Got reply from partner', {body: body}); 104 //logger.info('Got reply from partner', {body: body});
103 xml2js(body, function(err, result) { 105 xml2js(body, function(err, result) {
104 if (err) { 106 if (err) {
105 logger.warn('Got invalid XML from partner', {err: err, body: body, task: task}); 107 logger.warn('Got invalid XML from partner', {err: err, body: body, task: task});
106 } 108 }
107 logger.info('XML message from partner', {result: result}); 109 logger.info('XML message from partner', {result: result});
108 110
109 var rc = '68'; 111 var rc = '68';
110 var message = result.ciwaru.msg[0]; 112 var message = result.ciwaru.msg[0];
111 113
112 var trxid = 0; 114 var trxid = 0;
113 try { 115 try {
114 trxid = result.ciwaru.reqnum[0]; 116 trxid = result.ciwaru.reqnum[0];
115 } 117 }
116 catch(err) { 118 catch(err) {
117 trxid = result.ciwaru.trxid[0]; 119 trxid = result.ciwaru.trxid[0];
118 } 120 }
119 121
120 if (message.toUpperCase().indexOf('PENDING') >= 0) { 122 if (message.toUpperCase().indexOf('PENDING') >= 0) {
121 rc = '68'; 123 rc = '68';
122 } 124 }
123 else if (hasSuccessKeywords(message)) { 125 else if (hasSuccessKeywords(message)) {
124 var sn = getSNFromMessage(result.ciwaru.msg); 126 var sn = getSNFromMessage(result.ciwaru.msg);
125 message = 'SN=' + sn + '; ' + message; 127 message = 'SN=' + sn + '; ' + message;
126 rc = '00'; 128 rc = '00';
127 } else { 129 } else {
128 rc = supplierRcToST24Rc(result.ciwaru.rc[0]); 130 rc = supplierRcToST24Rc(result.ciwaru.rc[0]);
129 if (!rc) { 131 if (!rc) {
130 rc = '68'; 132 rc = '68';
131 } 133 }
132 } 134 }
133 135
134 if ((task.retry == maxRetry) || (rc != '68')) { 136 if ((task.retry == maxRetry) || (rc != '68')) {
135 callbackReport(trxid, rc, message); 137 callbackReport(trxid, rc, message);
136 } else { 138 } else {
137 logger.info('Not reporting to AAA for duplicate 68', {task: task}); 139 logger.info('Not reporting to AAA for duplicate 68', {task: task});
138 } 140 }
139 141
140 if (rc == '68') { 142 if (rc == '68') {
141 task.retry--; 143 task.retry--;
142 144
143 if (task.retry) { 145 if (task.retry) {
144 logger.info('Got pending status, retrying in ' + sleepBeforeRetry + 's'); 146 logger.info('Got pending status, retrying in ' + sleepBeforeRetry + 's');
145 setTimeout(topupRequest, sleepBeforeRetry * 1000, task, task.retry); 147 setTimeout(topupRequest, sleepBeforeRetry * 1000, task, task.retry);
146 } 148 }
147 else { 149 else {
148 logger.warn('Maximum retry for pending status exceeded', {task: task}); 150 logger.warn('Maximum retry for pending status exceeded', {task: task});
149 } 151 }
150 } 152 }
151 }); 153 });
152 } 154 }
153 155
154 function topupRequest(task, retry) { 156 function topupRequest(task, retry) {
155 157
156 if (retry === undefined) { 158 if (retry === undefined) {
157 task.retry = maxRetry; 159 task.retry = maxRetry;
158 } 160 }
159 161
160 var remoteProduct = task.remoteProduct.split(','); 162 var remoteProduct = task.remoteProduct.split(',');
161 163
162 var params = { 164 var params = {
163 trxtype: '01', 165 trxtype: '01',
164 prdcode: remoteProduct[0], 166 prdcode: remoteProduct[0],
165 value: remoteProduct[1], 167 value: remoteProduct[1],
166 msisdn: task.destination, 168 msisdn: task.destination,
167 trxid: task.requestId, 169 trxid: task.requestId,
168 uid: config.h2h_out.userid, 170 uid: config.h2h_out.userid,
169 password: config.h2h_out.password, 171 password: config.h2h_out.password,
170 }; 172 };
171 173
172 var postBody = createXmlPayload(params); 174 var postBody = createXmlPayload(params);
173 175
174 var partnerUrl = url.parse(config.h2h_out.partner); 176 var partnerUrl = url.parse(config.h2h_out.partner);
175 var postRequest = { 177 var postRequest = {
176 host: partnerUrl.hostname, 178 host: partnerUrl.hostname,
177 path: partnerUrl.path, 179 path: partnerUrl.path,
178 port: partnerUrl.port, 180 port: partnerUrl.port,
179 method: "POST", 181 method: "POST",
180 headers: { 182 headers: {
181 'Content-Type': 'text/xml', 183 'Content-Type': 'text/xml',
182 'Content-Length': Buffer.byteLength(postBody) 184 'Content-Length': Buffer.byteLength(postBody)
183 } 185 }
184 }; 186 };
185 187
186 logger.info('POST to partner', {postRequest: postRequest}); 188 logger.info('POST to partner', {postRequest: postRequest});
187 var req = http.request(postRequest, function( res ) { 189 var req = http.request(postRequest, function( res ) {
188 190
189 logger.info('Status code: ' + res.statusCode ); 191 logger.info('Status code: ' + res.statusCode );
190 var buffer = ""; 192 var buffer = "";
191 res.on( "data", function( data ) { buffer = buffer + data; } ); 193 res.on( "data", function( data ) { buffer = buffer + data; } );
192 res.on( "end", function( data ) { 194 res.on( "end", function( data ) {
193 topupResponseHandler(buffer, task); 195 topupResponseHandler(buffer, task);
194 }); 196 });
195 }); 197 });
196 198
197 req.on('error', function(e) { 199 req.on('error', function(e) {
198 logger.warn('problem with request: ' + e.message); 200 logger.warn('problem with request: ' + e.message);
199 callbackReport(task['requestId'], '40', e.message); 201 callbackReport(task['requestId'], '40', e.message);
200 }); 202 });
201 203
202 req.write(postBody); 204 req.write(postBody);
203 req.end(); 205 req.end();
204 } 206 }
205 207
206 exports.start = start; 208 exports.start = start;
207 exports.topupRequest = topupRequest; 209 exports.topupRequest = topupRequest;
208 exports.calculateSignature = calculateSignature; 210 exports.calculateSignature = calculateSignature;
209 exports.createXmlPayload = createXmlPayload; 211 exports.createXmlPayload = createXmlPayload;
210 exports.getSNFromMessage = getSNFromMessage; 212 exports.getSNFromMessage = getSNFromMessage;
211 213
1 var should = require("should"); 1 var should = require("should");
2 var partner = require("./partner-cjk"); 2 var partner = require("./partner-cjk");
3 3
4 describe("#partner-cjk", function() { 4 describe("#partner-cjk", function() {
5 var params = { 5 var params = {
6 trxtype: '01', 6 trxtype: '01',
7 prdcode: 'PU1TS10', 7 prdcode: 'PU1TS10',
8 value: '10000', 8 value: '10000',
9 msisdn: '082129777024', 9 msisdn: '082129777024',
10 trxid: '1237', 10 trxid: '1237',
11 uid: '082129777025', 11 uid: '082129777025',
12 password: '1234', 12 password: '1234',
13 }; 13 };
14 14
15 describe("#createSign", function() { 15 describe("#createSign", function() {
16 it('should return correct sign', function() { 16 it('should return correct sign', function() {
17 partner.calculateSignature(params).should.equal('93f3fbed4f4567ba1e10f2d0a0485c7c0d2254b1cb519ae51e533d7111cb6f8b'); 17 partner.calculateSignature(params).should.equal('93f3fbed4f4567ba1e10f2d0a0485c7c0d2254b1cb519ae51e533d7111cb6f8b');
18 }); 18 });
19 }); 19 });
20 20
21 describe('#createXmlPayload', function() { 21 describe('#createXmlPayload', function() {
22 it('should return correct xml', function() { 22 it('should return correct xml', function() {
23 partner.createXmlPayload(params).should.equal('<?xml version="1.0" ?>\n<ciwaru><trxtype>01</trxtype><prdcode>PU1TS10</prdcode><value>10000</value><msisdn>082129777024</msisdn><trxid>1237</trxid><uid>082129777025</uid><hash>93f3fbed4f4567ba1e10f2d0a0485c7c0d2254b1cb519ae51e533d7111cb6f8b</hash></ciwaru>'); 23 partner.createXmlPayload(params).should.equal('<?xml version="1.0" ?>\n<ciwaru><trxtype>01</trxtype><prdcode>PU1TS10</prdcode><value>10000</value><msisdn>082129777024</msisdn><trxid>1237</trxid><uid>082129777025</uid><hash>93f3fbed4f4567ba1e10f2d0a0485c7c0d2254b1cb519ae51e533d7111cb6f8b</hash></ciwaru>');
24 }); 24 });
25 }); 25 });
26 26
27 describe('#getSNFromMessage', function() { 27 describe('#getSNFromMessage', function() {
28 it('should return correct sn', function() { 28 it('should return correct sn', function() {
29 var message = '2014-­09-­16 01:40:10: SUKSES Topup ke 082129777024 sebesar 20000 dengan SN 0031000529115447 harga = 20056; Saldo = 221.492'; 29 var message = '2016-05-04 10:15:50: SUKSES Topup Ke 081905851012 Sebesar 5.000 Dengan SN: 100008530070 Harga = 5.612. Saldo = 475.972';
30 partner.getSNFromMessage(message).should.equal('0031000529115447'); 30 partner.getSNFromMessage(message).should.equal('100008530070');
31 }); 31 });
32 }); 32 });
33 }); 33 });
34 34