parse-result.js 4.89 KB
const MODULE_NAME = 'PARSE-RESULT';

const config = require('komodo-sdk/config');
const logger = require('tektrans-logger');

const getParamsMemberObj = require('./generic-xmlrpc/get-params-members-obj');
const parseXml = require('./parse-xml');

const report = require('./report');
const translateRc = require('./translate-rc');
const messageExtractor = require('./message-extractor');
const patternRules = require('./pattern-rules');

const priceRules = (
    config.partner
    && config.partner.price_rules
    && Array.isArray(config.partner.price_rules)
    && config.partner.price_rules.length
    && config.partner.price_rules
        .filter((rule) => rule.pattern && !rule.disable && !rule.disabled)
        .map((rule) => ({
            pattern: (typeof rule.pattern === 'string') ? new RegExp(rule.pattern) : rule.pattern,
            idx: rule.idx,
            disable: rule.disable || rule.disabled,
            postprocessing: rule.postprocessing,
        }))
) || patternRules.price;

const balanceRules = (
    config.partner
    && config.partner.balance_rules
    && Array.isArray(config.partner.balance_rules)
    && config.partner.balance_rules.length
    && config.partner.balance_rules
        .filter((rule) => rule.pattern && !rule.disable && !rule.disabled)
        .map((rule) => ({
            pattern: (typeof rule.pattern === 'string') ? new RegExp(rule.pattern) : rule.pattern,
            idx: rule.idx,
            disable: rule.disable || rule.disabled,
            postprocessing: rule.postprocessing,
        }))
) || patternRules.balance;

module.exports = (xid, trxIdFromCaller, xml, isCallback, remoteIp) => {
    logger.verbose(`${MODULE_NAME} 58547863: Processing XML message`, { xid, isCallback });

    const responseType = isCallback ? 'CALLBACK' : 'DIRECT-RESPONSE';

    if (!trxIdFromCaller && !isCallback) {
        if (logger) logger.warn(`${MODULE_NAME} 8CAAD7C9: No trx id on non callback`, { xid });
        return;
    }

    const obj = parseXml(xid, xml);
    if (!obj) {
        const e = new Error(`${MODULE_NAME} B46CAAD1: Invalid XML`);
        logger.warn(e.message, { xid });

        if (trxIdFromCaller) {
            report(xid, {
                trx_id: trxIdFromCaller.toString(),
                rc: '68',
                message: {
                    xid,
                    responseType,
                    'GW-ERROR': {
                        message: e.message,
                        responseFromPartner: xml,
                    },
                },
            });
        }

        return;
    }

    const params = getParamsMemberObj(obj, false);

    if (!params) {
        const e = new Error(`${MODULE_NAME} A7B7EB30: Can not get params from message`);
        logger.warn(e.message, { xid });

        if (trxIdFromCaller) {
            report(xid, {
                trx_id: trxIdFromCaller.toString(),
                rc: '68',
                message: {
                    xid,
                    responseType,
                    'GW-ERROR': {
                        message: e.message,
                        responseFromPartner: obj,
                    },
                },
            });
        }
    }

    logger.verbose(`${MODULE_NAME} 3D5400C1: Params extracted from response`, { xid, params });

    const requestIdField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.requestId) || 'REQUESTID';
    const requestIdFromResponse = params[requestIdField];

    const responseCodeField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.responseCode) || 'RESPONSECODE';
    const responseCodeFromResponse = params[responseCodeField];

    const messageField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.message) || 'MESSAGE';
    const messageFromResponse = params[messageField];

    const snField = (config.partner.xmlrpc_field && config.partner.xmlrpc_field.sn) || 'SN';
    const snFromResponse = params[snField];

    const trxId = trxIdFromCaller || requestIdFromResponse;
    if (!trxId) {
        logger.warn(`${MODULE_NAME} 534E684A: Unknown trxId`, { xid });
        return;
    }

    const rc = responseCodeFromResponse
        ? translateRc(xid, responseCodeFromResponse) || '40'
        : '68';

    const sn = (
        rc === '00' && (
            snFromResponse
            || messageExtractor(patternRules.sn, messageFromResponse)
        )
    ) || null;

    const amount = Number(
        messageExtractor(
            priceRules,
            messageFromResponse,
        ) || '',
    ) || null;

    const balance = Number(
        messageExtractor(
            balanceRules,
            messageFromResponse,
        ) || '',
    ) || null;

    report(xid, {
        trx_id: trxId.toString(),
        rc,
        sn,
        amount,
        balance,
        message: {
            xid,
            ip: remoteIp || null,
            responseType: isCallback ? 'CALLBACK' : 'DIRECT-RESPONSE',
            message: params,
        },
    });
};