diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index 44a7cbffb..16c955467 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -2841,6 +2841,15 @@ query GET_JOBID_BY_MERCHANTID_RONUMBER($merchantID: String!, $roNumber: String!) bodyshop { id intellipay_config + email } } }`; + +exports.GET_BODYSHOP_BY_MERCHANT_ID = ` +query GET_BODYSHOP_BY_MERCHANTID($merchantID: String!) { + bodyshops(where: {intellipay_merchant_id: {_eq: $merchantID}}) { + id + email + } +}`; diff --git a/server/intellipay/lib/handleInvoiceBasedPayment.js b/server/intellipay/lib/handleInvoiceBasedPayment.js index f99378d56..5a6bad360 100644 --- a/server/intellipay/lib/handleInvoiceBasedPayment.js +++ b/server/intellipay/lib/handleInvoiceBasedPayment.js @@ -2,8 +2,11 @@ const handlePaymentValidationError = require("./handlePaymentValidationError"); const { GET_JOBID_BY_MERCHANTID_RONUMBER, INSERT_PAYMENT_RESPONSE, - INSERT_NEW_PAYMENT + INSERT_NEW_PAYMENT, + GET_BODYSHOP_BY_MERCHANT_ID } = require("../../graphql-client/queries"); + +const { sendServerEmail } = require("../../email/sendemail"); const getPaymentType = require("./getPaymentType"); const moment = require("moment"); @@ -36,7 +39,32 @@ const handleInvoiceBasedPayment = async (values, logger, logMeta, res) => { }); if (!result?.jobs?.length) { - return handlePaymentValidationError(res, logger, "intellipay-postback-job-not-found", "Job not found", logMeta); + // Fetch bodyshop data + const bodyshop = await gqlClient.request(GET_BODYSHOP_BY_MERCHANT_ID, { + merchantID: values.merchantid + }); + + if (bodyshop?.bodyshops?.[0]) { + // Note: changed bodyshops to bodyshop to match query name + const email = bodyshop.bodyshops[0].email; + await sendServerEmail({ + subject: `Failed to Insert Payment`, + text: `The system has attempted to insert a payment that was generated by your merchant terminal but could not find an associated invoice. Transaction details are below. Please input this payment to your system manually.\n\n${Object.keys( + values + ) + .map((key) => `${key}: ${values[key]}`) + .join("\n")}` + }); + } + + return handlePaymentValidationError( + res, + logger, + "intellipay-postback-job-not-found", + "Job not found", + logMeta, + 200 + ); } const job = result.jobs[0]; diff --git a/server/intellipay/lib/handlePaymentValidationError.js b/server/intellipay/lib/handlePaymentValidationError.js index fccf7a75f..185089b41 100644 --- a/server/intellipay/lib/handlePaymentValidationError.js +++ b/server/intellipay/lib/handlePaymentValidationError.js @@ -5,14 +5,15 @@ * @param logCode * @param message * @param logMeta + * @param returnCode * @returns {*} */ -const handlePaymentValidationError = (res, logger, logCode, message, logMeta) => { +const handlePaymentValidationError = (res, logger, logCode, message, logMeta, returnCode) => { logger.log(logCode, "ERROR", "api", null, { message, ...logMeta }); - return res.status(400).send(`Bad Request: ${message}`); + return res.status(returnCode || 400).send(`Bad Request: ${message}`); }; module.exports = handlePaymentValidationError; diff --git a/server/job/test/job-totals.test.js b/server/job/test/job-totals.test.js index 059b0bb1e..04a915b6b 100644 --- a/server/job/test/job-totals.test.js +++ b/server/job/test/job-totals.test.js @@ -2,7 +2,8 @@ import fs from "fs"; import path from "path"; import { describe, it, expect } from "vitest"; import { TotalsServerSide as TotalsServerSideCA } from "../job-totals"; // Canadian version (imex) -import { TotalsServerSide as TotalsServerSideUS } from "../job-totals-USA"; // US version (rome) +import { TotalsServerSide as TotalsServerSideUS } from "../job-totals-USA"; +import { isFunction } from "lodash"; // US version (rome) /** * This function is used to replace the values in the object with their toObject() representation. @@ -11,7 +12,7 @@ import { TotalsServerSide as TotalsServerSideUS } from "../job-totals-USA"; // U * @returns {*} */ const dineroReplacer = (key, value) => { - if (value && typeof value === "object" && typeof value.toObject === "function") { + if (isFunction(value)) { return value.toObject(); } return value;