Commit f1d0d57d61a14499ee94c22943d0ea798ced56d2
1 parent
4e29174c01
Exists in
master
Log on webhook
Showing 2 changed files with 37 additions and 1 deletions Inline Diff
lib/core-callback/sender.js
1 | const MODULE_NAME = 'CORE-CALLBACK.SENDER'; | 1 | const MODULE_NAME = 'CORE-CALLBACK.SENDER'; |
2 | 2 | ||
3 | const axios = require('axios'); | 3 | const axios = require('axios'); |
4 | const config = require('komodo-sdk/config'); | 4 | const config = require('komodo-sdk/config'); |
5 | const logger = require('tektrans-logger'); | 5 | const logger = require('tektrans-logger'); |
6 | 6 | ||
7 | const dumper = require('./dumper/sender'); | 7 | const dumper = require('./dumper/sender'); |
8 | const matrix = require('../matrix'); | 8 | const matrix = require('../matrix'); |
9 | 9 | ||
10 | const HTTP_TIMEOUT = Number( | 10 | const HTTP_TIMEOUT = Number( |
11 | config.callback_sender && config.callback_sender.http_timeout_ms, | 11 | config.callback_sender && config.callback_sender.http_timeout_ms, |
12 | ) || 30 * 1000; | 12 | ) || 30 * 1000; |
13 | 13 | ||
14 | const SLEEP_BEFORE_RETRY_MS = Number( | 14 | const SLEEP_BEFORE_RETRY_MS = Number( |
15 | config.callback_sender && config.callback_sender.sleep_before_retry_ms, | 15 | config.callback_sender && config.callback_sender.sleep_before_retry_ms, |
16 | ) || 10 * 1000; | 16 | ) || 10 * 1000; |
17 | 17 | ||
18 | const MAX_RETRY = Number( | 18 | const MAX_RETRY = Number( |
19 | config.callback_sender && config.callback_sender.max_retry, | 19 | config.callback_sender && config.callback_sender.max_retry, |
20 | ) || 10; | 20 | ) || 10; |
21 | 21 | ||
22 | logger.verbose(`${MODULE_NAME} 848B9104: Initialized`, { | 22 | logger.verbose(`${MODULE_NAME} 848B9104: Initialized`, { |
23 | HTTP_TIMEOUT, | 23 | HTTP_TIMEOUT, |
24 | SLEEP_BEFORE_RETRY_MS, | 24 | SLEEP_BEFORE_RETRY_MS, |
25 | MAX_RETRY, | 25 | MAX_RETRY, |
26 | }); | 26 | }); |
27 | 27 | ||
28 | const axiosHeaders = { | 28 | const axiosHeaders = { |
29 | 'Content-Type': 'application/json', | 29 | 'Content-Type': 'application/json', |
30 | 'User-Agent': 'KOMODO-HTTPGETX callback sender', | 30 | 'User-Agent': 'KOMODO-HTTPGETX callback sender', |
31 | }; | 31 | }; |
32 | 32 | ||
33 | const sleep = require('../sleep'); | 33 | const sleep = require('../sleep'); |
34 | const urlConcatQs = require('../url-concat-qs'); | 34 | const urlConcatQs = require('../url-concat-qs'); |
35 | 35 | ||
36 | const sender = async (data, xid, retry) => { | 36 | const sender = async (data, xid, retry) => { |
37 | if (!data.reverse_url) { | 37 | if (!data.reverse_url) { |
38 | logger.verbose(`${MODULE_NAME} C4FF18FB: Ignoring missing reverse url`, { | 38 | logger.verbose(`${MODULE_NAME} C4FF18FB: Ignoring missing reverse url`, { |
39 | xid, | 39 | xid, |
40 | dataFromCore: data, | 40 | dataFromCore: data, |
41 | }); | 41 | }); |
42 | 42 | ||
43 | return; | 43 | return; |
44 | } | 44 | } |
45 | 45 | ||
46 | const params = { | 46 | const params = { |
47 | httpgetx_xid: xid, | 47 | httpgetx_xid: xid, |
48 | command: data.command, | 48 | command: data.command, |
49 | 49 | ||
50 | request_id: data.request_id && data.request_id.toString(), | 50 | request_id: data.request_id && data.request_id.toString(), |
51 | transaction_id: data.transaction_id && data.transaction_id.toString(), | 51 | transaction_id: data.transaction_id && data.transaction_id.toString(), |
52 | transaction_date: data.transaction_date, | 52 | transaction_date: data.transaction_date, |
53 | 53 | ||
54 | store_name: data.store_name, | 54 | store_name: data.store_name, |
55 | terminal_name: data.terminal_name, | 55 | terminal_name: data.terminal_name, |
56 | 56 | ||
57 | product_name: data.product_name, | 57 | product_name: data.product_name, |
58 | destination: data.destination, | 58 | destination: data.destination, |
59 | 59 | ||
60 | rc: data.rc, | 60 | rc: data.rc, |
61 | sn: data.sn || undefined, | 61 | sn: data.sn || undefined, |
62 | amount: Number(data.amount) || undefined, | 62 | amount: Number(data.amount) || undefined, |
63 | ending_balance: Number(data.ending_balance) || undefined, | 63 | ending_balance: Number(data.ending_balance) || undefined, |
64 | 64 | ||
65 | message: data.message, | 65 | message: data.message, |
66 | 66 | ||
67 | bill_count: Number(data.bill_count) || undefined, | 67 | bill_count: Number(data.bill_count) || undefined, |
68 | bill_amount: Number(data.bill_amount) || undefined, | 68 | bill_amount: Number(data.bill_amount) || undefined, |
69 | fee_per_bill: Number(data.fee) || undefined, | 69 | fee_per_bill: Number(data.fee) || undefined, |
70 | fee_total: Number(data.fee_total) || undefined, | 70 | fee_total: Number(data.fee_total) || undefined, |
71 | 71 | ||
72 | bill_detail: data.bill_detail || undefined, | 72 | bill_detail: data.bill_detail || undefined, |
73 | struk: data.struk || undefined, | 73 | struk: data.struk || undefined, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | if (data.command === 'INQUIRY' && data.amount_to_charge) { | 76 | if (data.command === 'INQUIRY' && data.amount_to_charge) { |
77 | params.amount_to_charge = data.amount_to_charge; | 77 | params.amount_to_charge = data.amount_to_charge; |
78 | } | 78 | } |
79 | 79 | ||
80 | const isPostpaid = ['INQUIRY', 'PAY'].indexOf(data.command) >= 0; | 80 | const isPostpaid = ['INQUIRY', 'PAY'].indexOf(data.command) >= 0; |
81 | const isHttpPost = isPostpaid; | 81 | const isHttpPost = isPostpaid; |
82 | 82 | ||
83 | const endpointUrl = isHttpPost ? data.reverse_url : urlConcatQs(data.reverse_url, params); | 83 | const endpointUrl = isHttpPost ? data.reverse_url : urlConcatQs(data.reverse_url, params); |
84 | 84 | ||
85 | logger.info(`${MODULE_NAME} 8B6A4CEC: Sending to PARTNER`, { | 85 | logger.info(`${MODULE_NAME} 8B6A4CEC: Sending to PARTNER`, { |
86 | xid, | 86 | xid, |
87 | retry: retry || 0, | 87 | retry: retry || 0, |
88 | isPostpaid, | 88 | isPostpaid, |
89 | isHttpPost, | 89 | isHttpPost, |
90 | endpointUrl, | 90 | endpointUrl, |
91 | }); | 91 | }); |
92 | 92 | ||
93 | let responseToDump; | 93 | let responseToDump; |
94 | let errorResponseToDump; | 94 | let errorResponseToDump; |
95 | 95 | ||
96 | try { | 96 | try { |
97 | const response = isHttpPost | 97 | const response = isHttpPost |
98 | ? await axios.post(data.reverse_url, params, { | 98 | ? await axios.post(data.reverse_url, params, { |
99 | timeout: HTTP_TIMEOUT, | 99 | timeout: HTTP_TIMEOUT, |
100 | headers: axiosHeaders, | 100 | headers: axiosHeaders, |
101 | }) | 101 | }) |
102 | : await axios.get(data.reverse_url, { | 102 | : await axios.get(data.reverse_url, { |
103 | params, | 103 | params, |
104 | timeout: HTTP_TIMEOUT, | 104 | timeout: HTTP_TIMEOUT, |
105 | headers: axiosHeaders, | 105 | headers: axiosHeaders, |
106 | }); | 106 | }); |
107 | 107 | ||
108 | responseToDump = response; | 108 | responseToDump = response; |
109 | 109 | ||
110 | matrix.callback_sender.sent += 1; | 110 | matrix.callback_sender.sent += 1; |
111 | matrix.callback_sender.active_count += 1; | 111 | matrix.callback_sender.active_count += 1; |
112 | matrix.callback_sender.active_sending[xid] = { | 112 | matrix.callback_sender.active_sending[xid] = { |
113 | ts: new Date(), | 113 | ts: new Date(), |
114 | trxId: data.trx_id, | 114 | trxId: data.trx_id, |
115 | reverseUrl: data.reverse_url, | 115 | reverseUrl: data.reverse_url, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | if (isPostpaid) { | 118 | if (isPostpaid) { |
119 | matrix.callback_sender.sent_using_post += 1; | 119 | matrix.callback_sender.sent_using_post += 1; |
120 | } else { | 120 | } else { |
121 | matrix.callback_sender.sent_using_get += 1; | 121 | matrix.callback_sender.sent_using_get += 1; |
122 | } | 122 | } |
123 | 123 | ||
124 | logger.info(`${MODULE_NAME} 3641FBD7: Has been sent to PARTNER successfully`, { | 124 | logger.info(`${MODULE_NAME} 3641FBD7: Has been sent to PARTNER successfully`, { |
125 | xid, | 125 | xid, |
126 | retry, | 126 | retry, |
127 | httpStatus: response.status, | 127 | httpStatus: response.status, |
128 | responseBody: response && response.data, | 128 | responseBody: response && response.data, |
129 | }); | 129 | }); |
130 | } catch (e) { | 130 | } catch (e) { |
131 | matrix.callback_sender.sent_failed += 1; | 131 | matrix.callback_sender.sent_failed += 1; |
132 | matrix.callback_sender.last_error = { | 132 | matrix.callback_sender.last_error = { |
133 | xid, | 133 | xid, |
134 | ts: new Date(), | 134 | ts: new Date(), |
135 | eCode: e.code, | 135 | eCode: e.code, |
136 | eMessage: e.message, | 136 | eMessage: e.message, |
137 | trxId: data.trx_id, | 137 | trxId: data.trx_id, |
138 | reverseUrl: data.reverse_url, | 138 | reverseUrl: data.reverse_url, |
139 | httpStatus: e.response && e.response.status, | 139 | httpStatus: e.response && e.response.status, |
140 | responseBody: e.response && e.response.data, | 140 | responseBody: e.response && e.response.data, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | responseToDump = e.response && e.response.data; | 143 | responseToDump = e.response && e.response.data; |
144 | errorResponseToDump = e; | 144 | errorResponseToDump = e; |
145 | 145 | ||
146 | logger.warn(`${MODULE_NAME} A1EC9E70: Failed on sending to PARTNER`, { | 146 | logger.warn(`${MODULE_NAME} A1EC9E70: Failed on sending to PARTNER`, { |
147 | xid, | 147 | xid, |
148 | retry, | 148 | retry, |
149 | maxRetry: MAX_RETRY, | 149 | maxRetry: MAX_RETRY, |
150 | errCode: e.code, | 150 | errCode: e.code, |
151 | errMessage: e.message, | 151 | errMessage: e.message, |
152 | reverseUrl: data.reverse_url, | 152 | reverseUrl: data.reverse_url, |
153 | endpointUrl, | 153 | endpointUrl, |
154 | httpStatus: e.response && e.response.status, | 154 | httpStatus: e.response && e.response.status, |
155 | responseBody: e.response && e.response.data, | 155 | responseBody: e.response && e.response.data, |
156 | }); | 156 | }); |
157 | 157 | ||
158 | if (e.response && e.response.status) { | 158 | if (e.response && e.response.status) { |
159 | logger.verbose(`${MODULE_NAME} 10AE785C: Skip retry on http status presence`, { | 159 | logger.verbose(`${MODULE_NAME} 10AE785C: Skip retry on http status presence`, { |
160 | xid, | 160 | xid, |
161 | httpStatus: e.response && e.response.status, | 161 | httpStatus: e.response && e.response.status, |
162 | }); | 162 | }); |
163 | return; | 163 | return; |
164 | } | 164 | } |
165 | 165 | ||
166 | if ((retry || 0) < MAX_RETRY) { | 166 | if ((retry || 0) < MAX_RETRY) { |
167 | await sleep(SLEEP_BEFORE_RETRY_MS); | 167 | await sleep(SLEEP_BEFORE_RETRY_MS); |
168 | 168 | ||
169 | logger.verbose(`${MODULE_NAME} D8958695: Going to retry sending CORE-CALLBACK TO PARTNER`, { | 169 | logger.verbose(`${MODULE_NAME} D8958695: Going to retry sending CORE-CALLBACK TO PARTNER`, { |
170 | xid, | 170 | xid, |
171 | retried: retry, | 171 | retried: retry, |
172 | sleepTime: SLEEP_BEFORE_RETRY_MS, | 172 | sleepTime: SLEEP_BEFORE_RETRY_MS, |
173 | }); | 173 | }); |
174 | 174 | ||
175 | sender(data, xid, (retry || 0) + 1); | 175 | sender(data, xid, (retry || 0) + 1); |
176 | } | 176 | } |
177 | } finally { | 177 | } finally { |
178 | matrix.callback_sender.active_count -= 1; | 178 | matrix.callback_sender.active_count -= 1; |
179 | if (matrix.callback_sender.active_sending[xid]) { | 179 | if (matrix.callback_sender.active_sending[xid]) { |
180 | delete matrix.callback_sender.active_sending[xid]; | 180 | delete matrix.callback_sender.active_sending[xid]; |
181 | } | 181 | } |
182 | 182 | ||
183 | if (config.listener.partner.webhook) { | 183 | if (config.listener.partner.webhook) { |
184 | try { | 184 | try { |
185 | const webhookType = 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK'; | ||
186 | |||
187 | logger.verbose(`${MODULE_NAME} E21E3DC6: Sending webhook`, { | ||
188 | xid, | ||
189 | webhookType, | ||
190 | partner: config.listener.partner.webhook, | ||
191 | trxId: data.trx_id, | ||
192 | request_id: data.request_id && data.request_id.toString(), | ||
193 | }); | ||
194 | |||
185 | axios.post(config.listener.partner.webhook, { | 195 | axios.post(config.listener.partner.webhook, { |
186 | webhookType: 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK', | 196 | webhookType: 'KOMODO-CENTER-HTTPGETX.CORE-CALLBACK', |
187 | body: params, | 197 | body: params, |
188 | }); | 198 | }); |
199 | |||
200 | logger.verbose(`${MODULE_NAME} 26BCA07F: Webhook sent`, { | ||
201 | xid, | ||
202 | webhookType, | ||
203 | partner: config.listener.partner.webhook, | ||
204 | trxId: data.trx_id, | ||
205 | request_id: data.request_id && data.request_id.toString(), | ||
206 | }); | ||
189 | } catch (e) { | 207 | } catch (e) { |
190 | logger.warn(`${MODULE_NAME} F722520A: Exception on calling webhook`, { | 208 | logger.warn(`${MODULE_NAME} F722520A: Exception on calling webhook`, { |
191 | xid, | 209 | xid, |
192 | eCode: e.code, | 210 | eCode: e.code, |
193 | eMessage: e.message || e.toString(), | 211 | eMessage: e.message || e.toString(), |
194 | }); | 212 | }); |
195 | } | 213 | } |
196 | } | 214 | } |
197 | 215 | ||
198 | dumper( | 216 | dumper( |
199 | xid, | 217 | xid, |
200 | isHttpPost ? 'POST' : 'GET', | 218 | isHttpPost ? 'POST' : 'GET', |
201 | endpointUrl, | 219 | endpointUrl, |
202 | params, | 220 | params, |
203 | responseToDump, | 221 | responseToDump, |
204 | errorResponseToDump, | 222 | errorResponseToDump, |
205 | ); | 223 | ); |
206 | } | 224 | } |
207 | }; | 225 | }; |
208 | 226 | ||
209 | module.exports = sender; | 227 | module.exports = sender; |
210 | 228 |
lib/partner-listener/routers/topup.js
1 | const MODULE_NAME = 'PARTNER-LISTENER.ROUTER.TOPUP'; | 1 | const MODULE_NAME = 'PARTNER-LISTENER.ROUTER.TOPUP'; |
2 | 2 | ||
3 | const express = require('express'); | 3 | const express = require('express'); |
4 | const axios = require('axios'); | 4 | const axios = require('axios'); |
5 | 5 | ||
6 | const config = require('komodo-sdk/config'); | 6 | const config = require('komodo-sdk/config'); |
7 | const logger = require('tektrans-logger'); | 7 | const logger = require('tektrans-logger'); |
8 | const coreapi = require('komodo-sdk/coreapi'); | 8 | const coreapi = require('komodo-sdk/coreapi'); |
9 | // const coreapi = require('../../coreapi'); | 9 | // const coreapi = require('../../coreapi'); |
10 | const matrix = require('../../matrix'); | 10 | const matrix = require('../../matrix'); |
11 | const dumper = require('../dumper'); | 11 | const dumper = require('../dumper'); |
12 | 12 | ||
13 | const router = express.Router(); | 13 | const router = express.Router(); |
14 | module.exports = router; | 14 | module.exports = router; |
15 | 15 | ||
16 | const terminalsWithLocation = Array.isArray(config.terminals_with_location) | 16 | const terminalsWithLocation = Array.isArray(config.terminals_with_location) |
17 | ? config.terminals_with_location | 17 | ? config.terminals_with_location |
18 | .filter((item) => typeof item === 'string') | 18 | .filter((item) => typeof item === 'string') |
19 | .map((item) => (item.trim().toLowerCase())) | 19 | .map((item) => (item.trim().toLowerCase())) |
20 | : []; | 20 | : []; |
21 | 21 | ||
22 | function onInvalidParameter(missingParameter, req, res) { | 22 | function onInvalidParameter(missingParameter, req, res) { |
23 | logger.verbose(`${MODULE_NAME} 1536D577: Undefined ${missingParameter} parameter`, { | 23 | logger.verbose(`${MODULE_NAME} 1536D577: Undefined ${missingParameter} parameter`, { |
24 | xid: res.locals.xid, | 24 | xid: res.locals.xid, |
25 | ip: req.ip, | 25 | ip: req.ip, |
26 | terminal_name: req.body.terminal_name || req.query.terminal_name, | 26 | terminal_name: req.body.terminal_name || req.query.terminal_name, |
27 | request_id: req.body.request_id || req.query.request_id, | 27 | request_id: req.body.request_id || req.query.request_id, |
28 | product_name: req.body.product_name || req.query.product_name, | 28 | product_name: req.body.product_name || req.query.product_name, |
29 | destination: req.body.destination || req.query.destination, | 29 | destination: req.body.destination || req.query.destination, |
30 | }); | 30 | }); |
31 | res.end('INVALID REQUEST'); | 31 | res.end('INVALID REQUEST'); |
32 | } | 32 | } |
33 | 33 | ||
34 | function pagePrerequisite(req, res, next) { | 34 | function pagePrerequisite(req, res, next) { |
35 | if (!req.body) req.body = {}; | 35 | if (!req.body) req.body = {}; |
36 | 36 | ||
37 | const terminalName = req.body.terminal_name || req.query.terminal_name; | 37 | const terminalName = req.body.terminal_name || req.query.terminal_name; |
38 | if (!terminalName || typeof terminalName !== 'string') { | 38 | if (!terminalName || typeof terminalName !== 'string') { |
39 | onInvalidParameter('terminal_name', req, res); | 39 | onInvalidParameter('terminal_name', req, res); |
40 | return; | 40 | return; |
41 | } | 41 | } |
42 | 42 | ||
43 | if (!req.body.password && !req.query.password) { | 43 | if (!req.body.password && !req.query.password) { |
44 | onInvalidParameter('password', req, res); | 44 | onInvalidParameter('password', req, res); |
45 | return; | 45 | return; |
46 | } | 46 | } |
47 | 47 | ||
48 | if (!req.body.request_id && !req.query.request_id) { | 48 | if (!req.body.request_id && !req.query.request_id) { |
49 | onInvalidParameter('request_id', req, res); | 49 | onInvalidParameter('request_id', req, res); |
50 | return; | 50 | return; |
51 | } | 51 | } |
52 | 52 | ||
53 | if (!req.body.product_name && !req.query.product_name) { | 53 | if (!req.body.product_name && !req.query.product_name) { |
54 | onInvalidParameter('product_name', req, res); | 54 | onInvalidParameter('product_name', req, res); |
55 | return; | 55 | return; |
56 | } | 56 | } |
57 | 57 | ||
58 | if (!req.body.destination && !req.query.destination) { | 58 | if (!req.body.destination && !req.query.destination) { |
59 | onInvalidParameter('destination', req, res); | 59 | onInvalidParameter('destination', req, res); |
60 | return; | 60 | return; |
61 | } | 61 | } |
62 | 62 | ||
63 | next(); | 63 | next(); |
64 | } | 64 | } |
65 | 65 | ||
66 | async function pageIndex(req, res) { | 66 | async function pageIndex(req, res) { |
67 | const { xid } = res.locals; | 67 | const { xid } = res.locals; |
68 | 68 | ||
69 | const terminalNameWithoutIp = ((req.body.terminal_name || req.query.terminal_name) || '').trim(); | 69 | const terminalNameWithoutIp = ((req.body.terminal_name || req.query.terminal_name) || '').trim(); |
70 | const terminalName = `${terminalNameWithoutIp}@${req.ip.replace(/^::ffff:/, '')}`; | 70 | const terminalName = `${terminalNameWithoutIp}@${req.ip.replace(/^::ffff:/, '')}`; |
71 | 71 | ||
72 | const qs = { | 72 | const qs = { |
73 | terminal_name: terminalName, | 73 | terminal_name: terminalName, |
74 | password: req.body.password || req.query.password, | 74 | password: req.body.password || req.query.password, |
75 | request_id: req.body.request_id || req.query.request_id, | 75 | request_id: req.body.request_id || req.query.request_id, |
76 | product_name: req.body.product_name || req.query.product_name, | 76 | product_name: req.body.product_name || req.query.product_name, |
77 | destination: req.body.destination || req.query.destination, | 77 | destination: req.body.destination || req.query.destination, |
78 | origin: config.name || 'HTTPGETX', | 78 | origin: config.name || 'HTTPGETX', |
79 | report_ip: config.listener.core.ip || null, | 79 | report_ip: config.listener.core.ip || null, |
80 | report_port: config.listener.core.port, | 80 | report_port: config.listener.core.port, |
81 | reverse_url: req.body.reverse_url || req.query.reverse_url || null, | 81 | reverse_url: req.body.reverse_url || req.query.reverse_url || null, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | if (terminalsWithLocation.indexOf(terminalNameWithoutIp.toLowerCase()) >= 0) { | 84 | if (terminalsWithLocation.indexOf(terminalNameWithoutIp.toLowerCase()) >= 0) { |
85 | const location = req.body.location | 85 | const location = req.body.location |
86 | || req.body.location_id | 86 | || req.body.location_id |
87 | || req.query.location | 87 | || req.query.location |
88 | || req.query.location_id; | 88 | || req.query.location_id; |
89 | 89 | ||
90 | if (location) { | 90 | if (location) { |
91 | logger.verbose(`${MODULE_NAME} 5C41FBFA: Including location from partner request`, { | 91 | logger.verbose(`${MODULE_NAME} 5C41FBFA: Including location from partner request`, { |
92 | xid, | 92 | xid, |
93 | terminalName, | 93 | terminalName, |
94 | location, | 94 | location, |
95 | }); | 95 | }); |
96 | 96 | ||
97 | qs.location = location; | 97 | qs.location = location; |
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | matrix.core.sent += 1; | 101 | matrix.core.sent += 1; |
102 | 102 | ||
103 | const [err, coreResponse] = await coreapi({ | 103 | const [err, coreResponse] = await coreapi({ |
104 | xid, | 104 | xid, |
105 | path: '/prepaid/buy', | 105 | path: '/prepaid/buy', |
106 | qs, | 106 | qs, |
107 | }); | 107 | }); |
108 | 108 | ||
109 | if (err || !coreResponse) { | 109 | if (err || !coreResponse) { |
110 | matrix.core.sent_failed += 1; | 110 | matrix.core.sent_failed += 1; |
111 | matrix.core.last_error = { | 111 | matrix.core.last_error = { |
112 | xid, | 112 | xid, |
113 | ts: new Date(), | 113 | ts: new Date(), |
114 | e: err, | 114 | e: err, |
115 | eCode: err.code, | 115 | eCode: err.code, |
116 | eMessage: err.message, | 116 | eMessage: err.message, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | logger.warn(`${MODULE_NAME} 8DEBE15F: ERROR on /prepaid/buy response`, { | 119 | logger.warn(`${MODULE_NAME} 8DEBE15F: ERROR on /prepaid/buy response`, { |
120 | xid, | 120 | xid, |
121 | err, | 121 | err, |
122 | coreResponseTypeof: typeof coreResponse, | 122 | coreResponseTypeof: typeof coreResponse, |
123 | coreResponse, | 123 | coreResponse, |
124 | }); | 124 | }); |
125 | res.end('INVALID CORE RESPONSE'); | 125 | res.end('INVALID CORE RESPONSE'); |
126 | 126 | ||
127 | dumper(xid, req, 'INVALID CORE RESPONSE'); | 127 | dumper(xid, req, 'INVALID CORE RESPONSE'); |
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | 130 | ||
131 | logger.verbose(`${MODULE_NAME} 2528A9B4: Got CORE response`, { | 131 | logger.verbose(`${MODULE_NAME} 2528A9B4: Got CORE response`, { |
132 | xid, | 132 | xid, |
133 | coreResponse, | 133 | coreResponse, |
134 | }); | 134 | }); |
135 | 135 | ||
136 | const responseToPartner = { | 136 | const responseToPartner = { |
137 | httpgetx_xid: xid, | 137 | httpgetx_xid: xid, |
138 | request_id: coreResponse.request_id, | 138 | request_id: coreResponse.request_id, |
139 | transaction_id: coreResponse.transaction_id, | 139 | transaction_id: coreResponse.transaction_id, |
140 | transaction_date: coreResponse.transaction_date, | 140 | transaction_date: coreResponse.transaction_date, |
141 | store_name: coreResponse.store_name, | 141 | store_name: coreResponse.store_name, |
142 | terminal_name: coreResponse.terminal_name, | 142 | terminal_name: coreResponse.terminal_name, |
143 | product_name: coreResponse.product_name, | 143 | product_name: coreResponse.product_name, |
144 | destination: coreResponse.destination, | 144 | destination: coreResponse.destination, |
145 | rc: coreResponse.rc, | 145 | rc: coreResponse.rc, |
146 | sn: coreResponse.sn || undefined, | 146 | sn: coreResponse.sn || undefined, |
147 | amount: Number(coreResponse.amount) || undefined, | 147 | amount: Number(coreResponse.amount) || undefined, |
148 | ending_balance: Number(coreResponse.ending_balance) || undefined, | 148 | ending_balance: Number(coreResponse.ending_balance) || undefined, |
149 | message: coreResponse.message, | 149 | message: coreResponse.message, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | res.json(responseToPartner); | 152 | res.json(responseToPartner); |
153 | 153 | ||
154 | if (config.listener.partner.webhook) { | 154 | if (config.listener.partner.webhook) { |
155 | try { | 155 | try { |
156 | const webhookType = 'KOMODO-CENTER-HTTPGETX.PARTNER-LISTENER.DIRECT-RESPONSE'; | ||
157 | |||
158 | logger.verbose(`${MODULE_NAME} 2CA59ED3: Sending webhook`, { | ||
159 | xid, | ||
160 | webhookType, | ||
161 | partner: config.listener.partner.webhook, | ||
162 | trxId: coreResponse.transaction_id, | ||
163 | request_id: req.body.request_id || req.query.request_id, | ||
164 | }); | ||
165 | |||
156 | axios.post(config.listener.partner.webhook, { | 166 | axios.post(config.listener.partner.webhook, { |
157 | webhookType: 'KOMODO-CENTER-HTTPGETX.PARTNER-LISTENER.DIRECT-RESPONSE', | 167 | webhookType, |
158 | body: responseToPartner, | 168 | body: responseToPartner, |
159 | }); | 169 | }); |
170 | |||
171 | logger.verbose(`${MODULE_NAME} 50BE8D98: Webhook sent`, { | ||
172 | xid, | ||
173 | webhookType, | ||
174 | partner: config.listener.partner.webhook, | ||
175 | trxId: coreResponse.transaction_id, | ||
176 | request_id: req.body.request_id || req.query.request_id, | ||
177 | }); | ||
160 | } catch (e) { | 178 | } catch (e) { |
161 | logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, { | 179 | logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, { |
162 | xid, | 180 | xid, |
163 | eCode: e.code, | 181 | eCode: e.code, |
164 | eMessage: e.message || e.toString(), | 182 | eMessage: e.message || e.toString(), |
165 | }); | 183 | }); |
166 | } | 184 | } |
167 | } | 185 | } |
168 | 186 | ||
169 | dumper(xid, req, responseToPartner); | 187 | dumper(xid, req, responseToPartner); |
170 | } | 188 | } |
171 | 189 | ||
172 | // router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); }); | 190 | // router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); }); |
173 | router.get('/', pagePrerequisite, pageIndex); | 191 | router.get('/', pagePrerequisite, pageIndex); |
174 | router.post('/', express.urlencoded({ extended: true }), express.json({ extended: true }), pageIndex); | 192 | router.post('/', express.urlencoded({ extended: true }), express.json({ extended: true }), pageIndex); |
175 | 193 |