topup.js 5.46 KB
const MODULE_NAME = 'PARTNER-LISTENER.ROUTER.TOPUP';

const express = require('express');
const axios = require('axios');

const config = require('komodo-sdk/config');
const logger = require('tektrans-logger');
const coreapi = require('komodo-sdk/coreapi');
// const coreapi = require('../../coreapi');
const matrix = require('../../matrix');
const dumper = require('../dumper');

const router = express.Router();
module.exports = router;

const terminalsWithLocation = Array.isArray(config.terminals_with_location)
    ? config.terminals_with_location
        .filter((item) => typeof item === 'string')
        .map((item) => (item.trim().toLowerCase()))
    : [];

function onInvalidParameter(missingParameter, req, res) {
    logger.verbose(`${MODULE_NAME} 1536D577: Undefined ${missingParameter} parameter`, {
        xid: res.locals.xid,
        ip: req.ip,
        terminal_name: req.body.terminal_name || req.query.terminal_name,
        request_id: req.body.request_id || req.query.request_id,
        product_name: req.body.product_name || req.query.product_name,
        destination: req.body.destination || req.query.destination,
    });
    res.end('INVALID REQUEST');
}

function pagePrerequisite(req, res, next) {
    if (!req.body) req.body = {};

    const terminalName = req.body.terminal_name || req.query.terminal_name;
    if (!terminalName || typeof terminalName !== 'string') {
        onInvalidParameter('terminal_name', req, res);
        return;
    }

    if (!req.body.password && !req.query.password) {
        onInvalidParameter('password', req, res);
        return;
    }

    if (!req.body.request_id && !req.query.request_id) {
        onInvalidParameter('request_id', req, res);
        return;
    }

    if (!req.body.product_name && !req.query.product_name) {
        onInvalidParameter('product_name', req, res);
        return;
    }

    if (!req.body.destination && !req.query.destination) {
        onInvalidParameter('destination', req, res);
        return;
    }

    next();
}

async function pageIndex(req, res) {
    const { xid } = res.locals;

    const terminalNameWithoutIp = ((req.body.terminal_name || req.query.terminal_name) || '').trim();
    const terminalName = `${terminalNameWithoutIp}@${req.ip.replace(/^::ffff:/, '')}`;

    const qs = {
        terminal_name: terminalName,
        password: req.body.password || req.query.password,
        request_id: req.body.request_id || req.query.request_id,
        product_name: req.body.product_name || req.query.product_name,
        destination: req.body.destination || req.query.destination,
        origin: config.name || 'HTTPGETX',
        report_ip: config.listener.core.ip || null,
        report_port: config.listener.core.port,
        reverse_url: req.body.reverse_url || req.query.reverse_url || null,
    };

    if (terminalsWithLocation.indexOf(terminalNameWithoutIp.toLowerCase()) >= 0) {
        const location = req.body.location
            || req.body.location_id
            || req.query.location
            || req.query.location_id;

        if (location) {
            logger.verbose(`${MODULE_NAME} 5C41FBFA: Including location from partner request`, {
                xid,
                terminalName,
                location,
            });

            qs.location = location;
        }
    }

    matrix.core.sent += 1;

    const [err, coreResponse] = await coreapi({
        xid,
        path: '/prepaid/buy',
        qs,
    });

    if (err || !coreResponse) {
        matrix.core.sent_failed += 1;
        matrix.core.last_error = {
            xid,
            ts: new Date(),
            e: err,
            eCode: err.code,
            eMessage: err.message,
        };

        logger.warn(`${MODULE_NAME} 8DEBE15F: ERROR on /prepaid/buy response`, {
            xid,
            err,
            coreResponseTypeof: typeof coreResponse,
            coreResponse,
        });
        res.end('INVALID CORE RESPONSE');

        dumper(xid, req, 'INVALID CORE RESPONSE');
        return;
    }

    logger.verbose(`${MODULE_NAME} 2528A9B4: Got CORE response`, {
        xid,
        coreResponse,
    });

    const responseToPartner = {
        httpgetx_xid: xid,
        request_id: coreResponse.request_id,
        transaction_id: coreResponse.transaction_id,
        transaction_date: coreResponse.transaction_date,
        store_name: coreResponse.store_name,
        terminal_name: coreResponse.terminal_name,
        product_name: coreResponse.product_name,
        destination: coreResponse.destination,
        rc: coreResponse.rc,
        sn: coreResponse.sn || undefined,
        amount: Number(coreResponse.amount) || undefined,
        ending_balance: Number(coreResponse.ending_balance) || undefined,
        message: coreResponse.message,
    };

    res.json(responseToPartner);

    if (config.listener.partner.webhook) {
        try {
            axios.post(config.listener.partner.webhook, {
                webhookType: 'KOMODO-CENTER-HTTPGETX.PARTNER-LISTENER.DIRECT-RESPONSE',
                body: responseToPartner,
            });
        } catch (e) {
            logger.warn(`${MODULE_NAME} ECC37ECA: Exception on calling webhook`, {
                xid,
                eCode: e.code,
                eMessage: e.message || e.toString(),
            });
        }
    }

    dumper(xid, req, responseToPartner);
}

// router.all('/', (req, res) => { res.status(404).end('404: Not implemented yet'); });
router.get('/', pagePrerequisite, pageIndex);
router.post('/', express.urlencoded({ extended: true }), pageIndex);