Commit 1ae80ad7feb59a2de28788a112d17e660745e6a5
1 parent
45a958ee44
Exists in
master
and in
1 other branch
Refactor to partner-listener
Showing 11 changed files with 444 additions and 444 deletions Side-by-side Diff
- index.js
- lib/listener-partner/index.js
- lib/listener-partner/routers/inquiry.js
- lib/listener-partner/routers/pay.js
- lib/listener-partner/routers/topup.js
- lib/listener-partner/routers/trx-status.js
- lib/partner-listener/index.js
- lib/partner-listener/routers/inquiry.js
- lib/partner-listener/routers/pay.js
- lib/partner-listener/routers/topup.js
- lib/partner-listener/routers/trx-status.js
index.js
lib/listener-partner/index.js
... | ... | @@ -1,36 +0,0 @@ |
1 | -const DEFAULT_LISTENER_FROM_PARTNER_PORT = 25614; | |
2 | - | |
3 | -const express = require('express'); | |
4 | - | |
5 | -const config = require('komodo-sdk/config'); | |
6 | -const logger = require('komodo-sdk/logger'); | |
7 | - | |
8 | -const middlewareCommon = require('../middlewares/common'); | |
9 | - | |
10 | -const routerInquiry = require('./routers/inquiry'); | |
11 | -const routerPay = require('./routers/pay'); | |
12 | -const routerTopup = require('./routers/topup'); | |
13 | -const routerTrxStatus = require('./routers/trx-status'); | |
14 | - | |
15 | -const app = express(); | |
16 | - | |
17 | -app.use(express.json({ extended: true })); | |
18 | -app.use(express.urlencoded({ extended: true })); | |
19 | -app.use(middlewareCommon); | |
20 | - | |
21 | -app.use('/inquiry', routerInquiry); | |
22 | -app.use('/pay', routerPay); | |
23 | -app.use('/topup', routerTopup); | |
24 | -app.use('/trx-status', routerTrxStatus); | |
25 | - | |
26 | -app.use((req, res) => { | |
27 | - const { xid } = res.locals; | |
28 | - res.status(404).end(`KOMODO-HTTP-GET-X CENTER.\n404: Method not found.\n\nXID: ${xid}.\n`); | |
29 | -}); | |
30 | - | |
31 | -app.listen(config.listener.partner.port || DEFAULT_LISTENER_FROM_PARTNER_PORT, () => { | |
32 | - logger.info(`Listen from partner request on port ${config.listener.partner.port}`); | |
33 | -}).on('error', (e) => { | |
34 | - logger.error(`Can not listen request from partner on port ${config.listener.partner.port || DEFAULT_LISTENER_FROM_PARTNER_PORT}. ${e.toString()}`); | |
35 | - process.exit(1); | |
36 | -}); |
lib/listener-partner/routers/inquiry.js
... | ... | @@ -1,106 +0,0 @@ |
1 | -const axios = require('axios').default; | |
2 | -const express = require('express'); | |
3 | -const coreUrl = require('komodo-sdk/core-url'); | |
4 | - | |
5 | -const config = require('komodo-sdk/config'); | |
6 | -const logger = require('komodo-sdk/logger'); | |
7 | - | |
8 | -const getFromBodyQsParams = require('../../get-from-body-qs-params'); | |
9 | -const ipv6ToIpv4 = require('../../ipv6-to-ipv4'); | |
10 | - | |
11 | -const router = express.Router(); | |
12 | -module.exports = router; | |
13 | - | |
14 | -const CORE_ENDPOINT = `${coreUrl}/postpaid2/inquiry`; | |
15 | - | |
16 | -const mainHandler = async (req, res) => { | |
17 | - const { xid } = res.locals; | |
18 | - | |
19 | - const requestId = (getFromBodyQsParams(req, 'request_id') || '').toString().trim(); | |
20 | - const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); | |
21 | - const terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; | |
22 | - const productName = (getFromBodyQsParams(req, 'product_name') || '').trim().toUpperCase(); | |
23 | - const destination = (getFromBodyQsParams(req, 'destination') || '').toString().trim(); | |
24 | - const password = getFromBodyQsParams(req, 'password'); | |
25 | - const reverseUrl = getFromBodyQsParams(req, 'reverse_url'); | |
26 | - | |
27 | - if (!requestId || !terminalNameWithoutIp || !productName || !destination) { | |
28 | - res.end('INVALID REQUEST. Missing request_id or terminal_name or product_name or destination.'); | |
29 | - return; | |
30 | - } | |
31 | - | |
32 | - const params = { | |
33 | - origin: config.name, | |
34 | - report_ip: config.listener.core.from_ip, | |
35 | - report_port: config.listener.core.port || 25614, | |
36 | - request_id: requestId, | |
37 | - terminal_name: terminalName, | |
38 | - product_name: productName, | |
39 | - destination, | |
40 | - terminal_password: password, | |
41 | - reverse_url: reverseUrl, | |
42 | - }; | |
43 | - | |
44 | - logger.info('Forwarding INQUIRY request to CORE', { xid, params }); | |
45 | - try { | |
46 | - const result = await axios.get(CORE_ENDPOINT, { | |
47 | - params, | |
48 | - timeout: 10000, | |
49 | - }); | |
50 | - | |
51 | - if (!result || !result.data) { | |
52 | - const newError = new Error('8002EB0D: Empty CORE INQUIRY direct-response'); | |
53 | - logger.warn(newError.message, { xid }); | |
54 | - throw newError; | |
55 | - } | |
56 | - | |
57 | - logger.verbose('Got INQUIRY direct-response from CORE', { | |
58 | - xid, | |
59 | - coreResponse: result.data, | |
60 | - }); | |
61 | - | |
62 | - const resultForPartner = { | |
63 | - httpgetx_xid: xid, | |
64 | - command: result.data.command, | |
65 | - request_id: result.data.request_id && result.data.request_id.toString(), | |
66 | - transaction_id: result.data.transaction_id && result.data.transaction_id.toString(), | |
67 | - transaction_date: result.data.transaction_date, | |
68 | - store_name: result.data.store_name, | |
69 | - terminal_name: result.data.terminal_name, | |
70 | - product_name: result.data.product_name, | |
71 | - destination: result.data.destination, | |
72 | - rc: result.data.rc, | |
73 | - sn: result.data.sn, | |
74 | - message: result.data.message, | |
75 | - amount: result.data.amount, | |
76 | - ending_balance: result.data.ending_balance, | |
77 | - amount_to_charge: result.data.amount_to_charge, | |
78 | - }; | |
79 | - | |
80 | - logger.verbose('Forwarding CORE direct-response to partner', { | |
81 | - xid, | |
82 | - resultForPartner, | |
83 | - }); | |
84 | - | |
85 | - res.json(resultForPartner); | |
86 | - } catch (e) { | |
87 | - logger.warn('EXCEPTION on forwarding INQUIRY request to CORE', { | |
88 | - xid, | |
89 | - errCode: e.code, | |
90 | - errMessage: e.message, | |
91 | - }); | |
92 | - | |
93 | - res.json({ | |
94 | - httpgetx_xid: xid, | |
95 | - command: 'INQUIRY', | |
96 | - request_id: requestId, | |
97 | - terminal_name: terminalName, | |
98 | - product_name: productName, | |
99 | - destination, | |
100 | - rc: '68', | |
101 | - message: 'CORE tidak merespon dengan benar, tidak dapat mengetahui status request anda', | |
102 | - }); | |
103 | - } | |
104 | -}; | |
105 | - | |
106 | -router.all('/', mainHandler); |
lib/listener-partner/routers/pay.js
... | ... | @@ -1,105 +0,0 @@ |
1 | -const axios = require('axios').default; | |
2 | -const express = require('express'); | |
3 | -const coreUrl = require('komodo-sdk/core-url'); | |
4 | - | |
5 | -const config = require('komodo-sdk/config'); | |
6 | -const logger = require('komodo-sdk/logger'); | |
7 | - | |
8 | -const getFromBodyQsParams = require('../../get-from-body-qs-params'); | |
9 | -const ipv6ToIpv4 = require('../../ipv6-to-ipv4'); | |
10 | - | |
11 | -const router = express.Router(); | |
12 | -module.exports = router; | |
13 | - | |
14 | -const CORE_ENDPOINT = `${coreUrl}/postpaid2/pay`; | |
15 | - | |
16 | -const mainHandler = async (req, res) => { | |
17 | - const { xid } = res.locals; | |
18 | - | |
19 | - const requestId = (getFromBodyQsParams(req, 'request_id') || '').toString().trim(); | |
20 | - const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); | |
21 | - const terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; | |
22 | - const productName = (getFromBodyQsParams(req, 'product_name') || '').trim().toUpperCase(); | |
23 | - const destination = (getFromBodyQsParams(req, 'destination') || '').toString().trim(); | |
24 | - const password = getFromBodyQsParams(req, 'password'); | |
25 | - const reverseUrl = getFromBodyQsParams(req, 'reverse_url'); | |
26 | - | |
27 | - if (!requestId || !terminalNameWithoutIp || !productName || !destination) { | |
28 | - res.end('INVALID REQUEST. Missing request_id or terminal_name or product_name or destination.'); | |
29 | - return; | |
30 | - } | |
31 | - | |
32 | - const params = { | |
33 | - origin: config.name, | |
34 | - report_ip: config.listener.core.from_ip, | |
35 | - report_port: config.listener.core.port || 25614, | |
36 | - request_id: requestId, | |
37 | - terminal_name: terminalName, | |
38 | - product_name: productName, | |
39 | - destination, | |
40 | - terminal_password: password, | |
41 | - reverse_url: reverseUrl, | |
42 | - }; | |
43 | - | |
44 | - logger.info('Forwarding PAY request to CORE', { xid, params }); | |
45 | - try { | |
46 | - const result = await axios.get(CORE_ENDPOINT, { | |
47 | - params, | |
48 | - timeout: 10000, | |
49 | - }); | |
50 | - | |
51 | - if (!result || !result.data) { | |
52 | - const newError = new Error('0D428E4C: Empty CORE PAY direct-response'); | |
53 | - logger.warn(newError.message, { xid }); | |
54 | - throw newError; | |
55 | - } | |
56 | - | |
57 | - logger.verbose('Got PAY direct-response from CORE', { | |
58 | - xid, | |
59 | - coreResponse: result.data, | |
60 | - }); | |
61 | - | |
62 | - const resultForPartner = { | |
63 | - httpgetx_xid: xid, | |
64 | - command: result.data.command, | |
65 | - request_id: result.data.request_id && result.data.request_id.toString(), | |
66 | - transaction_id: result.data.transaction_id && result.data.transaction_id.toString(), | |
67 | - transaction_date: result.data.transaction_date, | |
68 | - store_name: result.data.store_name, | |
69 | - terminal_name: result.data.terminal_name, | |
70 | - product_name: result.data.product_name, | |
71 | - destination: result.data.destination, | |
72 | - rc: result.data.rc, | |
73 | - sn: result.data.sn, | |
74 | - message: result.data.message, | |
75 | - amount: result.data.amount, | |
76 | - ending_balance: result.data.ending_balance, | |
77 | - }; | |
78 | - | |
79 | - logger.verbose('Forwarding CORE PAY direct-response to partner', { | |
80 | - xid, | |
81 | - resultForPartner, | |
82 | - }); | |
83 | - | |
84 | - res.json(resultForPartner); | |
85 | - } catch (e) { | |
86 | - logger.warn('EXCEPTION on forwarding PAY request to CORE', { | |
87 | - xid, | |
88 | - errCode: e.code, | |
89 | - errMessage: e.message, | |
90 | - }); | |
91 | - | |
92 | - res.json({ | |
93 | - httpgetx_xid: xid, | |
94 | - command: 'PAY', | |
95 | - request_id: requestId, | |
96 | - terminal_name: terminalName, | |
97 | - product_name: productName, | |
98 | - destination, | |
99 | - rc: '68', | |
100 | - message: 'CORE tidak merespon dengan benar, tidak dapat mengetahui status request anda', | |
101 | - }); | |
102 | - } | |
103 | -}; | |
104 | - | |
105 | -router.all('/', mainHandler); |
lib/listener-partner/routers/topup.js
... | ... | @@ -1,87 +0,0 @@ |
1 | -const express = require('express'); | |
2 | - | |
3 | -const config = require('komodo-sdk/config'); | |
4 | -const logger = require('komodo-sdk/logger'); | |
5 | -const coreapi = require('komodo-sdk/coreapi'); | |
6 | -// const coreapi = require('../../coreapi'); | |
7 | - | |
8 | -const router = express.Router(); | |
9 | -module.exports = router; | |
10 | - | |
11 | -function onInvalidParameter(missingParameter, req, res) { | |
12 | - logger.verbose(`TOPUP: Undefined ${missingParameter} parameter`, { | |
13 | - xid: res.locals.xid, | |
14 | - ip: req.ip, | |
15 | - terminal_name: req.body.terminal_name || req.query.terminal_name, | |
16 | - request_id: req.body.request_id || req.query.request_id, | |
17 | - product_name: req.body.product_name || req.query.product_name, | |
18 | - destination: req.body.destination || req.query.destination, | |
19 | - }); | |
20 | - res.end('INVALID REQUEST'); | |
21 | -} | |
22 | - | |
23 | -function pagePrerequisite(req, res, next) { | |
24 | - if (!req.body) req.body = {}; | |
25 | - | |
26 | - if (!req.body.terminal_name && !req.query.terminal_name) { | |
27 | - onInvalidParameter('terminal_name', req, res); | |
28 | - return; | |
29 | - } | |
30 | - | |
31 | - if (!req.body.password && !req.query.password) { | |
32 | - onInvalidParameter('password', req, res); | |
33 | - return; | |
34 | - } | |
35 | - | |
36 | - if (!req.body.request_id && !req.query.request_id) { | |
37 | - onInvalidParameter('request_id', req, res); | |
38 | - return; | |
39 | - } | |
40 | - | |
41 | - if (!req.body.product_name && !req.query.product_name) { | |
42 | - onInvalidParameter('product_name', req, res); | |
43 | - return; | |
44 | - } | |
45 | - | |
46 | - if (!req.body.destination && !req.query.destination) { | |
47 | - onInvalidParameter('destination', req, res); | |
48 | - return; | |
49 | - } | |
50 | - | |
51 | - next(); | |
52 | -} | |
53 | - | |
54 | -async function pageIndex(req, res) { | |
55 | - const terminalName = `${req.body.terminal_name || req.query.terminal_name}@${req.ip.replace(/^::ffff:/, '')}`; | |
56 | - | |
57 | - const [err, coreResponse] = await coreapi({ | |
58 | - xid: res.locals.xid, | |
59 | - path: '/prepaid/buy', | |
60 | - qs: { | |
61 | - terminal_name: terminalName, | |
62 | - password: req.body.password || req.query.password, | |
63 | - request_id: req.body.request_id || req.query.request_id, | |
64 | - product_name: req.body.product_name || req.query.product_name, | |
65 | - destination: req.body.destination || req.query.destination, | |
66 | - origin: config.name || 'HTTPGETX', | |
67 | - report_ip: config.listener.core.ip || null, | |
68 | - report_port: config.listener.core.port, | |
69 | - reverse_url: req.body.reverse_url || req.query.reverse_url || null, | |
70 | - }, | |
71 | - }); | |
72 | - | |
73 | - logger.verbose('Got CORE response', { xid: res.locals.xid, err, coreResponse }); | |
74 | - | |
75 | - if (err) { | |
76 | - logger.warn('TOPUP: ERROR on /prepaid/buy response', { | |
77 | - xid: res.locals.xid, err, coreResponseTypeof: typeof coreResponse, coreResponse, | |
78 | - }); | |
79 | - res.end('INVALID CORE RESPONSE'); | |
80 | - return; | |
81 | - } | |
82 | - | |
83 | - res.end('OK'); | |
84 | -} | |
85 | - | |
86 | -router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); }); | |
87 | -router.get('/', pagePrerequisite, pageIndex); |
lib/listener-partner/routers/trx-status.js
... | ... | @@ -1,109 +0,0 @@ |
1 | -const express = require('express'); | |
2 | -const moment = require('moment'); | |
3 | - | |
4 | -const logger = require('komodo-sdk/logger'); | |
5 | - | |
6 | -const coreapi = require('../../coreapi'); | |
7 | - | |
8 | -const router = express.Router(); | |
9 | -module.exports = router; | |
10 | - | |
11 | -async function pageIndex(req, res) { | |
12 | - if (!req.body) req.body = {}; | |
13 | - | |
14 | - if (!req.body.terminal_name && !req.query.terminal_name) { | |
15 | - res.json({ | |
16 | - error: 'Parameter terminal_name tidak terdefinisi', | |
17 | - }); | |
18 | - return; | |
19 | - } | |
20 | - | |
21 | - if (!req.body.password && !req.query.password) { | |
22 | - res.json({ | |
23 | - error: true, | |
24 | - message: 'Parameter password tidak terdefinisi', | |
25 | - }); | |
26 | - return; | |
27 | - } | |
28 | - | |
29 | - if (!req.body.request_id && !req.query.request_id) { | |
30 | - res.json({ | |
31 | - error: true, | |
32 | - message: 'Parameter request_id tidak terdefinisi', | |
33 | - }); | |
34 | - return; | |
35 | - } | |
36 | - | |
37 | - const remoteIp = req.ip.replace(/^::ffff:/, ''); | |
38 | - const askerTerminalName = `${req.body.terminal_name || req.query.terminal_name}@${remoteIp}`; | |
39 | - | |
40 | - const coreResponse = await coreapi({ | |
41 | - xid: res.locals.xid, | |
42 | - path: '/trx-status/view', | |
43 | - qs: { | |
44 | - asker_terminal_name: askerTerminalName, | |
45 | - asker_terminal_password: req.body.password || req.query.password, | |
46 | - request_id: req.body.request_id || req.query.request_id, | |
47 | - }, | |
48 | - }); | |
49 | - | |
50 | - if (!coreResponse || !coreResponse.status) { | |
51 | - const msg = 'Status transaksi tidak dapat diketahui karena suatu kesalahan pada sistem'; | |
52 | - | |
53 | - logger.warn(msg, { | |
54 | - xid: res.locals.xid, | |
55 | - ip: req.ip, | |
56 | - terminal_name: req.body.terminal_name || req.query.terminal_name, | |
57 | - request_id: req.body.request_id || req.query.request_id, | |
58 | - }); | |
59 | - | |
60 | - res.json({ | |
61 | - error: true, | |
62 | - from_ip: remoteIp, | |
63 | - terminal_name: req.body.terminal_name || req.query.terminal_name, | |
64 | - full_terminal_name: askerTerminalName, | |
65 | - password: req.body.password || req.query.password, | |
66 | - message: msg, | |
67 | - }); | |
68 | - return; | |
69 | - } | |
70 | - | |
71 | - const trx = coreResponse && coreResponse.result ? { | |
72 | - id: coreResponse.result.id, | |
73 | - request_id: coreResponse.result.request_id, | |
74 | - store_id: coreResponse.result.store_id, | |
75 | - store_name: coreResponse.result.store_name, | |
76 | - terminal_id: coreResponse.result.terminal_id, | |
77 | - terminal_name: coreResponse.result.terminal_name, | |
78 | - | |
79 | - created: moment(coreResponse.result.created).format('YYYY-MM-DD HH:mm:ss'), | |
80 | - modified: moment(coreResponse.result.modified).format('YYYY-MM-DD HH:mm:ss'), | |
81 | - | |
82 | - product_name: coreResponse.result.product_name, | |
83 | - destination: coreResponse.result.destination, | |
84 | - amount: coreResponse.result.amount, | |
85 | - ending_balance: coreResponse.result.ending_balance, | |
86 | - rc: coreResponse.result.rc, | |
87 | - message: coreResponse.result.reply_message, | |
88 | - sn: coreResponse.result.sn, | |
89 | - } | |
90 | - : null; | |
91 | - | |
92 | - const result = { | |
93 | - error: coreResponse.status !== 'OK', | |
94 | - from_ip: remoteIp, | |
95 | - terminal_name: req.body.terminal_name || req.query.terminal_name, | |
96 | - full_terminal_name: askerTerminalName, | |
97 | - password: req.body.password || req.query.password, | |
98 | - message: coreResponse.message, | |
99 | - trx_found: Boolean(trx), | |
100 | - trx, | |
101 | - // original_trx: coreResponse.result, | |
102 | - }; | |
103 | - | |
104 | - res.json(result); | |
105 | - | |
106 | - logger.info('Partner request responded', { xid: res.locals.xid, processing_time_in_ms: new Date() - res.locals.x_http_request_ts, result }); | |
107 | -} | |
108 | - | |
109 | -router.get('/', pageIndex); |
lib/partner-listener/index.js
... | ... | @@ -0,0 +1,36 @@ |
1 | +const DEFAULT_LISTENER_FROM_PARTNER_PORT = 25614; | |
2 | + | |
3 | +const express = require('express'); | |
4 | + | |
5 | +const config = require('komodo-sdk/config'); | |
6 | +const logger = require('komodo-sdk/logger'); | |
7 | + | |
8 | +const middlewareCommon = require('../middlewares/common'); | |
9 | + | |
10 | +const routerInquiry = require('./routers/inquiry'); | |
11 | +const routerPay = require('./routers/pay'); | |
12 | +const routerTopup = require('./routers/topup'); | |
13 | +const routerTrxStatus = require('./routers/trx-status'); | |
14 | + | |
15 | +const app = express(); | |
16 | + | |
17 | +app.use(express.json({ extended: true })); | |
18 | +app.use(express.urlencoded({ extended: true })); | |
19 | +app.use(middlewareCommon); | |
20 | + | |
21 | +app.use('/inquiry', routerInquiry); | |
22 | +app.use('/pay', routerPay); | |
23 | +app.use('/topup', routerTopup); | |
24 | +app.use('/trx-status', routerTrxStatus); | |
25 | + | |
26 | +app.use((req, res) => { | |
27 | + const { xid } = res.locals; | |
28 | + res.status(404).end(`KOMODO-HTTP-GET-X CENTER.\n404: Method not found.\n\nXID: ${xid}.\n`); | |
29 | +}); | |
30 | + | |
31 | +app.listen(config.listener.partner.port || DEFAULT_LISTENER_FROM_PARTNER_PORT, () => { | |
32 | + logger.info(`Listen from partner request on port ${config.listener.partner.port}`); | |
33 | +}).on('error', (e) => { | |
34 | + logger.error(`Can not listen request from partner on port ${config.listener.partner.port || DEFAULT_LISTENER_FROM_PARTNER_PORT}. ${e.toString()}`); | |
35 | + process.exit(1); | |
36 | +}); |
lib/partner-listener/routers/inquiry.js
... | ... | @@ -0,0 +1,106 @@ |
1 | +const axios = require('axios').default; | |
2 | +const express = require('express'); | |
3 | +const coreUrl = require('komodo-sdk/core-url'); | |
4 | + | |
5 | +const config = require('komodo-sdk/config'); | |
6 | +const logger = require('komodo-sdk/logger'); | |
7 | + | |
8 | +const getFromBodyQsParams = require('../../get-from-body-qs-params'); | |
9 | +const ipv6ToIpv4 = require('../../ipv6-to-ipv4'); | |
10 | + | |
11 | +const router = express.Router(); | |
12 | +module.exports = router; | |
13 | + | |
14 | +const CORE_ENDPOINT = `${coreUrl}/postpaid2/inquiry`; | |
15 | + | |
16 | +const mainHandler = async (req, res) => { | |
17 | + const { xid } = res.locals; | |
18 | + | |
19 | + const requestId = (getFromBodyQsParams(req, 'request_id') || '').toString().trim(); | |
20 | + const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); | |
21 | + const terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; | |
22 | + const productName = (getFromBodyQsParams(req, 'product_name') || '').trim().toUpperCase(); | |
23 | + const destination = (getFromBodyQsParams(req, 'destination') || '').toString().trim(); | |
24 | + const password = getFromBodyQsParams(req, 'password'); | |
25 | + const reverseUrl = getFromBodyQsParams(req, 'reverse_url'); | |
26 | + | |
27 | + if (!requestId || !terminalNameWithoutIp || !productName || !destination) { | |
28 | + res.end('INVALID REQUEST. Missing request_id or terminal_name or product_name or destination.'); | |
29 | + return; | |
30 | + } | |
31 | + | |
32 | + const params = { | |
33 | + origin: config.name, | |
34 | + report_ip: config.listener.core.from_ip, | |
35 | + report_port: config.listener.core.port || 25614, | |
36 | + request_id: requestId, | |
37 | + terminal_name: terminalName, | |
38 | + product_name: productName, | |
39 | + destination, | |
40 | + terminal_password: password, | |
41 | + reverse_url: reverseUrl, | |
42 | + }; | |
43 | + | |
44 | + logger.info('Forwarding INQUIRY request to CORE', { xid, params }); | |
45 | + try { | |
46 | + const result = await axios.get(CORE_ENDPOINT, { | |
47 | + params, | |
48 | + timeout: 10000, | |
49 | + }); | |
50 | + | |
51 | + if (!result || !result.data) { | |
52 | + const newError = new Error('8002EB0D: Empty CORE INQUIRY direct-response'); | |
53 | + logger.warn(newError.message, { xid }); | |
54 | + throw newError; | |
55 | + } | |
56 | + | |
57 | + logger.verbose('Got INQUIRY direct-response from CORE', { | |
58 | + xid, | |
59 | + coreResponse: result.data, | |
60 | + }); | |
61 | + | |
62 | + const resultForPartner = { | |
63 | + httpgetx_xid: xid, | |
64 | + command: result.data.command, | |
65 | + request_id: result.data.request_id && result.data.request_id.toString(), | |
66 | + transaction_id: result.data.transaction_id && result.data.transaction_id.toString(), | |
67 | + transaction_date: result.data.transaction_date, | |
68 | + store_name: result.data.store_name, | |
69 | + terminal_name: result.data.terminal_name, | |
70 | + product_name: result.data.product_name, | |
71 | + destination: result.data.destination, | |
72 | + rc: result.data.rc, | |
73 | + sn: result.data.sn, | |
74 | + message: result.data.message, | |
75 | + amount: result.data.amount, | |
76 | + ending_balance: result.data.ending_balance, | |
77 | + amount_to_charge: result.data.amount_to_charge, | |
78 | + }; | |
79 | + | |
80 | + logger.verbose('Forwarding CORE direct-response to partner', { | |
81 | + xid, | |
82 | + resultForPartner, | |
83 | + }); | |
84 | + | |
85 | + res.json(resultForPartner); | |
86 | + } catch (e) { | |
87 | + logger.warn('EXCEPTION on forwarding INQUIRY request to CORE', { | |
88 | + xid, | |
89 | + errCode: e.code, | |
90 | + errMessage: e.message, | |
91 | + }); | |
92 | + | |
93 | + res.json({ | |
94 | + httpgetx_xid: xid, | |
95 | + command: 'INQUIRY', | |
96 | + request_id: requestId, | |
97 | + terminal_name: terminalName, | |
98 | + product_name: productName, | |
99 | + destination, | |
100 | + rc: '68', | |
101 | + message: 'CORE tidak merespon dengan benar, tidak dapat mengetahui status request anda', | |
102 | + }); | |
103 | + } | |
104 | +}; | |
105 | + | |
106 | +router.all('/', mainHandler); |
lib/partner-listener/routers/pay.js
... | ... | @@ -0,0 +1,105 @@ |
1 | +const axios = require('axios').default; | |
2 | +const express = require('express'); | |
3 | +const coreUrl = require('komodo-sdk/core-url'); | |
4 | + | |
5 | +const config = require('komodo-sdk/config'); | |
6 | +const logger = require('komodo-sdk/logger'); | |
7 | + | |
8 | +const getFromBodyQsParams = require('../../get-from-body-qs-params'); | |
9 | +const ipv6ToIpv4 = require('../../ipv6-to-ipv4'); | |
10 | + | |
11 | +const router = express.Router(); | |
12 | +module.exports = router; | |
13 | + | |
14 | +const CORE_ENDPOINT = `${coreUrl}/postpaid2/pay`; | |
15 | + | |
16 | +const mainHandler = async (req, res) => { | |
17 | + const { xid } = res.locals; | |
18 | + | |
19 | + const requestId = (getFromBodyQsParams(req, 'request_id') || '').toString().trim(); | |
20 | + const terminalNameWithoutIp = (getFromBodyQsParams(req, 'terminal_name') || '').toString().trim(); | |
21 | + const terminalName = `${terminalNameWithoutIp}@${ipv6ToIpv4(req.ip)}`; | |
22 | + const productName = (getFromBodyQsParams(req, 'product_name') || '').trim().toUpperCase(); | |
23 | + const destination = (getFromBodyQsParams(req, 'destination') || '').toString().trim(); | |
24 | + const password = getFromBodyQsParams(req, 'password'); | |
25 | + const reverseUrl = getFromBodyQsParams(req, 'reverse_url'); | |
26 | + | |
27 | + if (!requestId || !terminalNameWithoutIp || !productName || !destination) { | |
28 | + res.end('INVALID REQUEST. Missing request_id or terminal_name or product_name or destination.'); | |
29 | + return; | |
30 | + } | |
31 | + | |
32 | + const params = { | |
33 | + origin: config.name, | |
34 | + report_ip: config.listener.core.from_ip, | |
35 | + report_port: config.listener.core.port || 25614, | |
36 | + request_id: requestId, | |
37 | + terminal_name: terminalName, | |
38 | + product_name: productName, | |
39 | + destination, | |
40 | + terminal_password: password, | |
41 | + reverse_url: reverseUrl, | |
42 | + }; | |
43 | + | |
44 | + logger.info('Forwarding PAY request to CORE', { xid, params }); | |
45 | + try { | |
46 | + const result = await axios.get(CORE_ENDPOINT, { | |
47 | + params, | |
48 | + timeout: 10000, | |
49 | + }); | |
50 | + | |
51 | + if (!result || !result.data) { | |
52 | + const newError = new Error('0D428E4C: Empty CORE PAY direct-response'); | |
53 | + logger.warn(newError.message, { xid }); | |
54 | + throw newError; | |
55 | + } | |
56 | + | |
57 | + logger.verbose('Got PAY direct-response from CORE', { | |
58 | + xid, | |
59 | + coreResponse: result.data, | |
60 | + }); | |
61 | + | |
62 | + const resultForPartner = { | |
63 | + httpgetx_xid: xid, | |
64 | + command: result.data.command, | |
65 | + request_id: result.data.request_id && result.data.request_id.toString(), | |
66 | + transaction_id: result.data.transaction_id && result.data.transaction_id.toString(), | |
67 | + transaction_date: result.data.transaction_date, | |
68 | + store_name: result.data.store_name, | |
69 | + terminal_name: result.data.terminal_name, | |
70 | + product_name: result.data.product_name, | |
71 | + destination: result.data.destination, | |
72 | + rc: result.data.rc, | |
73 | + sn: result.data.sn, | |
74 | + message: result.data.message, | |
75 | + amount: result.data.amount, | |
76 | + ending_balance: result.data.ending_balance, | |
77 | + }; | |
78 | + | |
79 | + logger.verbose('Forwarding CORE PAY direct-response to partner', { | |
80 | + xid, | |
81 | + resultForPartner, | |
82 | + }); | |
83 | + | |
84 | + res.json(resultForPartner); | |
85 | + } catch (e) { | |
86 | + logger.warn('EXCEPTION on forwarding PAY request to CORE', { | |
87 | + xid, | |
88 | + errCode: e.code, | |
89 | + errMessage: e.message, | |
90 | + }); | |
91 | + | |
92 | + res.json({ | |
93 | + httpgetx_xid: xid, | |
94 | + command: 'PAY', | |
95 | + request_id: requestId, | |
96 | + terminal_name: terminalName, | |
97 | + product_name: productName, | |
98 | + destination, | |
99 | + rc: '68', | |
100 | + message: 'CORE tidak merespon dengan benar, tidak dapat mengetahui status request anda', | |
101 | + }); | |
102 | + } | |
103 | +}; | |
104 | + | |
105 | +router.all('/', mainHandler); |
lib/partner-listener/routers/topup.js
... | ... | @@ -0,0 +1,87 @@ |
1 | +const express = require('express'); | |
2 | + | |
3 | +const config = require('komodo-sdk/config'); | |
4 | +const logger = require('komodo-sdk/logger'); | |
5 | +const coreapi = require('komodo-sdk/coreapi'); | |
6 | +// const coreapi = require('../../coreapi'); | |
7 | + | |
8 | +const router = express.Router(); | |
9 | +module.exports = router; | |
10 | + | |
11 | +function onInvalidParameter(missingParameter, req, res) { | |
12 | + logger.verbose(`TOPUP: Undefined ${missingParameter} parameter`, { | |
13 | + xid: res.locals.xid, | |
14 | + ip: req.ip, | |
15 | + terminal_name: req.body.terminal_name || req.query.terminal_name, | |
16 | + request_id: req.body.request_id || req.query.request_id, | |
17 | + product_name: req.body.product_name || req.query.product_name, | |
18 | + destination: req.body.destination || req.query.destination, | |
19 | + }); | |
20 | + res.end('INVALID REQUEST'); | |
21 | +} | |
22 | + | |
23 | +function pagePrerequisite(req, res, next) { | |
24 | + if (!req.body) req.body = {}; | |
25 | + | |
26 | + if (!req.body.terminal_name && !req.query.terminal_name) { | |
27 | + onInvalidParameter('terminal_name', req, res); | |
28 | + return; | |
29 | + } | |
30 | + | |
31 | + if (!req.body.password && !req.query.password) { | |
32 | + onInvalidParameter('password', req, res); | |
33 | + return; | |
34 | + } | |
35 | + | |
36 | + if (!req.body.request_id && !req.query.request_id) { | |
37 | + onInvalidParameter('request_id', req, res); | |
38 | + return; | |
39 | + } | |
40 | + | |
41 | + if (!req.body.product_name && !req.query.product_name) { | |
42 | + onInvalidParameter('product_name', req, res); | |
43 | + return; | |
44 | + } | |
45 | + | |
46 | + if (!req.body.destination && !req.query.destination) { | |
47 | + onInvalidParameter('destination', req, res); | |
48 | + return; | |
49 | + } | |
50 | + | |
51 | + next(); | |
52 | +} | |
53 | + | |
54 | +async function pageIndex(req, res) { | |
55 | + const terminalName = `${req.body.terminal_name || req.query.terminal_name}@${req.ip.replace(/^::ffff:/, '')}`; | |
56 | + | |
57 | + const [err, coreResponse] = await coreapi({ | |
58 | + xid: res.locals.xid, | |
59 | + path: '/prepaid/buy', | |
60 | + qs: { | |
61 | + terminal_name: terminalName, | |
62 | + password: req.body.password || req.query.password, | |
63 | + request_id: req.body.request_id || req.query.request_id, | |
64 | + product_name: req.body.product_name || req.query.product_name, | |
65 | + destination: req.body.destination || req.query.destination, | |
66 | + origin: config.name || 'HTTPGETX', | |
67 | + report_ip: config.listener.core.ip || null, | |
68 | + report_port: config.listener.core.port, | |
69 | + reverse_url: req.body.reverse_url || req.query.reverse_url || null, | |
70 | + }, | |
71 | + }); | |
72 | + | |
73 | + logger.verbose('Got CORE response', { xid: res.locals.xid, err, coreResponse }); | |
74 | + | |
75 | + if (err) { | |
76 | + logger.warn('TOPUP: ERROR on /prepaid/buy response', { | |
77 | + xid: res.locals.xid, err, coreResponseTypeof: typeof coreResponse, coreResponse, | |
78 | + }); | |
79 | + res.end('INVALID CORE RESPONSE'); | |
80 | + return; | |
81 | + } | |
82 | + | |
83 | + res.end('OK'); | |
84 | +} | |
85 | + | |
86 | +router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); }); | |
87 | +router.get('/', pagePrerequisite, pageIndex); |
lib/partner-listener/routers/trx-status.js
... | ... | @@ -0,0 +1,109 @@ |
1 | +const express = require('express'); | |
2 | +const moment = require('moment'); | |
3 | + | |
4 | +const logger = require('komodo-sdk/logger'); | |
5 | + | |
6 | +const coreapi = require('../../coreapi'); | |
7 | + | |
8 | +const router = express.Router(); | |
9 | +module.exports = router; | |
10 | + | |
11 | +async function pageIndex(req, res) { | |
12 | + if (!req.body) req.body = {}; | |
13 | + | |
14 | + if (!req.body.terminal_name && !req.query.terminal_name) { | |
15 | + res.json({ | |
16 | + error: 'Parameter terminal_name tidak terdefinisi', | |
17 | + }); | |
18 | + return; | |
19 | + } | |
20 | + | |
21 | + if (!req.body.password && !req.query.password) { | |
22 | + res.json({ | |
23 | + error: true, | |
24 | + message: 'Parameter password tidak terdefinisi', | |
25 | + }); | |
26 | + return; | |
27 | + } | |
28 | + | |
29 | + if (!req.body.request_id && !req.query.request_id) { | |
30 | + res.json({ | |
31 | + error: true, | |
32 | + message: 'Parameter request_id tidak terdefinisi', | |
33 | + }); | |
34 | + return; | |
35 | + } | |
36 | + | |
37 | + const remoteIp = req.ip.replace(/^::ffff:/, ''); | |
38 | + const askerTerminalName = `${req.body.terminal_name || req.query.terminal_name}@${remoteIp}`; | |
39 | + | |
40 | + const coreResponse = await coreapi({ | |
41 | + xid: res.locals.xid, | |
42 | + path: '/trx-status/view', | |
43 | + qs: { | |
44 | + asker_terminal_name: askerTerminalName, | |
45 | + asker_terminal_password: req.body.password || req.query.password, | |
46 | + request_id: req.body.request_id || req.query.request_id, | |
47 | + }, | |
48 | + }); | |
49 | + | |
50 | + if (!coreResponse || !coreResponse.status) { | |
51 | + const msg = 'Status transaksi tidak dapat diketahui karena suatu kesalahan pada sistem'; | |
52 | + | |
53 | + logger.warn(msg, { | |
54 | + xid: res.locals.xid, | |
55 | + ip: req.ip, | |
56 | + terminal_name: req.body.terminal_name || req.query.terminal_name, | |
57 | + request_id: req.body.request_id || req.query.request_id, | |
58 | + }); | |
59 | + | |
60 | + res.json({ | |
61 | + error: true, | |
62 | + from_ip: remoteIp, | |
63 | + terminal_name: req.body.terminal_name || req.query.terminal_name, | |
64 | + full_terminal_name: askerTerminalName, | |
65 | + password: req.body.password || req.query.password, | |
66 | + message: msg, | |
67 | + }); | |
68 | + return; | |
69 | + } | |
70 | + | |
71 | + const trx = coreResponse && coreResponse.result ? { | |
72 | + id: coreResponse.result.id, | |
73 | + request_id: coreResponse.result.request_id, | |
74 | + store_id: coreResponse.result.store_id, | |
75 | + store_name: coreResponse.result.store_name, | |
76 | + terminal_id: coreResponse.result.terminal_id, | |
77 | + terminal_name: coreResponse.result.terminal_name, | |
78 | + | |
79 | + created: moment(coreResponse.result.created).format('YYYY-MM-DD HH:mm:ss'), | |
80 | + modified: moment(coreResponse.result.modified).format('YYYY-MM-DD HH:mm:ss'), | |
81 | + | |
82 | + product_name: coreResponse.result.product_name, | |
83 | + destination: coreResponse.result.destination, | |
84 | + amount: coreResponse.result.amount, | |
85 | + ending_balance: coreResponse.result.ending_balance, | |
86 | + rc: coreResponse.result.rc, | |
87 | + message: coreResponse.result.reply_message, | |
88 | + sn: coreResponse.result.sn, | |
89 | + } | |
90 | + : null; | |
91 | + | |
92 | + const result = { | |
93 | + error: coreResponse.status !== 'OK', | |
94 | + from_ip: remoteIp, | |
95 | + terminal_name: req.body.terminal_name || req.query.terminal_name, | |
96 | + full_terminal_name: askerTerminalName, | |
97 | + password: req.body.password || req.query.password, | |
98 | + message: coreResponse.message, | |
99 | + trx_found: Boolean(trx), | |
100 | + trx, | |
101 | + // original_trx: coreResponse.result, | |
102 | + }; | |
103 | + | |
104 | + res.json(result); | |
105 | + | |
106 | + logger.info('Partner request responded', { xid: res.locals.xid, processing_time_in_ms: new Date() - res.locals.x_http_request_ts, result }); | |
107 | +} | |
108 | + | |
109 | +router.get('/', pageIndex); |