feature/IO-2885-IntelliPay-App-Postback
- Finish ticket
This commit is contained in:
@@ -18,21 +18,52 @@ const client = new SecretsManagerClient({
|
||||
|
||||
const gqlClient = require("../graphql-client/graphql-client").client;
|
||||
|
||||
/**
|
||||
* Generates a properly formatted Cpteller API URL
|
||||
* @param {Object} options - URL configuration options
|
||||
* @param {string} options.apiType - 'webapi' or 'custapi'
|
||||
* @param {string} [options.version] - API version (e.g., '26' for webapi)
|
||||
* @param {Object} [options.params] - URL query parameters
|
||||
* @returns {string} - The formatted Cpteller URL
|
||||
*/
|
||||
const getCptellerUrl = (options) => {
|
||||
const { apiType = "webapi", version, params = {} } = options;
|
||||
|
||||
// Base URL construction
|
||||
let url = `https://${domain}.cpteller.com/api/`;
|
||||
|
||||
// Add version if specified for webapi
|
||||
if (apiType === "webapi" && version) {
|
||||
url += `${version}/`;
|
||||
}
|
||||
|
||||
// Add the API endpoint
|
||||
url += `${apiType}.cfc`;
|
||||
|
||||
// Add query parameters if any exist
|
||||
const queryParams = new URLSearchParams(params).toString();
|
||||
if (queryParams) {
|
||||
url += `?${queryParams}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Get shop credentials from AWS Secrets Manager
|
||||
* @param bodyshop
|
||||
* @returns {Promise<{error}|{merchantkey: *, apikey: *}|any>}
|
||||
*/
|
||||
const getShopCredentials = async (bodyshop) => {
|
||||
// Development only
|
||||
if (process.env.NODE_ENV === undefined) {
|
||||
// In Dev/Testing we will use the environment variables
|
||||
if (process.env?.NODE_ENV !== "production") {
|
||||
return {
|
||||
merchantkey: process.env.INTELLIPAY_MERCHANTKEY,
|
||||
apikey: process.env.INTELLIPAY_APIKEY
|
||||
};
|
||||
}
|
||||
|
||||
// Production code
|
||||
// In Production we will use the AWS Secrets Manager
|
||||
if (bodyshop?.imexshopid) {
|
||||
try {
|
||||
const secret = await client.send(
|
||||
@@ -106,7 +137,10 @@ const lightboxCredentials = async (req, res) => {
|
||||
...shopCredentials,
|
||||
operatingenv: "businessattended"
|
||||
}),
|
||||
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=autoterminal${req.body.refresh ? "_refresh" : ""}` //autoterminal_refresh
|
||||
url: getCptellerUrl({
|
||||
apiType: "custapi",
|
||||
params: { method: `autoterminal${req.body.refresh ? "_refresh" : ""}` }
|
||||
})
|
||||
};
|
||||
|
||||
const response = await axios(options);
|
||||
@@ -178,7 +212,11 @@ const paymentRefund = async (req, res) => {
|
||||
paymentid: req.body.paymentid,
|
||||
amount: req.body.amount
|
||||
}),
|
||||
url: `https://${domain}.cpteller.com/api/26/webapi.cfc?method=payment_refund`
|
||||
url: getCptellerUrl({
|
||||
apiType: "webapi",
|
||||
version: "26",
|
||||
params: { method: "payment_refund" }
|
||||
})
|
||||
};
|
||||
|
||||
logger.log("intellipay-refund-options-prepared", "DEBUG", req.user?.email, null, {
|
||||
@@ -259,7 +297,10 @@ const generatePaymentUrl = async (req, res) => {
|
||||
invoice: req.body.invoice,
|
||||
createshorturl: true
|
||||
}),
|
||||
url: `https://${domain}.cpteller.com/api/custapi.cfc?method=generate_lightbox_url`
|
||||
url: getCptellerUrl({
|
||||
apiType: "custapi",
|
||||
params: { method: "generate_lightbox_url" }
|
||||
})
|
||||
};
|
||||
|
||||
logger.log("intellipay-generate-payment-url-options-prepared", "DEBUG", req.user?.email, null, {
|
||||
@@ -344,7 +385,7 @@ const checkFee = async (req, res) => {
|
||||
},
|
||||
{ sort: false } // Ensure query string order is preserved
|
||||
),
|
||||
url: `https://${domain}.cpteller.com/api/26/webapi.cfc`
|
||||
url: getCptellerUrl({ apiType: "webapi", version: "26" })
|
||||
};
|
||||
|
||||
logger.log("intellipay-checkfee-options-prepared", "DEBUG", req.user?.email, null, {
|
||||
@@ -506,19 +547,49 @@ const postBack = async (req, res) => {
|
||||
}
|
||||
|
||||
if (values?.invoice) {
|
||||
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
||||
id: values.invoice
|
||||
// Early Bail on Merchant ID
|
||||
if (!values?.merchantid) {
|
||||
logger.log("intellipay-postback-no-merchantid", "ERROR", "api", null, {
|
||||
message: "Merchant ID is missing",
|
||||
...logResponseMeta
|
||||
});
|
||||
|
||||
return res.status(400).send("Bad Request: Merchant ID is missing");
|
||||
}
|
||||
|
||||
const result = await gqlClient.request(queries.GET_JOBID_BY_MERCHANTID_RONUMBER, {
|
||||
merchantID: values.merchantid,
|
||||
roNumber: values.invoice
|
||||
});
|
||||
|
||||
const bodyshop = await gqlClient.request(queries.GET_BODYSHOP_BY_ID, {
|
||||
id: job.jobs_by_pk.shopid
|
||||
});
|
||||
// Early Bail on No Jobs Found
|
||||
if (!result?.jobs?.length) {
|
||||
logger.log("intellipay-postback-job-not-found", "ERROR", "api", null, {
|
||||
message: "Job not found",
|
||||
...logResponseMeta
|
||||
});
|
||||
|
||||
const ipMapping = bodyshop.bodyshops_by_pk.intellipay_config?.payment_map;
|
||||
return res.status(400).send("Bad Request: Job not found");
|
||||
}
|
||||
|
||||
const job = result?.jobs?.[0];
|
||||
|
||||
const bodyshop = job?.bodyshop;
|
||||
|
||||
// Early Bail on no Bodyshop Found
|
||||
if (!bodyshop) {
|
||||
logger.log("intellipay-postback-bodyshop-not-found", "ERROR", "api", null, {
|
||||
message: "Bodyshop not found",
|
||||
...logResponseMeta
|
||||
});
|
||||
|
||||
return res.status(400).send("Bad Request: Bodyshop not found");
|
||||
}
|
||||
|
||||
const ipMapping = bodyshop?.intellipay_config?.payment_map;
|
||||
|
||||
logger.log("intellipay-postback-invoice-job-fetched", "DEBUG", "api", null, {
|
||||
job,
|
||||
bodyshop,
|
||||
...logResponseMeta
|
||||
});
|
||||
|
||||
@@ -528,7 +599,7 @@ const postBack = async (req, res) => {
|
||||
transactionid: values.authcode,
|
||||
payer: "Customer",
|
||||
type: ipMapping ? ipMapping[(values.cardtype || "").toLowerCase()] || values.cardtype : values.cardtype,
|
||||
jobid: values.invoice,
|
||||
jobid: job.id,
|
||||
date: moment(Date.now())
|
||||
}
|
||||
});
|
||||
@@ -541,9 +612,9 @@ const postBack = async (req, res) => {
|
||||
const responseResults = await gqlClient.request(queries.INSERT_PAYMENT_RESPONSE, {
|
||||
paymentResponse: {
|
||||
amount: values.total,
|
||||
bodyshopid: bodyshop.bodyshops_by_pk.id,
|
||||
bodyshopid: bodyshop.id,
|
||||
paymentid: paymentResult.id,
|
||||
jobid: values.invoice,
|
||||
jobid: job.id,
|
||||
declinereason: "Approved",
|
||||
ext_paymentid: values.paymentid,
|
||||
successful: true,
|
||||
@@ -576,13 +647,10 @@ const postBack = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
const postBackCallBack = async (req, res) => {};
|
||||
|
||||
module.exports = {
|
||||
lightboxCredentials,
|
||||
paymentRefund,
|
||||
generatePaymentUrl,
|
||||
checkFee,
|
||||
postBack,
|
||||
postBackCallBack
|
||||
postBack
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user