Commit 76e71b65aa62cb76c26294b4ceb17f9ee59ae08d
1 parent
ed96a98898
Exists in
master
penanganan respon tanpa rc
Showing 1 changed file with 1 additions and 1 deletions Inline Diff
lib/partner.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | const HTTP = require('http'); | 3 | const HTTP = require('http'); |
4 | const URL = require('url'); | 4 | const URL = require('url'); |
5 | const request = require('request'); | 5 | const request = require('request'); |
6 | const uuidv4 = require('uuid/v4'); | 6 | const uuidv4 = require('uuid/v4'); |
7 | 7 | ||
8 | const config = require('komodo-sdk/config'); | 8 | const config = require('komodo-sdk/config'); |
9 | const logger = require('komodo-sdk/logger'); | 9 | const logger = require('komodo-sdk/logger'); |
10 | const matrix = require('komodo-sdk/matrix'); | 10 | const matrix = require('komodo-sdk/matrix'); |
11 | const pull = require('komodo-sdk/gateway/pull'); | 11 | const pull = require('komodo-sdk/gateway/pull'); |
12 | 12 | ||
13 | const komodoClient = require('./komodo-client'); | 13 | const komodoClient = require('./komodo-client'); |
14 | const partnerRc = require('./komodo-rc'); | 14 | const partnerRc = require('./komodo-rc'); |
15 | 15 | ||
16 | if (!matrix.pending_tasks) { | 16 | if (!matrix.pending_tasks) { |
17 | matrix.pending_tasks = {}; | 17 | matrix.pending_tasks = {}; |
18 | } | 18 | } |
19 | 19 | ||
20 | function deleteFromPendingTasks(trx_id) { | 20 | function deleteFromPendingTasks(trx_id) { |
21 | if (matrix.pending_tasks && matrix.pending_tasks[trx_id]) { | 21 | if (matrix.pending_tasks && matrix.pending_tasks[trx_id]) { |
22 | delete matrix.pending_tasks[trx_id]; | 22 | delete matrix.pending_tasks[trx_id]; |
23 | } | 23 | } |
24 | } | 24 | } |
25 | 25 | ||
26 | function report(data) { | 26 | function report(data) { |
27 | pull.report(data); | 27 | pull.report(data); |
28 | 28 | ||
29 | if (data.rc !== '68' && data.rc !== '96') { | 29 | if (data.rc !== '68' && data.rc !== '96') { |
30 | deleteFromPendingTasks(data.trx_id); | 30 | deleteFromPendingTasks(data.trx_id); |
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | function _hit(task, is_advice) { | 34 | function _hit(task, is_advice) { |
35 | 35 | ||
36 | if (matrix.pending_tasks && !matrix.pending_tasks[task.trx_id]) { | 36 | if (matrix.pending_tasks && !matrix.pending_tasks[task.trx_id]) { |
37 | matrix.pending_tasks[task.trx_id] = task; | 37 | matrix.pending_tasks[task.trx_id] = task; |
38 | } | 38 | } |
39 | 39 | ||
40 | const request_options = { | 40 | const request_options = { |
41 | url: config.partner.url, | 41 | url: config.partner.url, |
42 | qs: { | 42 | qs: { |
43 | request_id: task.trx_id, | 43 | request_id: task.trx_id, |
44 | terminal_name: config.partner.terminal_name || config.partner.username, | 44 | terminal_name: config.partner.terminal_name || config.partner.username, |
45 | password: config.partner.password, | 45 | password: config.partner.password, |
46 | reverse_url: config.reverse_report_url, | 46 | reverse_url: config.reverse_report_url, |
47 | product_name: task.remote_product, | 47 | product_name: task.remote_product, |
48 | destination: task.destination | 48 | destination: task.destination |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | if (!request_options.qs.request_id || !request_options.qs.terminal_name || !request_options.qs.password || !request_options.qs.reverse_url || !request_options.qs.product_name || !request_options.qs.destination) { | 52 | if (!request_options.qs.request_id || !request_options.qs.terminal_name || !request_options.qs.password || !request_options.qs.reverse_url || !request_options.qs.product_name || !request_options.qs.destination) { |
53 | logger.verbose('Missing parameter on request', request_options.qs); | 53 | logger.verbose('Missing parameter on request', request_options.qs); |
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | 56 | ||
57 | logger.info('Requesting to partner', {is_advice: is_advice, trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); | 57 | logger.info('Requesting to partner', {is_advice: is_advice, trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); |
58 | request(request_options, function(err, res, body) { | 58 | request(request_options, function(err, res, body) { |
59 | if (err) { | 59 | if (err) { |
60 | logger.warn('Error requesting to partner', {err: err, trx_id: task.trx_id, destination: task.destination, is_advice: is_advice}); | 60 | logger.warn('Error requesting to partner', {err: err, trx_id: task.trx_id, destination: task.destination, is_advice: is_advice}); |
61 | report({ | 61 | report({ |
62 | trx_id: task.trx_id, | 62 | trx_id: task.trx_id, |
63 | rc: (!is_advice && (err.syscall === 'connect')) ? '91' : '68', | 63 | rc: (!is_advice && (err.syscall === 'connect')) ? '91' : '68', |
64 | message: 'INTERNAL: REQUEST ERROR: ' + err.toString(), | 64 | message: 'INTERNAL: REQUEST ERROR: ' + err.toString(), |
65 | misc: { | 65 | misc: { |
66 | task: task | 66 | task: task |
67 | } | 67 | } |
68 | }); | 68 | }); |
69 | return; | 69 | return; |
70 | } | 70 | } |
71 | 71 | ||
72 | if (res.statusCode != 200) { | 72 | if (res.statusCode != 200) { |
73 | logger.warn('Partner returning non 200 HTTP status code', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, http_status_code: res.statusCode, response_body: body}); | 73 | logger.warn('Partner returning non 200 HTTP status code', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, http_status_code: res.statusCode, response_body: body}); |
74 | report({ | 74 | report({ |
75 | trx_id: task.trx_id, | 75 | trx_id: task.trx_id, |
76 | rc: '68', | 76 | rc: '68', |
77 | message: ('INTERNAL: Got non 200 HTTP status code: ' + res.statusCode + '\n\n' + body).trim(), | 77 | message: ('INTERNAL: Got non 200 HTTP status code: ' + res.statusCode + '\n\n' + body).trim(), |
78 | raw: body, | 78 | raw: body, |
79 | misc: { | 79 | misc: { |
80 | task: task | 80 | task: task |
81 | } | 81 | } |
82 | }); | 82 | }); |
83 | return; | 83 | return; |
84 | } | 84 | } |
85 | 85 | ||
86 | logger.verbose('Got response from partner', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, response_body: body}); | 86 | logger.verbose('Got response from partner', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, response_body: body}); |
87 | 87 | ||
88 | const result = komodoClient.parseResponse(body); | 88 | const result = komodoClient.parseResponse(body); |
89 | if (!result) { | 89 | if (!result) { |
90 | logger.warn('Partner returning invalid JSON', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, response_body: body}); | 90 | logger.warn('Partner returning invalid JSON', {trx_id: task.trx_id, destination: task.destination, is_advice: is_advice, response_body: body}); |
91 | report({ | 91 | report({ |
92 | trx_id: task.trx_id, | 92 | trx_id: task.trx_id, |
93 | rc: is_advice ? '68' : '90', | 93 | rc: is_advice ? '68' : '90', |
94 | message: 'INTERNAL: Partner return invalid JSON:\n' + body, | 94 | message: 'INTERNAL: Partner return invalid JSON:\n' + body, |
95 | raw: body, | 95 | raw: body, |
96 | misc: { | 96 | misc: { |
97 | task: task | 97 | task: task |
98 | } | 98 | } |
99 | }); | 99 | }); |
100 | return; | 100 | return; |
101 | } | 101 | } |
102 | 102 | ||
103 | report({ | 103 | report({ |
104 | trx_id: task.trx_id, | 104 | trx_id: task.trx_id, |
105 | rc: partnerRc[result.rc] || '40', | 105 | rc: result.rc ? partnerRc[result.rc] || '40' : '68', |
106 | message: result.message, | 106 | message: result.message, |
107 | sn: result.sn, | 107 | sn: result.sn, |
108 | amount: Number(result.amount) || null, | 108 | amount: Number(result.amount) || null, |
109 | balance: Number(result.ending_balance) || null, | 109 | balance: Number(result.ending_balance) || null, |
110 | raw: body, | 110 | raw: body, |
111 | misc: { | 111 | misc: { |
112 | task: task | 112 | task: task |
113 | } | 113 | } |
114 | }); | 114 | }); |
115 | }) | 115 | }) |
116 | } | 116 | } |
117 | 117 | ||
118 | function buy(task) { | 118 | function buy(task) { |
119 | _hit(task, false); | 119 | _hit(task, false); |
120 | } | 120 | } |
121 | 121 | ||
122 | function advice(task) { | 122 | function advice(task) { |
123 | _hit(task, true); | 123 | _hit(task, true); |
124 | } | 124 | } |
125 | 125 | ||
126 | function reverseReportHandler(req, res) { | 126 | function reverseReportHandler(req, res) { |
127 | const report_id = uuidv4(); | 127 | const report_id = uuidv4(); |
128 | 128 | ||
129 | logger.verbose('Incoming reverse report', {report_id: report_id, url: req.url}); | 129 | logger.verbose('Incoming reverse report', {report_id: report_id, url: req.url}); |
130 | res.end('OK'); | 130 | res.end('OK'); |
131 | 131 | ||
132 | const qs = URL.parse(req.url, true).query; | 132 | const qs = URL.parse(req.url, true).query; |
133 | 133 | ||
134 | if (!qs.request_id || !qs.rc) { | 134 | if (!qs.request_id || !qs.rc) { |
135 | logger.verbose('No request_id and rc on reverse report message', {report_id: report_id, url: req.url, qs: qs}); | 135 | logger.verbose('No request_id and rc on reverse report message', {report_id: report_id, url: req.url, qs: qs}); |
136 | return; | 136 | return; |
137 | } | 137 | } |
138 | 138 | ||
139 | const task = { | 139 | const task = { |
140 | trx_id: qs.request_id, | 140 | trx_id: qs.request_id, |
141 | destination: qs.destination, | 141 | destination: qs.destination, |
142 | remote_product: qs.product_name | 142 | remote_product: qs.product_name |
143 | } | 143 | } |
144 | 144 | ||
145 | report({ | 145 | report({ |
146 | trx_id: qs.request_id, | 146 | trx_id: qs.request_id, |
147 | rc: partnerRc[qs.rc] || '40', | 147 | rc: partnerRc[qs.rc] || '40', |
148 | message: qs.message, | 148 | message: qs.message, |
149 | sn: qs.sn, | 149 | sn: qs.sn, |
150 | amount: qs.amount || null, | 150 | amount: qs.amount || null, |
151 | balance: Number(qs.ending_balance) || null, | 151 | balance: Number(qs.ending_balance) || null, |
152 | raw: req.url, | 152 | raw: req.url, |
153 | misc: { | 153 | misc: { |
154 | task: task | 154 | task: task |
155 | } | 155 | } |
156 | }); | 156 | }); |
157 | } | 157 | } |
158 | 158 | ||
159 | function createReverseReportHttpServer() { | 159 | function createReverseReportHttpServer() { |
160 | const http_server = HTTP.createServer(reverseReportHandler); | 160 | const http_server = HTTP.createServer(reverseReportHandler); |
161 | http_server.listen(config.reverse_report_port, function(err) { | 161 | http_server.listen(config.reverse_report_port, function(err) { |
162 | if (err) { | 162 | if (err) { |
163 | logger.warn('Error creating reverse report HTTP server: ' + err.toString()); | 163 | logger.warn('Error creating reverse report HTTP server: ' + err.toString()); |
164 | process.exit(1); | 164 | process.exit(1); |
165 | return; | 165 | return; |
166 | } | 166 | } |
167 | 167 | ||
168 | logger.info('Reverse report HTTP server listening on port ' + config.reverse_report_port); | 168 | logger.info('Reverse report HTTP server listening on port ' + config.reverse_report_port); |
169 | }) | 169 | }) |
170 | } | 170 | } |
171 | 171 | ||
172 | createReverseReportHttpServer(); | 172 | createReverseReportHttpServer(); |
173 | 173 | ||
174 | exports.buy = buy; | 174 | exports.buy = buy; |
175 | exports.advice = advice; | 175 | exports.advice = advice; |
176 | 176 |