const handlePaymentValidationError = require("./handlePaymentValidationError"); const { GET_JOBID_BY_MERCHANTID_RONUMBER, INSERT_PAYMENT_RESPONSE, INSERT_NEW_PAYMENT, GET_BODYSHOP_BY_MERCHANT_ID } = require("../../graphql-client/queries"); const { sendTaskEmail } = require("../../email/sendemail"); const getPaymentType = require("./getPaymentType"); const moment = require("moment"); const gqlClient = require("../../graphql-client/graphql-client").client; /** * @description Handle invoice-based payment processing * @param values * @param logger * @param logMeta * @param res * @returns {Promise<*>} */ const handleInvoiceBasedPayment = async (values, logger, logMeta, res) => { // Validate required fields if (!values.merchantid) { return handlePaymentValidationError( res, logger, "intellipay-postback-no-merchantid", "Merchant ID is missing", logMeta ); } // Fetch job data const result = await gqlClient.request(GET_JOBID_BY_MERCHANTID_RONUMBER, { merchantID: values.merchantid, roNumber: values.invoice }); if (!result?.jobs?.length) { // 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 sendTaskEmail({ to: email, 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]; const bodyshop = job?.bodyshop; if (!bodyshop) { return handlePaymentValidationError( res, logger, "intellipay-postback-bodyshop-not-found", "Bodyshop not found", logMeta ); } const ipMapping = bodyshop.intellipay_config?.payment_map; logger.log("intellipay-postback-invoice-job-fetched", "DEBUG", "api", null, { job, ...logMeta }); // Create payment record const paymentResult = await gqlClient.request(INSERT_NEW_PAYMENT, { paymentInput: { amount: values.total, transactionid: values.authcode, payer: "Customer", type: getPaymentType(ipMapping, values.cardtype), jobid: job.id, date: moment() .tz(bodyshop?.timezone ?? "UTC") .format("YYYY-MM-DD") } }); logger.log("intellipay-postback-invoice-payment-success", "DEBUG", "api", null, { paymentResult, ...logMeta }); // Create payment response record const responseResults = await gqlClient .request(INSERT_PAYMENT_RESPONSE, { paymentResponse: { amount: values.total, bodyshopid: bodyshop.id, paymentid: paymentResult.insert_payments.returning[0].id, jobid: job.id, declinereason: "Approved", ext_paymentid: values.paymentid, successful: true, response: values } }) .catch((err) => { logger.log("intellipay-postback-invoice-response-error", "ERROR", "api", null, { err, ...logMeta }); }); logger.log("intellipay-postback-invoice-response-success", "DEBUG", "api", null, { responseResults, ...logMeta }); return res.sendStatus(200); }; module.exports = handleInvoiceBasedPayment;