Commit 4e651067774f61c8628cd8905389269117891ea9

Authored by Adhidarma Hadiwinoto
1 parent c47be51fe8
Exists in master

mulai adaptasi agar bisa tangani selain st24 asli

Showing 3 changed files with 57 additions and 15 deletions Inline Diff

1 "use strict"; 1 "use strict";
2 2
3 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 3 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
4 4
5 const fs = require('fs'); 5 const fs = require('fs');
6 const url = require('url'); 6 const url = require('url');
7 const https = require('https'); 7 const https = require('https');
8 const xmlrpc = require('xmlrpc'); 8 const xmlrpc = require('xmlrpc');
9 9
10 const config = require('komodo-sdk/config'); 10 const config = require('komodo-sdk/config');
11 const logger = require('komodo-sdk/logger'); 11 const logger = require('komodo-sdk/logger');
12 const matrix = require('komodo-sdk/matrix'); 12 const matrix = require('komodo-sdk/matrix');
13 const pull = require('komodo-sdk/gateway/pull'); 13 const pull = require('komodo-sdk/gateway/pull');
14 14
15 const st24 = require('./st24'); 15 const st24 = require('./st24');
16 16
17 const partnerRc = fs.existsSync(__dirname + '/../rc-local.json') ? require('../rc-local.json') : require('./partner-rc.json'); 17 const partnerRc = fs.existsSync(__dirname + '/../rc-local.json') ? require('../rc-local.json') : require('./partner-rc.json');
18 18
19 if (config.partner.use_sslv3) { 19 if (config.partner.use_sslv3) {
20 https.globalAgent.options.secureProtocol = 'SSLv3_method'; 20 https.globalAgent.options.secureProtocol = 'SSLv3_method';
21 } 21 }
22 22
23 function createXmlRpcClient(endpoint) { 23 function createXmlRpcClient(endpoint) {
24 const partnerUrl = url.parse(endpoint); 24 const partnerUrl = url.parse(endpoint);
25 const clientOptions = { 25 const clientOptions = {
26 host: partnerUrl.hostname, 26 host: partnerUrl.hostname,
27 port: partnerUrl.port, 27 port: partnerUrl.port,
28 path: partnerUrl.pathname 28 path: partnerUrl.pathname
29 }; 29 };
30 30
31 logger.verbose('Creating XML-RPC client using ' + partnerUrl.protocol, clientOptions); 31 logger.verbose('Creating XML-RPC client using ' + partnerUrl.protocol, clientOptions);
32 32
33 return (partnerUrl.protocol === 'https:') ? xmlrpc.createSecureClient(clientOptions) : xmlrpc.createClient(clientOptions); 33 return (partnerUrl.protocol === 'https:') ? xmlrpc.createSecureClient(clientOptions) : xmlrpc.createClient(clientOptions);
34 } 34 }
35 35
36 function buy(task) { 36 function buy(task) {
37 _topUpRequest(task);
38 }
39
40 function _topUpRequest(task, isAdvice) {
37 const params = { 41 const params = {
38 MSISDN: config.partner.msisdn || config.partner.userid, 42 MSISDN: config.partner.msisdn || config.partner.userid,
39 REQUESTID: task.trx_id, 43 REQUESTID: task.trx_id,
40 PIN: config.partner.pin || config.partner.password, 44 PIN: config.partner.pin || config.partner.password,
41 NOHP: task.destination, 45 NOHP: task.destination,
42 NOM: task.remote_product 46 NOM: task.remote_product
43 }; 47 };
44 48
45 const xmlrpcMethod = 'topUpRequest'; 49 const xmlrpcMethod = 'topUpRequest';
46 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url}); 50 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url});
47 51
48 const client = createXmlRpcClient(config.partner.url); 52 const client = createXmlRpcClient(config.partner.url);
49 client.methodCall(xmlrpcMethod, [ params ], function (err, value) { 53 client.methodCall(xmlrpcMethod, [ params ], function (err, value) {
50 54
51 if (err) { 55 if (err) {
52 56
53 let msg = 'XMLRPC Client Error: ' + err; 57 let msg = 'XMLRPC Client Error: ' + err;
54 let rc = '68'; 58 let rc = '68';
55 59
56 if ( 60 if (
57 err.code === 'ECONNREFUSED' 61 !isAdvice &&
58 || err.code === 'EHOSTUNREACH' 62 (
59 || (err.code === 'ETIMEDOUT' && err.syscall === "connect") 63 err.code === 'ECONNREFUSED'
60 || (err.code === 'EPROTO' && err.syscall === "write") 64 || err.code === 'EHOSTUNREACH'
65 || (err.code === 'ETIMEDOUT' && err.syscall === "connect")
66 || (err.code === 'EPROTO' && err.syscall === "write")
67 )
61 ) { 68 ) {
62 rc = '91'; 69 rc = '91';
63 } 70 }
64 71
65 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err}); 72 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err});
66 report({ 73 report({
67 trx_id: task.trx_id, 74 trx_id: task.trx_id,
68 rc: rc, 75 rc: rc,
69 message: 'INTERNAL: ' + msg, 76 message: 'INTERNAL: ' + msg,
70 misc: { 77 misc: {
71 task: task 78 task: task
72 } 79 }
73 }); 80 });
74 81
75 if (rc === '68') { 82 if (rc === '68') {
76 setTimeout( 83 setTimeout(
77 function() { advice(task); }, 84 function() { advice(task); },
78 5 * 60 * 1000 85 5 * 60 * 1000
79 ); 86 );
80 } 87 }
81 88
82 return; 89 return;
83 } 90 }
84 91
85 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value}); 92 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value});
86 matrix.last_topupRequest_ack = value; 93 matrix.last_topupRequest_ack = value;
87 94
88 report({ 95 report({
89 trx_id: task.trx_id, 96 trx_id: task.trx_id,
90 rc: partnerRc[value.RESPONSECODE] || '40', 97 rc: partnerRc[value.RESPONSECODE] || '40',
91 message: value.MESSAGE, 98 message: value.MESSAGE,
92 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE), 99 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE),
93 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE), 100 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE),
94 raw: value, 101 raw: value,
95 misc: { 102 misc: {
96 task: task 103 task: task
97 } 104 }
98 }); 105 });
99 }); 106 });
100 } 107 }
101 108
102 function advice(task) { 109 function _topUpInquiry(task) {
103 const params = { 110 const params = {
104 REQUESTID: task.trx_id, 111 REQUESTID: task.trx_id,
105 MSISDN: config.partner.msisdn || config.partner.userid, 112 MSISDN: config.partner.msisdn || config.partner.userid,
106 PIN: config.partner.pin || config.partner.password, 113 PIN: config.partner.pin || config.partner.password,
107 NOHP: task.destination 114 NOHP: task.destination
108 }; 115 };
109 116
110 const xmlrpcMethod = 'topUpInquiry'; 117 const xmlrpcMethod = 'topUpInquiry';
111 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url}); 118 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url});
112 119
113 const client = createXmlRpcClient(config.partner.url); 120 const client = createXmlRpcClient(config.partner.url);
114 client.methodCall(xmlrpcMethod, [ params ], function (err, value) { 121 client.methodCall(xmlrpcMethod, [ params ], function (err, value) {
115 122
116 if (err) { 123 if (err) {
117 124
118 const msg = 'XMLRPC Client Error: ' + err; 125 const msg = 'XMLRPC Client Error: ' + err;
119 126
120 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err}); 127 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err});
121 report({ 128 report({
122 trx_id: task.trx_id, 129 trx_id: task.trx_id,
123 rc: '68', 130 rc: '68',
124 message: 'INTERNAL: ' + msg, 131 message: 'INTERNAL: ' + msg,
125 misc: { 132 misc: {
126 task: task 133 task: task
127 } 134 }
128 }); 135 });
129 136
130 setTimeout(
131 function() { advice(task); },
132 60 * 1000
133 );
134
135 return; 137 return;
136 } 138 }
137 139
138 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value}); 140 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value});
139 //matrix.last_topupRequest_ack = value; 141 //matrix.last_topupRequest_ack = value;
140 142
141 report({ 143 report({
142 trx_id: task.trx_id, 144 trx_id: task.trx_id,
143 rc: partnerRc[value.RESPONSECODE] || '40', 145 rc: partnerRc[value.RESPONSECODE] || '40',
144 message: value.MESSAGE, 146 message: value.MESSAGE,
145 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE), 147 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE),
146 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE), 148 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE),
147 raw: value, 149 raw: value,
148 misc: { 150 misc: {
149 task: task 151 task: task
150 } 152 }
151 }); 153 });
152 }); 154 });
153 } 155 }
154 156
157 function advice(task) {
158 if (config && advice_is_not_allowed) {
159 return;
160 }
161
162 if (config && advice_is_topuprequest) {
163 _topUpRequest(task, true);
164 }
165 else {
166 _topUpInquiry(task);
167 }
168 }
169
155 function report(data) { 170 function report(data) {
156 if (!data) { 171 if (!data) {
157 return; 172 return;
158 } 173 }
159 174
160 matrix.last_report_to_core = data; 175 matrix.last_report_to_core = data;
161 pull.report(data); 176 pull.report(data);
162 } 177 }
1 "use strict"; 1 "use strict";
2 2
3 function extractSnFromMessage(msg) { 3 function extractSnFromMessage(msg, custom_rule) {
4 if (!msg || typeof msg !== 'string') { 4 if (!msg || typeof msg !== 'string') {
5 return; 5 return;
6 } 6 }
7 7
8 let match = msg.match(/^SN=(.*?);/); 8 let pattern;
9 if (!match || match.length < 2) { 9 let pattern_match_idx;
10 return; 10
11 if (custom_rule && custom_rule.pattern) {
12 pattern = custom_rule.pattern;
13 pattern_match_idx = custom_rule.match_idx;
14 }
15 else {
16 pattern = "^SN=(.*?);";
17 pattern_match_idx = 1;
11 } 18 }
12 19
13 return match[1]; 20 const re = new RegExp(pattern);
21 const matches = msg.match(re);
22
23 if (!matches) return;
24
25 if (pattern_match_idx < matches.length) {
26 return matches[pattern_match_idx];
27 } else {
28 return;
29 }
14 } 30 }
15 31
16 function extractPriceFromMsg(msg) { 32 function extractPriceFromMsg(msg) {
17 if (!msg || typeof msg !== 'string') { 33 if (!msg || typeof msg !== 'string') {
18 return; 34 return;
19 } 35 }
20 36
21 let match = msg.match(/\d,HRG=(.*?),ID=/); 37 let match = msg.match(/\d,HRG=(.*?),ID=/);
22 if (!match || match.length < 2) { 38 if (!match || match.length < 2) {
23 return; 39 return;
24 } 40 }
25 41
26 if (!match[1]) { 42 if (!match[1]) {
27 return; 43 return;
28 } 44 }
29 45
30 return parseInt(match[1].replace(/\./g, '')); 46 return parseInt(match[1].replace(/\./g, ''));
31 } 47 }
32 48
33 49
34 exports.extractSnFromMessage = extractSnFromMessage; 50 exports.extractSnFromMessage = extractSnFromMessage;
35 exports.extractPriceFromMsg = extractPriceFromMsg; 51 exports.extractPriceFromMsg = extractPriceFromMsg;
36 52
rc-local.sample.kopnus.json
File was created 1 {
2 "00": "00",
3 "14": "14",
4 "15": "88",
5 "68": "68",
6 "74": "77",
7 "82": "94",
8 "I8": "14",
9 "I9": "14",
10 "A0": "68"
11 }
12