Files
bodyshop/server/intellipay/lib/handleInvoiceBasedPayment.js
Allan Carr f19b9cb8e1 IO-3395 Postback Payment Date
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-10-07 10:59:10 -07:00

141 lines
3.7 KiB
JavaScript

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;