I have website on React and getting the callback with payment result from the payment engine to the backend (Node.js).
I receive the callback from payment engine using a POST
method:
app.post("/api/payment-status", async (req, res) => {
res.setHeader("Content-Type", "application/json");
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
const {createdDate, transactionStatus, reason, reasonCode, orderReference} = JSON.parse(Object.keys(req.body)[0]);
console.log("transactionStatus: ", transactionStatus, "reason: ", reason, "reasonCode: ", reasonCode, "orderReference: ", orderReference);
const wfpRes = await fetchItemSetting(res, webConfig.enableWfpSandboxID);
const secretKey = isWebConfigOn(wfpRes[0].is_active) ? webConfig.wfpSandboxSecretKey! : webConfig.wfpSecretKey!;
const wfpAcceptStatus = webConfig.wfpAcceptStatus;
const wfpResData = {
orderReference,
status: wfpAcceptStatus,
time: createdDate
};
const wfpData = generateWfpDataForSignature(wfpResData);
const wfpSignature = getWfpSignature(secretKey, wfpData);
let paymentData = {};
if (transactionStatus === webConfig.wfpTransactionStatus && reason === webConfig.wfpReason && reasonCode === Number(webConfig.wfpReasonCode) && orderReference) {
console.log("Success!!!");
paymentData = {
isSuccess: true,
wfpOrderReference: orderReference,
wfpStatus: transactionStatus,
wfpReason: reason,
msg: "Успішний платіж.",
wfpReasonCode: reasonCode
};
} else {
console.log("Failed!!!!");
paymentData = {
isSuccess: false,
wfpOrderReference: orderReference,
wfpStatus: transactionStatus,
wfpReason: reason,
msg: `Замовлення №${orderReference}. Код неуспішного платежу: ${reasonCode}!`,
wfpReasonCode: reasonCode
};
}
if (typeof paymentData === "object" && Object.keys(paymentData).length > 0) {
eventEmitter.emit("paymentStatusReceived", paymentData);
}
return res.status(200).send({...wfpResData, signature: wfpSignature});
});
To get the result I use EventEmitter
.
const EventEmitter = require("events");
const eventEmitter = new EventEmitter();
app.get("/api/order/payment-data", (req, res) => {
res.setHeader("Content-Type", "application/json");
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
eventEmitter.once("paymentStatusReceived", (paymentData) => {
if (typeof paymentData === "object" && Object.keys(paymentData).length > 0) {
return res.json(paymentData);
}
});
});
Instead of paymentData
object data I get the html output from 502 error page. When I add the following headers to axios GET
request.
"Access-Control-Allow-Origin": "*",
Accept: "application/json",
"Content-Type": "application/json",
"Access-Control-Expose-Headers": "*, Authorization",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS"
Then I get 406 Not Acceptable status code.
For example, the first time I pay in the test mode I get the correct data but when I try a few more times it just 406 error code. Or garbage html when I remove this content type: Accept: "application/json"
.
Any ideas how to find and fix this error? Or what should be the correct code to wait for a callback from a payment engine and then get it as JSON
?