Commit 1ae80ad7feb59a2de28788a112d17e660745e6a5

Authored by Adhidarma Hadiwinoto
1 parent 45a958ee44
Exists in master and in 1 other branch dev

Refactor to partner-listener

Showing 11 changed files with 444 additions and 444 deletions Side-by-side Diff

... ... @@ -28,5 +28,5 @@ if (config.cluster && cluster.isMaster) {
28 28 // eslint-disable-next-line global-require
29 29 require('./lib/core-callback');
30 30 // eslint-disable-next-line global-require
31   - require('./lib/listener-partner');
  31 + require('./lib/partner-listener');
32 32 }
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);