Commit 5443b922a7960d4a2770198890a3b3188bcd4088

Authored by adi surya
1 parent c6ed7016e1
Exists in master

file lib

Showing 29 changed files with 1244 additions and 0 deletions Inline Diff

1 node_modules 1 node_modules
2 config.json
File was created 1 {
2 "name": "gateway-sds-ss",
3 "url": "http://localhost",
4 "port": 11330,
5 "apikey": "fd97cf519b979262d9d9004cba6a165629ca8b69350a6afdcaab6ab2c9a996ae",
6 "pull_interval_ms": 5000,
7 "core": {
8 "url": "http://localhost:26840",
9 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJnZW5lcmF0b3IiOiJDTEkiLCJjbGllbnQiOnsibmFtZSI6IktPTU9ETzItR1ctU0RTLVNTIn0sImlhdCI6MTY1ODkwODA4N30.2Ego28jwgPs3s9-iKSbYipO72FTH5gFC5gkVccqiN24",
10 "request_timeout_ms": 10000
11 },
12 "products": {
13 },
14 "postpaid_products": {
15 },
16 "sds_ss": {
17 "url": "http://localhost:8187/request",
18 "request_timeout_ms": 10000,
19 "username": "user",
20 "password": "1234"
21 }
22 }
23
File was created 1 process.chdir(__dirname);
2
3 const fs = require('fs');
4 const pull = require('./lib/pull');
5 require('./lib/http-server');
6
7 pull.run();
8
9 fs.writeFileSync('pid.txt', process.pid.toString());
10
File was created 1 const MODULE_NAME = 'ACTIONS.BUY';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7 const configData = require('../config/data');
8
9 const topupToKomodo = require('./topup-to-komodo');
10
11 const client = axios.create({
12 baseURL: config.core.url,
13 timeout: config.core.request_timeout_ms,
14 headers: {
15 'x-access-token': config.core.access_token,
16 },
17 });
18
19 /**
20 * Buy a product from supplier komodo
21 *
22 * @param {string} xid
23 * @param {object} transaction
24 *
25 */
26 module.exports = async (xid, transaction) => {
27 try {
28 logger.verbose(`${MODULE_NAME} 4B139379: Buy product to komodo`, {
29 xid,
30 transaction,
31 });
32 const iConfig = await configData.all();
33
34 let productName = transaction.product_name;
35 if (
36 iConfig.products[transaction.product_name]
37 && iConfig.products[transaction.product_name].remote
38 ) {
39 productName = iConfig.products[transaction.product_name].remote;
40 }
41
42 const callbackUrl = `${iConfig.url}:${iConfig.port}/apikey/${iConfig.apikey}/updates`;
43 const result = await topupToKomodo(
44 xid,
45 transaction.id,
46 transaction.destination,
47 productName,
48 callbackUrl,
49 );
50 logger.verbose(`${MODULE_NAME} 5BDFAF41: result from komodo`, {
51 xid,
52 trxId: transaction.id,
53 result,
54 });
55 const params = {
56 id: result.request_id,
57 rc: result.rc,
58 amount: result.amount || null,
59 message: result.message,
60 sn: result.sn || null,
61 };
62
63 await client.post('/transactions/gateway-update', params);
64 } catch (e) {
65 logger.warn(`${MODULE_NAME} E9887C98: Exception`, {
66 xid,
67 message: e.message,
68 code: e.code,
69 });
70 }
71 };
72
lib/actions/index.js
File was created 1 exports.buy = require('./buy');
2 exports.inquiry = require('./inquiry');
3 exports.pay = require('./pay');
4
lib/actions/inquiry-to-komodo.js
File was created 1 const MODULE_NAME = 'ACTIONS.INQUIRY-TO-KOMODO';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7
8 const client = axios.create({
9 baseURL: config.komodo_http_get_x.url,
10 timeout: config.komodo_http_get_x.request_timeout_ms,
11 });
12
13 /**
14 * request inquiry transaction to komodo
15 *
16 * @param {string} xid
17 * @param {string} requestId
18 * @param {string} destination
19 * @param {string} productName
20 * @param {string} reverseUrl
21 */
22 module.exports = async (
23 xid,
24 requestId,
25 destination,
26 productName,
27 reverseUrl,
28 ) => {
29 logger.verbose(`${MODULE_NAME} 4AD4DF41: request inquiry to komodo`, {
30 requestId, destination, productName, reverseUrl, xid,
31 });
32
33 const params = {
34 request_id: requestId,
35 terminal_name: config.komodo_http_get_x.terminal_name,
36 password: config.komodo_http_get_x.password,
37 destination,
38 product_name: productName,
39 reverse_url: reverseUrl,
40 };
41
42 try {
43 const response = await client.get('/inquiry', {
44 params,
45 });
46 if (!response) {
47 throw new Error(`${MODULE_NAME} 6CE3E06E: Empty response from komodo`);
48 }
49 if (!response.data) {
50 throw new Error(`${MODULE_NAME} F236476F: Empty response data from komodo`);
51 }
52
53 return response.data;
54 } catch (err) {
55 logger.warn(`${MODULE_NAME} 48BAA6B7: Exception`, {
56 xid,
57 requestId,
58 destination,
59 productName,
60 message: err.message,
61 });
62 throw err;
63 }
64 };
65
lib/actions/inquiry.js
File was created 1 const MODULE_NAME = 'ACTIONS.INQUIRY';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7 const configData = require('../config/data');
8
9 const inquiryToKomodo = require('./inquiry-to-komodo');
10
11 const client = axios.create({
12 baseURL: config.core.url,
13 timeout: config.core.request_timeout_ms,
14 headers: {
15 'x-access-token': config.core.access_token,
16 },
17 });
18
19 /**
20 * Inquiry a product from supplier komodo
21 *
22 * @param {string} xid
23 * @param {object} transaction
24 *
25 */
26 module.exports = async (xid, transaction) => {
27 try {
28 logger.verbose(`${MODULE_NAME} ABE82225: Inquiry product to komodo`, {
29 xid,
30 transaction,
31 });
32 const iConfig = await configData.all();
33
34 let productName = transaction.product_name;
35 if (
36 iConfig.postpaid_products[transaction.product_name]
37 && iConfig.postpaid_products[transaction.product_name].remote
38 ) {
39 productName = iConfig.postpaid_products[transaction.product_name].remote;
40 }
41
42 const callbackUrl = `${iConfig.url}:${iConfig.port}/apikey/${iConfig.apikey}/updates`;
43 const result = await inquiryToKomodo(
44 xid,
45 transaction.id,
46 transaction.destination,
47 productName,
48 callbackUrl,
49 );
50 logger.verbose(`${MODULE_NAME} 076C1206: result from komodo`, {
51 xid,
52 trxId: transaction.id,
53 result,
54 });
55 const params = {
56 id: result.request_id,
57 rc: result.rc,
58 amount: result.amount || null,
59 message: result.message,
60 sn: result.sn || null,
61 };
62
63 await client.post('/transactions/gateway-update', params);
64 } catch (e) {
65 logger.warn(`${MODULE_NAME} D1A1B698: Exception`, {
66 xid,
67 message: e.message,
68 code: e.code,
69 });
70 }
71 };
72
File was created 1 const MODULE_NAME = 'ACTIONS.PAY';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7 const configData = require('../config/data');
8
9 const paymentToKomodo = require('./payment-to-komodo');
10
11 const client = axios.create({
12 baseURL: config.core.url,
13 timeout: config.core.request_timeout_ms,
14 headers: {
15 'x-access-token': config.core.access_token,
16 },
17 });
18
19 /**
20 * Pay a product from supplier komodo
21 *
22 * @param {string} xid
23 * @param {object} transaction
24 *
25 */
26 module.exports = async (xid, transaction) => {
27 try {
28 logger.verbose(`${MODULE_NAME} CB9506E9: Pay product to komodo`, {
29 xid,
30 transaction,
31 });
32 const iConfig = await configData.all();
33
34 let productName = transaction.product_name;
35 if (
36 iConfig.postpaid_products[transaction.product_name]
37 && iConfig.postpaid_products[transaction.product_name].remote
38 ) {
39 productName = iConfig.postpaid_products[transaction.product_name].remote;
40 }
41
42 const callbackUrl = `${iConfig.url}:${iConfig.port}/apikey/${iConfig.apikey}/updates`;
43 const result = await paymentToKomodo(
44 xid,
45 transaction.id,
46 transaction.destination,
47 productName,
48 callbackUrl,
49 );
50 logger.verbose(`${MODULE_NAME} 4F45F9E3: result from komodo`, {
51 xid,
52 trxId: transaction.id,
53 result,
54 });
55 const params = {
56 id: result.request_id,
57 rc: result.rc,
58 amount: result.amount || null,
59 message: result.message,
60 sn: result.sn || null,
61 };
62
63 await client.post('/transactions/gateway-update', params);
64 } catch (e) {
65 logger.warn(`${MODULE_NAME} EF0EE887: Exception`, {
66 xid,
67 message: e.message,
68 code: e.code,
69 });
70 }
71 };
72
lib/actions/payment-to-komodo.js
File was created 1 const MODULE_NAME = 'ACTIONS.PAY-TO-KOMODO';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7
8 const client = axios.create({
9 baseURL: config.komodo_http_get_x.url,
10 timeout: config.komodo_http_get_x.request_timeout_ms,
11 });
12
13 /**
14 * request pay transaction to komodo
15 *
16 * @param {string} xid
17 * @param {string} requestId
18 * @param {string} destination
19 * @param {string} productName
20 * @param {string} reverseUrl
21 */
22 module.exports = async (
23 xid,
24 requestId,
25 destination,
26 productName,
27 reverseUrl,
28 ) => {
29 logger.verbose(`${MODULE_NAME} 740EF164: pay to komodo`, {
30 requestId, destination, productName, xid,
31 });
32
33 const params = {
34 request_id: requestId,
35 terminal_name: config.komodo_http_get_x.terminal_name,
36 password: config.komodo_http_get_x.password,
37 destination,
38 product_name: productName,
39 reverse_url: reverseUrl,
40 };
41
42 try {
43 const response = await client.get('/pay', {
44 params,
45 });
46 if (!response) {
47 throw new Error(`${MODULE_NAME} 29D8D56F: Empty response from komodo`);
48 }
49 if (!response.data) {
50 throw new Error(`${MODULE_NAME} 288CD049: Empty response data from komodo`);
51 }
52
53 return response.data;
54 } catch (err) {
55 logger.warn(`${MODULE_NAME} DCE65215: Exception`, {
56 xid,
57 requestId,
58 destination,
59 productName,
60 message: err.message,
61 });
62 throw err;
63 }
64 };
65
lib/actions/topup-to-komodo.js
File was created 1 const MODULE_NAME = 'ACTIONS.TOPUP-TO-KOMODO';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5
6 const config = require('../config');
7
8 const client = axios.create({
9 baseURL: config.komodo_http_get_x.url,
10 timeout: config.komodo_http_get_x.request_timeout_ms,
11 });
12
13 /**
14 * request topup transaction to komodo
15 *
16 * @param {string} xid
17 * @param {string} requestId
18 * @param {string} destination
19 * @param {string} productName
20 * @param {string} reverseUrl
21 */
22 module.exports = async (
23 xid,
24 requestId,
25 destination,
26 productName,
27 reverseUrl,
28 ) => {
29 logger.verbose(`${MODULE_NAME} 4AD4DF41: topup to komodo`, {
30 requestId, destination, productName, xid,
31 });
32
33 const params = {
34 request_id: requestId,
35 terminal_name: config.komodo_http_get_x.terminal_name,
36 password: config.komodo_http_get_x.password,
37 destination,
38 product_name: productName,
39 reverse_url: reverseUrl,
40 };
41
42 try {
43 const response = await client.get('/topup', {
44 params,
45 });
46 if (!response) {
47 throw new Error(`${MODULE_NAME} 6CE3E06E: Empty response from komodo`);
48 }
49 if (!response.data) {
50 throw new Error(`${MODULE_NAME} F236476F: Empty response data from komodo`);
51 }
52
53 return response.data;
54 } catch (err) {
55 logger.warn(`${MODULE_NAME} 48BAA6B7: Exception`, {
56 xid,
57 requestId,
58 destination,
59 productName,
60 message: err.message,
61 });
62 throw err;
63 }
64 };
65
File was created 1 const MODULE_NAME = 'CONFIG.DATA';
2
3 const fs = require('fs/promises');
4 const logger = require('tektrans-logger');
5
6 let config = {};
7
8 /**
9 * Get all config
10 *
11 * @param {string} xid
12 *
13 * @returns <object>
14 */
15 async function all(xid) {
16 try {
17 if (Object.keys(config).length === 0) {
18 const configString = await fs.readFile('config.json');
19 config = JSON.parse(configString);
20 }
21 } catch (e) {
22 logger.warn(`${MODULE_NAME} ED8D390C: Exception`, {
23 xid,
24 eMessage: e.message,
25 eCode: e.code,
26 });
27 }
28 return config;
29 }
30
31 /**
32 * Get active product prepaid config
33 *
34 * @param {string} xid
35 *
36 * @returns <Array>
37 */
38 async function getActiveProductArray(xid) {
39 try {
40 if (Object.keys(config).length === 0) {
41 const configString = await fs.readFile('config.json');
42 config = JSON.parse(configString);
43 }
44 const allProductsArray = Object.values(config.products);
45 if (Array.isArray(allProductsArray)) {
46 const activeProductArray = allProductsArray.filter((val) => val.active === 1);
47 const activeProductNameArray = activeProductArray.map((val) => val.name);
48 return activeProductNameArray;
49 }
50 } catch (e) {
51 logger.warn(`${MODULE_NAME} 2D49D035: Exception`, {
52 xid,
53 eMessage: e.message,
54 eCode: e.code,
55 });
56 }
57 return [];
58 }
59
60 /**
61 * Get active product postpaid config
62 *
63 * @param {string} xid
64 *
65 * @returns <Array>
66 */
67 async function getActiveProductPostpaidArray(xid) {
68 try {
69 if (Object.keys(config).length === 0) {
70 const configString = await fs.readFile('config.json');
71 config = JSON.parse(configString);
72 }
73 const allProductsArray = Object.values(config.postpaid_products);
74 if (Array.isArray(allProductsArray)) {
75 const activeProductArray = allProductsArray.filter((val) => val.active === 1);
76 const activeProductNameArray = activeProductArray.map((val) => val.name);
77 return activeProductNameArray;
78 }
79 } catch (e) {
80 logger.warn(`${MODULE_NAME} B5414DB0: Exception`, {
81 xid,
82 eMessage: e.message,
83 eCode: e.code,
84 });
85 }
86 return [];
87 }
88
89 /**
90 * Reload config
91 *
92 * @param {string} xid
93 *
94 * @returns <object>
95 */
96 async function reload(xid) {
97 try {
98 const configString = await fs.readFile('config.json');
99 config = JSON.parse(configString);
100 } catch (e) {
101 logger.warn(`${MODULE_NAME} D005AED3: Exception`, {
102 xid,
103 eMessage: e.message,
104 eCode: e.code,
105 });
106 }
107 return config;
108 }
109
110 exports.all = all;
111 exports.reload = reload;
112 exports.getActiveProductArray = getActiveProductArray;
113 exports.getActiveProductPostpaidArray = getActiveProductPostpaidArray;
114
File was created 1 const data = require('../../config.json');
2
3 module.exports = data;
4
lib/config/remove-postpaid-product.js
File was created 1 const MODULE_NAME = 'CONFIG.REMOVE-POSTPAID-PRODUCT';
2
3 const fs = require('fs/promises');
4 const logger = require('tektrans-logger');
5
6 const configData = require('./data');
7
8 /**
9 * Menghapus nilai terkini config.products (postpaid)
10 *
11 * @param {string} name
12 *
13 */
14 module.exports = async (xid, name) => {
15 try {
16 logger.verbose(`${MODULE_NAME} B4361668: remove postpaid product from config file`, {
17 xid,
18 key: name,
19 });
20 const config = await configData.reload();
21
22 delete config.postpaid_products[name];
23 await fs.writeFile('config.json', JSON.stringify(config, null, 4));
24
25 await configData.reload();
26 } catch (e) {
27 logger.warn(`${MODULE_NAME} 9E5C6976: Exception`, {
28 xid,
29 eCode: e.code,
30 eMessage: e.message,
31 });
32 }
33 };
34
lib/config/remove-product.js
File was created 1 const MODULE_NAME = 'CONFIG.REMOVE-PREPAID-PRODUCT';
2
3 const fs = require('fs/promises');
4 const logger = require('tektrans-logger');
5
6 const configData = require('./data');
7
8 /**
9 * Menghapus nilai terkini config.products (prepaid)
10 *
11 * @param {string} name
12 *
13 */
14 module.exports = async (xid, name) => {
15 try {
16 logger.verbose(`${MODULE_NAME} 80D1628F: remove prepaid product from config file`, {
17 xid,
18 key: name,
19 });
20 const config = await configData.reload();
21
22 delete config.products[name];
23 await fs.writeFile('config.json', JSON.stringify(config, null, 4));
24
25 await configData.reload();
26 } catch (e) {
27 logger.warn(`${MODULE_NAME} 190BD3D7: Exception`, {
28 xid,
29 eCode: e.code,
30 eMessage: e.message,
31 });
32 }
33 };
34
lib/config/save-postpaid-product.js
File was created 1 const MODULE_NAME = 'CONFIG.SAVE-POSTPAID-PRODUCT';
2
3 const fs = require('fs/promises');
4 const logger = require('tektrans-logger');
5
6 const configData = require('./data');
7
8 /**
9 * Menyimpan nilai terkini config.products (postpaid)
10 *
11 */
12 module.exports = async (xid, key, value) => {
13 try {
14 logger.verbose(`${MODULE_NAME} 19BB0554: Saving postpaid product to config file`, {
15 xid,
16 key,
17 value,
18 });
19 const config = await configData.reload();
20
21 config.postpaid_products[key] = value;
22 await fs.writeFile('config.json', JSON.stringify(config, null, 4));
23
24 await configData.reload();
25 } catch (e) {
26 logger.warn(`${MODULE_NAME} D0F796A6: Exception`, {
27 xid,
28 eCode: e.code,
29 eMessage: e.message,
30 });
31 }
32 };
33
lib/config/save-product.js
File was created 1 const MODULE_NAME = 'CONFIG.SAVE-PREPAID-PRODUCT';
2
3 const fs = require('fs/promises');
4 const logger = require('tektrans-logger');
5
6 const configData = require('./data');
7
8 /**
9 * Menyimpan nilai terkini config.products (prepaid)
10 *
11 */
12 module.exports = async (xid, key, value) => {
13 try {
14 logger.verbose(`${MODULE_NAME} C6D936BF: Saving prepaid product to config file`, {
15 xid,
16 key,
17 value,
18 });
19 const config = await configData.reload();
20
21 config.products[key] = value;
22 await fs.writeFile('config.json', JSON.stringify(config, null, 4));
23
24 await configData.reload();
25 } catch (e) {
26 logger.warn(`${MODULE_NAME} 1D1937A9: Exception`, {
27 xid,
28 eCode: e.code,
29 eMessage: e.message,
30 });
31 }
32 };
33
lib/http-server/index.js
File was created 1 const MODULE_NAME = 'HTTP-SERVER';
2
3 const express = require('express');
4 const uniqid = require('uniqid');
5 const logger = require('tektrans-logger');
6
7 const config = require('../config');
8 const matrix = require('../matrix');
9 const checkApikey = require('./middlewares/check-apikey');
10
11 const routerMatrix = require('./routers/matrix');
12 const routerUpdates = require('./routers/updates');
13 const routerProducts = require('./routers/products');
14 const routerPostpaidProducts = require('./routers/postpaid-products');
15
16 const app = express();
17
18 app.use((req, res, next) => {
19 matrix.httpServer.requestCounter += 1;
20 res.locals.xid = uniqid();
21
22 next();
23 });
24
25 app.use('/matrix', routerMatrix);
26 app.use('/apikey/:apikey/updates', [checkApikey], routerUpdates);
27 app.use('/apikey/:apikey/products', [checkApikey], routerProducts);
28 app.use('/apikey/:apikey/postpaid/products', [checkApikey], routerPostpaidProducts);
29
30 app.use((req, res) => {
31 res.status(404).json({
32 error: true,
33 message: 'Method/service not found',
34 });
35 });
36
37 const { port } = config;
38 app.listen(port, () => {
39 logger.info(`${MODULE_NAME} 35069698: Listening`, { port });
40 });
41
lib/http-server/middlewares/check-apikey.js
File was created 1 const config = require('../../config');
2
3 module.exports = async (req, res, next) => {
4 const { apikey } = req.params;
5
6 if (!config.apikey) {
7 next();
8 } else if (config.apikey === apikey) {
9 next();
10 } else {
11 res.status(403).json({
12 error: true,
13 message: 'Invalid apikey',
14 });
15 }
16 };
17
lib/http-server/routers/matrix.js
File was created 1 const express = require('express');
2
3 const matrixDump = require('../../matrix/dump');
4
5 const router = express.Router();
6 module.exports = router;
7
8 const pageMain = (req, res) => {
9 res.json(matrixDump());
10 };
11
12 router.all('/', pageMain);
13
lib/http-server/routers/postpaid-products/index.js
File was created 1 const MODULE_NAME = 'HTTP-SERVER.ROUTER.POSTPAID-PRODUCTS';
2
3 const express = require('express');
4 const logger = require('tektrans-logger');
5
6 const configData = require('../../../config/data');
7 const configSaveProduct = require('../../../config/save-postpaid-product');
8 const configRemoveProduct = require('../../../config/remove-postpaid-product');
9
10 const router = express.Router();
11
12 module.exports = router;
13
14 const pageIndex = async (req, res) => {
15 const { xid } = res.locals;
16 try {
17 logger.verbose(`${MODULE_NAME} 24D7D9B4: get postpaid product configuration`, { xid });
18 const products = (await configData.all()).postpaid_products || {};
19 res.json({ error: false, message: 'OK', result: products });
20 } catch (e) {
21 logger.warn(`${MODULE_NAME} 1DB45AC5: Exception.`, {
22 xid, eMessage: e.message, eCode: e.code,
23 });
24 res.status(500).json({
25 error: true,
26 error_code: e.code,
27 message: e.message,
28 });
29 }
30 };
31
32 const pageSave = async (req, res) => {
33 const { xid } = res.locals;
34 const { name, remote = null, active = 0 } = req.body;
35 try {
36 logger.verbose(`${MODULE_NAME} A083E9DC: save postpaid product configuration`, { xid, data: req.body });
37
38 const params = {
39 name,
40 remote,
41 active,
42 };
43 await configSaveProduct(xid, name, params);
44 res.json({ error: false, message: 'OK' });
45 } catch (e) {
46 logger.warn(`${MODULE_NAME} 88B9218F: Exception.`, {
47 xid, eMessage: e.message, eCode: e.code,
48 });
49 res.status(500).json({
50 error: true,
51 error_code: e.code,
52 message: e.message,
53 });
54 }
55 };
56
57 const pageRemove = async (req, res) => {
58 const { xid } = res.locals;
59 const { name } = req.body;
60 try {
61 logger.verbose(`${MODULE_NAME} 7AD392AE: remove postpaid product configuration`, { xid, name });
62
63 await configRemoveProduct(xid, name);
64 res.json({ error: false, message: 'OK' });
65 } catch (e) {
66 logger.warn(`${MODULE_NAME} F714088B: Exception.`, {
67 xid, eMessage: e.message, eCode: e.code,
68 });
69 res.status(500).json({
70 error: true,
71 error_code: e.code,
72 message: e.message,
73 });
74 }
75 };
76
77 router.get('/', [express.json()], pageIndex);
78
79 router.post('/save', [express.json()], pageSave);
80 router.post('/remove', [express.json()], pageRemove);
81
lib/http-server/routers/products/index.js
File was created 1 const MODULE_NAME = 'HTTP-SERVER.ROUTER.PRODUCTS';
2
3 const express = require('express');
4 const logger = require('tektrans-logger');
5
6 const configData = require('../../../config/data');
7 const configSaveProduct = require('../../../config/save-product');
8 const configRemoveProduct = require('../../../config/remove-product');
9
10 const router = express.Router();
11
12 module.exports = router;
13
14 const pageIndex = async (req, res) => {
15 const { xid } = res.locals;
16 try {
17 logger.verbose(`${MODULE_NAME} F1BF0675: get product configuration`, { xid });
18 const products = (await configData.all()).products || {};
19 res.json({ error: false, message: 'OK', result: products });
20 } catch (e) {
21 logger.warn(`${MODULE_NAME} 839E55E0: Exception.`, {
22 xid, eMessage: e.message, eCode: e.code,
23 });
24 res.status(500).json({
25 error: true,
26 error_code: e.code,
27 message: e.message,
28 });
29 }
30 };
31
32 const pageSave = async (req, res) => {
33 const { xid } = res.locals;
34 const { name, remote = null, active = 0 } = req.body;
35 try {
36 logger.verbose(`${MODULE_NAME} 59CB2503: save product configuration`, { xid, data: req.body });
37
38 const params = {
39 name,
40 remote,
41 active,
42 };
43 await configSaveProduct(xid, name, params);
44 res.json({ error: false, message: 'OK' });
45 } catch (e) {
46 logger.warn(`${MODULE_NAME} 47F57E23: Exception.`, {
47 xid, eMessage: e.message, eCode: e.code,
48 });
49 res.status(500).json({
50 error: true,
51 error_code: e.code,
52 message: e.message,
53 });
54 }
55 };
56
57 const pageRemove = async (req, res) => {
58 const { xid } = res.locals;
59 const { name } = req.body;
60 try {
61 logger.verbose(`${MODULE_NAME} E94A7B38: remove product configuration`, { xid, name });
62
63 await configRemoveProduct(xid, name);
64 res.json({ error: false, message: 'OK' });
65 } catch (e) {
66 logger.warn(`${MODULE_NAME} 955FD7E3: Exception.`, {
67 xid, eMessage: e.message, eCode: e.code,
68 });
69 res.status(500).json({
70 error: true,
71 error_code: e.code,
72 message: e.message,
73 });
74 }
75 };
76
77 router.get('/', [express.json()], pageIndex);
78
79 router.post('/save', [express.json()], pageSave);
80 router.post('/remove', [express.json()], pageRemove);
81
lib/http-server/routers/updates/index.js
File was created 1 const MODULE_NAME = 'HTTP-SERVER.ROUTER.UPDATES';
2
3 const express = require('express');
4 const axios = require('axios').default;
5 const logger = require('tektrans-logger');
6
7 const config = require('../../../config');
8
9 const router = express.Router();
10
11 module.exports = router;
12
13 const client = axios.create({
14 baseURL: config.core.url,
15 timeout: config.core.request_timeout_ms,
16 headers: {
17 'x-access-token': config.core.access_token,
18 },
19 });
20
21 const pageUpdate = async (req, res) => {
22 const { xid } = res.locals;
23 let data = req.query;
24 if (req.method.toUpperCase() !== 'GET') {
25 data = req.body;
26 }
27
28 try {
29 logger.verbose(`${MODULE_NAME} 9E5C70C8: update from komodo`, { xid, data });
30 const params = {
31 id: data.request_id,
32 rc: data.rc,
33 amount: data.amount || null,
34 message: data.message,
35 sn: data.sn || null,
36 bill_count: data.bill_count,
37 bill_amount: data.bill_amount,
38 related_data: null,
39 amount_to_charge: data.amount_to_charge,
40 };
41
42 client.post('/transactions/gateway-update', params).then((result) => {
43 logger.verbose(`${MODULE_NAME} A8DA0D04: response from core2`, {
44 xid,
45 response: result.data,
46 });
47 }).catch((err) => {
48 logger.warn(`${MODULE_NAME} 32EB485C: Exception on request to core2`, {
49 xid,
50 eMessage: err.message,
51 eCode: err.code,
52 });
53 });
54
55 res.json({ error: false, message: 'OK' });
56 } catch (e) {
57 logger.warn(`${MODULE_NAME} B12B4A2C: Exception.`, {
58 xid, eMessage: e.message, eCode: e.code,
59 });
60 res.status(500).json({
61 error: true,
62 error_code: e.code,
63 message: e.message,
64 });
65 }
66 };
67
68 router.get('/', pageUpdate);
69 router.post('/', [express.urlencoded({ extended: true }), express.json()], pageUpdate);
70
File was created 1 const matrix = require('./index');
2
3 module.exports = () => {
4 matrix.processTitle = process.title;
5 matrix.uptimeSecs = process.uptime();
6 matrix.memoryUsage = process.memoryUsage();
7 matrix.resourceUsage = process.resourceUsage();
8
9 return matrix;
10 };
11
File was created 1 const data = {
2 processTitle: process.title,
3 pid: process.pid,
4 workingDirectory: process.cwd(),
5 uptimeSecs: process.uptime(),
6
7 memoryUsage: process.memoryUsage(),
8 resourceUsage: process.resourceUsage(),
9
10 platform: process.platform,
11 nodeVersion: process.version,
12 nodeRelease: process.release,
13
14 httpServer: {
15 requestCounter: 0,
16 },
17 };
18
19 module.exports = data;
20
lib/pull/get-inquiry.js
File was created 1 const MODULE_NAME = 'PULL.GET-INQUIRY';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5 const uniqid = require('uniqid');
6 const config = require('../config');
7 const configData = require('../config/data');
8 const actions = require('../actions');
9
10 const client = axios.create({
11 baseURL: config.core.url,
12 timeout: config.core.request_timeout_ms,
13 headers: {
14 'x-access-token': config.core.access_token,
15 },
16 });
17
18 let onPull = false;
19
20 /**
21 * pull unprocessed inquiry transaction from core
22 */
23 module.exports = async () => {
24 logger.verbose(`${MODULE_NAME} 64E2EFDE: Pull inquiry transaction from core`);
25 if (onPull) {
26 logger.verbose(`${MODULE_NAME} EECB3ECC: Pull inquiry already running`);
27 return false;
28 }
29 onPull = true;
30
31 const xid = uniqid();
32
33 try {
34 const products = await configData.getActiveProductPostpaidArray(xid);
35 const response = await client.post('/transactions/inquiry-pull', {
36 gateway: {
37 name: `${config.name}-postpaid`,
38 url: `${config.url}:${config.port}/apikey/${config.apikey}/postpaid`,
39 postpaid: 1,
40 },
41 products,
42 });
43 if (response.data.error) {
44 logger.info(`${MODULE_NAME} E082E007: Error when pulling inquiry transaction`, {
45 xid,
46 message: response.data.message,
47 error: response.data.error,
48 });
49 }
50
51 if (!response.data.result) {
52 logger.info(`${MODULE_NAME} 72C1FAC5: Empty inquiry transaction result`, {
53 xid,
54 result: response.data.result,
55 });
56 return null;
57 }
58
59 await actions.inquiry(xid, response.data.result);
60 } catch (e) {
61 logger.warn(`${MODULE_NAME} 1E5D9D56: Exception`, {
62 xid,
63 message: e.message,
64 code: e.code,
65 });
66 } finally {
67 onPull = false;
68 }
69 return true;
70 };
71
lib/pull/get-payment.js
File was created 1 const MODULE_NAME = 'PULL.GET-PAYMENT';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5 const uniqid = require('uniqid');
6 const config = require('../config');
7 const configData = require('../config/data');
8 const actions = require('../actions');
9
10 const client = axios.create({
11 baseURL: config.core.url,
12 timeout: config.core.request_timeout_ms,
13 headers: {
14 'x-access-token': config.core.access_token,
15 },
16 });
17
18 let onPull = false;
19
20 /**
21 * pull unprocessed payment transaction from core
22 */
23 module.exports = async () => {
24 logger.verbose(`${MODULE_NAME} 68CB1245: Pull payment transaction from core`);
25 if (onPull) {
26 logger.verbose(`${MODULE_NAME} 576C1D1A: Pull payment already running`);
27 return false;
28 }
29 onPull = true;
30
31 const xid = uniqid();
32
33 try {
34 const products = await configData.getActiveProductPostpaidArray(xid);
35 const response = await client.post('/transactions/payment-pull', {
36 gateway: {
37 name: `${config.name}-postpaid`,
38 url: `${config.url}:${config.port}/apikey/${config.apikey}/postpaid`,
39 postpaid: 1,
40 },
41 products,
42 });
43 if (response.data.error) {
44 logger.info(`${MODULE_NAME} E3093F6D: Error when pulling payment transaction`, {
45 xid,
46 message: response.data.message,
47 error: response.data.error,
48 });
49 }
50
51 if (!response.data.result) {
52 logger.info(`${MODULE_NAME} 230E9E0F: Empty payment transaction result`, {
53 xid,
54 result: response.data.result,
55 });
56 return null;
57 }
58
59 await actions.pay(xid, response.data.result);
60 } catch (e) {
61 logger.warn(`${MODULE_NAME} 7E6D9444: Exception`, {
62 xid,
63 message: e.message,
64 code: e.code,
65 });
66 } finally {
67 onPull = false;
68 }
69 return true;
70 };
71
lib/pull/get-prepaid.js
File was created 1 const MODULE_NAME = 'PULL.GET-PREPAID';
2
3 const logger = require('tektrans-logger');
4 const axios = require('axios').default;
5 const uniqid = require('uniqid');
6 const config = require('../config');
7 const configData = require('../config/data');
8 const actions = require('../actions');
9
10 const client = axios.create({
11 baseURL: config.core.url,
12 timeout: config.core.request_timeout_ms,
13 headers: {
14 'x-access-token': config.core.access_token,
15 },
16 });
17
18 let onPull = false;
19
20 /**
21 * pull unprocessed prepaid transaction from core
22 */
23 module.exports = async () => {
24 logger.verbose(`${MODULE_NAME} 385A1B0D: Pull prepaid transaction from core`);
25 if (onPull) {
26 logger.verbose(`${MODULE_NAME} 6563C2C9: Pull prepaid already running`);
27 return false;
28 }
29 onPull = true;
30
31 const xid = uniqid();
32
33 try {
34 const products = await configData.getActiveProductArray(xid);
35 const response = await client.post('/transactions/prepaid-pull', {
36 gateway: {
37 name: config.name,
38 url: `${config.url}:${config.port}/apikey/${config.apikey}`,
39 },
40 products,
41 });
42 if (response.data.error) {
43 logger.info(`${MODULE_NAME} A397BA74: Error when pulling prepaid transaction`, {
44 xid,
45 message: response.data.message,
46 error: response.data.error,
47 });
48 }
49
50 if (!response.data.result) {
51 logger.info(`${MODULE_NAME} 712130A5: Empty prepaid transaction result`, {
52 xid,
53 result: response.data.result,
54 });
55 return null;
56 }
57
58 await actions.buy(xid, response.data.result);
59 } catch (e) {
60 logger.warn(`${MODULE_NAME} 008B2FA5: Exception`, {
61 xid,
62 message: e.message,
63 code: e.code,
64 });
65 } finally {
66 onPull = false;
67 }
68 return true;
69 };
70
File was created 1 exports.run = require('./run');
2
File was created 1 const MODULE_NAME = 'PULL.RUN';
2 const logger = require('tektrans-logger');
3
4 const config = require('../config');
5 const getInquiry = require('./get-inquiry');
6 const getPrepaid = require('./get-prepaid');
7 const getPayment = require('./get-payment');
8
9 /**
10 * Run pulling schedule
11 */
12 module.exports = async () => {
13 logger.verbose(`${MODULE_NAME} 34022A49: Run pulling schedule`, {
14 interval: config.pull_interval_ms,
15 });
16 setInterval(() => {
17 logger.verbose(`${MODULE_NAME} 06B8C652: Pull run`);
18 getPrepaid();
19 getInquiry();
20 getPayment();
21 }, config.pull_interval_ms);
22 };
23