Commit 442388f0b247f677677dc1213d9a137b6fabd66d
1 parent
c7906ddf24
Exists in
master
Debug full endpoint url
Showing 2 changed files with 12 additions and 0 deletions Inline Diff
lib/hit/dump-req-res.js
1 | const MODULE_NAME = 'DUMP-REQ-RES'; | 1 | const MODULE_NAME = 'DUMP-REQ-RES'; |
2 | 2 | ||
3 | const querystring = require('querystring'); | ||
3 | const fs = require('fs'); | 4 | const fs = require('fs'); |
4 | const path = require('path'); | 5 | const path = require('path'); |
5 | const fsPromise = require('fs').promises; | 6 | const fsPromise = require('fs').promises; |
6 | const moment = require('moment'); | 7 | const moment = require('moment'); |
7 | 8 | ||
8 | const config = require('komodo-sdk/config'); | 9 | const config = require('komodo-sdk/config'); |
9 | const logger = require('tektrans-logger'); | 10 | const logger = require('tektrans-logger'); |
10 | 11 | ||
11 | const baseDumpDir = 'dump'; | 12 | const baseDumpDir = 'dump'; |
12 | const requestDumpDir = path.join(baseDumpDir, 'request'); | 13 | const requestDumpDir = path.join(baseDumpDir, 'request'); |
13 | 14 | ||
14 | if (!fs.existsSync(baseDumpDir)) { | 15 | if (!fs.existsSync(baseDumpDir)) { |
15 | logger.verbose(`${MODULE_NAME} 51105314: Creating base dump dir`); | 16 | logger.verbose(`${MODULE_NAME} 51105314: Creating base dump dir`); |
16 | fs.mkdirSync(baseDumpDir); | 17 | fs.mkdirSync(baseDumpDir); |
17 | } | 18 | } |
18 | 19 | ||
19 | if (!fs.existsSync(requestDumpDir)) { | 20 | if (!fs.existsSync(requestDumpDir)) { |
20 | logger.verbose(`${MODULE_NAME} 8A52891B: Creating request dump dir`); | 21 | logger.verbose(`${MODULE_NAME} 8A52891B: Creating request dump dir`); |
21 | fs.mkdirSync(requestDumpDir); | 22 | fs.mkdirSync(requestDumpDir); |
22 | } | 23 | } |
23 | 24 | ||
24 | module.exports = async ( | 25 | module.exports = async ( |
25 | xid, task, httpMethod, endpointUrl, params, responseBody, responseStatus, isAdvice, | 26 | xid, task, httpMethod, endpointUrl, params, responseBody, responseStatus, isAdvice, |
26 | ) => { | 27 | ) => { |
27 | if ( | 28 | if ( |
28 | !config | 29 | !config |
29 | || !config.partner | 30 | || !config.partner |
30 | || !config.partner.dump_request | 31 | || !config.partner.dump_request |
31 | ) { | 32 | ) { |
32 | return; | 33 | return; |
33 | } | 34 | } |
34 | 35 | ||
35 | const data = `-------- | 36 | const data = `-------- |
36 | XID: ${xid} | 37 | XID: ${xid} |
37 | PID: ${process.pid} | 38 | PID: ${process.pid} |
38 | DATE: ${moment().format('YYYY-MM-DD HH:mm:ss.SSS')} | 39 | DATE: ${moment().format('YYYY-MM-DD HH:mm:ss.SSS')} |
39 | 40 | ||
40 | TASK: | 41 | TASK: |
41 | ${JSON.stringify(task, null, 2)} | 42 | ${JSON.stringify(task, null, 2)} |
42 | 43 | ||
43 | IS-ADVICE: ${!!isAdvice} | 44 | IS-ADVICE: ${!!isAdvice} |
44 | 45 | ||
45 | HTTP-METHOD: ${httpMethod} | 46 | HTTP-METHOD: ${httpMethod} |
46 | URL: ${endpointUrl} | 47 | URL: ${endpointUrl} |
47 | PARAMS: | 48 | PARAMS: |
48 | ${ | 49 | ${ |
49 | params && ( | 50 | params && ( |
50 | (typeof params === 'string' && params) | 51 | (typeof params === 'string' && params) |
51 | || JSON.stringify(params, null, 2) | 52 | || JSON.stringify(params, null, 2) |
52 | ) | 53 | ) |
53 | } | 54 | } |
54 | 55 | ||
56 | ${httpMethod === 'GET' ? '' : `FULL URL: ${endpointUrl}?${querystring.stringify(params)}`} | ||
57 | |||
55 | RESPONSE-STATUS: ${responseStatus} | 58 | RESPONSE-STATUS: ${responseStatus} |
56 | RESPONSE-BODY: | 59 | RESPONSE-BODY: |
57 | ${ | 60 | ${ |
58 | responseBody && ( | 61 | responseBody && ( |
59 | (typeof responseBody === 'string' && responseBody) | 62 | (typeof responseBody === 'string' && responseBody) |
60 | || JSON.stringify(responseBody, null, 2) | 63 | || JSON.stringify(responseBody, null, 2) |
61 | ) | 64 | ) |
62 | } | 65 | } |
63 | 66 | ||
64 | `; | 67 | `; |
65 | 68 | ||
66 | const dumpDir = path.join( | 69 | const dumpDir = path.join( |
67 | requestDumpDir, | 70 | requestDumpDir, |
68 | moment().format('YYYY-MM-DD'), | 71 | moment().format('YYYY-MM-DD'), |
69 | ); | 72 | ); |
70 | 73 | ||
71 | try { | 74 | try { |
72 | await fsPromise.stat(dumpDir); | 75 | await fsPromise.stat(dumpDir); |
73 | } catch { | 76 | } catch { |
74 | await fsPromise.mkdir(dumpDir, { recursive: true }); | 77 | await fsPromise.mkdir(dumpDir, { recursive: true }); |
75 | } | 78 | } |
76 | 79 | ||
77 | await fsPromise.appendFile( | 80 | await fsPromise.appendFile( |
78 | path.join( | 81 | path.join( |
79 | dumpDir, | 82 | dumpDir, |
80 | `trx_${task.trx_id}`, | 83 | `trx_${task.trx_id}`, |
81 | ), | 84 | ), |
82 | data, | 85 | data, |
83 | ); | 86 | ); |
84 | 87 | ||
85 | await fsPromise.writeFile( | 88 | await fsPromise.writeFile( |
86 | path.join(requestDumpDir, 'last'), | 89 | path.join(requestDumpDir, 'last'), |
87 | data, | 90 | data, |
88 | ); | 91 | ); |
89 | }; | 92 | }; |
90 | 93 |
lib/hit/prepaid-topup.js
1 | const MODULE_NAME = 'HIT.PREPAID-TOPUP'; | 1 | const MODULE_NAME = 'HIT.PREPAID-TOPUP'; |
2 | 2 | ||
3 | const axios = require('axios'); | 3 | const axios = require('axios'); |
4 | const urljoin = require('url-join'); | 4 | const urljoin = require('url-join'); |
5 | const querystring = require('querystring'); | ||
5 | 6 | ||
6 | const config = require('komodo-sdk/config'); | 7 | const config = require('komodo-sdk/config'); |
7 | const logger = require('tektrans-logger'); | 8 | const logger = require('tektrans-logger'); |
8 | 9 | ||
9 | const report = require('../report/prepaid'); | 10 | const report = require('../report/prepaid'); |
10 | const translateRc = require('../translate-rc'); | 11 | const translateRc = require('../translate-rc'); |
11 | const composeCallbackUrl = require('./compose-callback-url'); | 12 | const composeCallbackUrl = require('./compose-callback-url'); |
12 | const dumpReqRes = require('./dump-req-res'); | 13 | const dumpReqRes = require('./dump-req-res'); |
13 | const axiosErrorIsSafe = require('./axios-error-is-safe'); | 14 | const axiosErrorIsSafe = require('./axios-error-is-safe'); |
14 | 15 | ||
15 | module.exports = async (xid, task) => { | 16 | module.exports = async (xid, task) => { |
16 | logger.verbose(`${MODULE_NAME} 2272F01F: Processing task`, { | 17 | logger.verbose(`${MODULE_NAME} 2272F01F: Processing task`, { |
17 | xid, | 18 | xid, |
18 | task, | 19 | task, |
19 | }); | 20 | }); |
20 | 21 | ||
21 | const params = { | 22 | const params = { |
22 | request_id: task.trx_id, | 23 | request_id: task.trx_id, |
23 | terminal_name: config.partner.terminal_name, | 24 | terminal_name: config.partner.terminal_name, |
24 | password: config.partner.password, | 25 | password: config.partner.password, |
25 | destination: task.destination, | 26 | destination: task.destination, |
26 | product_name: task.remote_product, | 27 | product_name: task.remote_product, |
27 | reverse_url: composeCallbackUrl(xid, task, false), | 28 | reverse_url: composeCallbackUrl(xid, task, false), |
28 | }; | 29 | }; |
29 | 30 | ||
30 | const endpointUrl = urljoin(config.partner.url, '/topup'); | 31 | const endpointUrl = urljoin(config.partner.url, '/topup'); |
32 | const fullEndpointUrl = urljoin( | ||
33 | endpointUrl, | ||
34 | [ | ||
35 | '?', | ||
36 | querystring.stringify(params), | ||
37 | ], | ||
38 | ); | ||
31 | let lastResponse = null; | 39 | let lastResponse = null; |
32 | 40 | ||
33 | try { | 41 | try { |
34 | logger.verbose(`${MODULE_NAME} 4AAD4F99: Going to HIT prepaid endpoint`, { | 42 | logger.verbose(`${MODULE_NAME} 4AAD4F99: Going to HIT prepaid endpoint`, { |
35 | xid, | 43 | xid, |
36 | endpointUrl, | 44 | endpointUrl, |
37 | params, | 45 | params, |
46 | fullEndpointUrl, | ||
38 | }); | 47 | }); |
39 | 48 | ||
40 | report(xid, { | 49 | report(xid, { |
41 | trx_id: task.trx_id, | 50 | trx_id: task.trx_id, |
42 | rc: '68', | 51 | rc: '68', |
43 | message: { | 52 | message: { |
44 | xid, | 53 | xid, |
45 | msg: 'Sending request to partner', | 54 | msg: 'Sending request to partner', |
46 | endpointUrl, | 55 | endpointUrl, |
47 | }, | 56 | }, |
48 | }); | 57 | }); |
49 | 58 | ||
50 | const response = await axios.get(endpointUrl, { | 59 | const response = await axios.get(endpointUrl, { |
51 | headers: { | 60 | headers: { |
52 | 'User-Agent': 'KOMODO-GW-HTTPGETX', | 61 | 'User-Agent': 'KOMODO-GW-HTTPGETX', |
53 | }, | 62 | }, |
54 | timeout: config.partner.hit_timeout_ms || 60 * 1000, | 63 | timeout: config.partner.hit_timeout_ms || 60 * 1000, |
55 | params, | 64 | params, |
56 | }); | 65 | }); |
57 | 66 | ||
58 | if (!response) { | 67 | if (!response) { |
59 | const e = new Error(`${MODULE_NAME} 8CF4E04D: Empty response`); | 68 | const e = new Error(`${MODULE_NAME} 8CF4E04D: Empty response`); |
60 | e.rc = '68'; | 69 | e.rc = '68'; |
61 | e.response = response; | 70 | e.response = response; |
62 | throw e; | 71 | throw e; |
63 | } | 72 | } |
64 | 73 | ||
65 | if (!response.data) { | 74 | if (!response.data) { |
66 | const e = new Error(`${MODULE_NAME} E72B5A53: Empty response data`); | 75 | const e = new Error(`${MODULE_NAME} E72B5A53: Empty response data`); |
67 | e.rc = '68'; | 76 | e.rc = '68'; |
68 | e.response = response; | 77 | e.response = response; |
69 | throw e; | 78 | throw e; |
70 | } | 79 | } |
71 | 80 | ||
72 | if (typeof response.data !== 'object') { | 81 | if (typeof response.data !== 'object') { |
73 | const e = new Error(`${MODULE_NAME} 507680AB: Response data is not a JSON`); | 82 | const e = new Error(`${MODULE_NAME} 507680AB: Response data is not a JSON`); |
74 | e.rc = '68'; | 83 | e.rc = '68'; |
75 | e.response = response; | 84 | e.response = response; |
76 | throw e; | 85 | throw e; |
77 | } | 86 | } |
78 | 87 | ||
79 | lastResponse = response; | 88 | lastResponse = response; |
80 | 89 | ||
81 | logger.verbose(`${MODULE_NAME} E51AFBBA: Got a direct response`, { | 90 | logger.verbose(`${MODULE_NAME} E51AFBBA: Got a direct response`, { |
82 | xid, | 91 | xid, |
83 | responseBody: response.data, | 92 | responseBody: response.data, |
84 | }); | 93 | }); |
85 | 94 | ||
86 | report(xid, { | 95 | report(xid, { |
87 | trx_id: task.trx_id, | 96 | trx_id: task.trx_id, |
88 | rc: response.data.rc ? translateRc[response.data.rc] || response.data.rc | 97 | rc: response.data.rc ? translateRc[response.data.rc] || response.data.rc |
89 | : '68', | 98 | : '68', |
90 | sn: response.data.sn || null, | 99 | sn: response.data.sn || null, |
91 | amount: Number(response.data.amount) || undefined, | 100 | amount: Number(response.data.amount) || undefined, |
92 | balance: Number(response.data.ending_balance) || undefined, | 101 | balance: Number(response.data.ending_balance) || undefined, |
93 | message: { | 102 | message: { |
94 | xid, | 103 | xid, |
95 | 'DIRECT-RESPONSE': response.data, | 104 | 'DIRECT-RESPONSE': response.data, |
96 | }, | 105 | }, |
97 | }); | 106 | }); |
98 | } catch (e) { | 107 | } catch (e) { |
99 | const rc = e.rc | 108 | const rc = e.rc |
100 | || (axiosErrorIsSafe(e) && '91') | 109 | || (axiosErrorIsSafe(e) && '91') |
101 | || '68'; | 110 | || '68'; |
102 | 111 | ||
103 | logger.warn(`${MODULE_NAME} 8E8E49F5: Exception`, { | 112 | logger.warn(`${MODULE_NAME} 8E8E49F5: Exception`, { |
104 | xid, | 113 | xid, |
105 | eCode: e.code, | 114 | eCode: e.code, |
106 | eMessage: e.message, | 115 | eMessage: e.message, |
107 | eRc: e.rc, | 116 | eRc: e.rc, |
108 | rc, | 117 | rc, |
109 | responseHttpStatus: e.response && e.response.status, | 118 | responseHttpStatus: e.response && e.response.status, |
110 | responseBody: e.response && e.response.data, | 119 | responseBody: e.response && e.response.data, |
111 | }); | 120 | }); |
112 | 121 | ||
113 | lastResponse = e.response; | 122 | lastResponse = e.response; |
114 | 123 | ||
115 | report(xid, { | 124 | report(xid, { |
116 | trx_id: task.trx_id, | 125 | trx_id: task.trx_id, |
117 | rc, | 126 | rc, |
118 | message: { | 127 | message: { |
119 | xid, | 128 | xid, |
120 | 'KOMODO-GW-ERROR': { | 129 | 'KOMODO-GW-ERROR': { |
121 | eCode: e.code, | 130 | eCode: e.code, |
122 | eMessage: e.message, | 131 | eMessage: e.message, |
123 | responseHttpStatus: e.response && e.response.status, | 132 | responseHttpStatus: e.response && e.response.status, |
124 | responseBody: e.response && e.response.data, | 133 | responseBody: e.response && e.response.data, |
125 | }, | 134 | }, |
126 | }, | 135 | }, |
127 | }); | 136 | }); |
128 | } finally { | 137 | } finally { |
129 | dumpReqRes( | 138 | dumpReqRes( |
130 | xid, | 139 | xid, |
131 | task, | 140 | task, |
132 | 'GET', | 141 | 'GET', |
133 | endpointUrl, | 142 | endpointUrl, |
134 | params, | 143 | params, |
135 | lastResponse && lastResponse.data, | 144 | lastResponse && lastResponse.data, |
136 | lastResponse && lastResponse.status, | 145 | lastResponse && lastResponse.status, |
137 | lastResponse, | 146 | lastResponse, |
138 | false, | 147 | false, |
139 | ); | 148 | ); |
140 | } | 149 | } |
141 | }; | 150 | }; |
142 | 151 |