Skip to content

Commit

Permalink
fix: Payment validation on server side now
Browse files Browse the repository at this point in the history
  • Loading branch information
plibither8 committed Nov 11, 2021
1 parent e2195ec commit 36ffd7b
Showing 1 changed file with 56 additions and 66 deletions.
122 changes: 56 additions & 66 deletions src/routes/payment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,16 @@ route.post(
const { value, error } = Joi.object({
pid: Joi.string().trim().required(),
}).validate(req.body, { convert: true });

if (!req.user.address || !req.user.phoneNumber) {
respond(res, req, 400, ERROR.BAD_REQUEST);
return;
}

if (error) {
console.error(error);
respond(res, req, 400, ERROR.BAD_INPUT);
return;
}

const { pid: productId } = value;

try {
const product = await prisma.product.findUnique({
where: { id: productId },
Expand All @@ -56,7 +52,6 @@ route.post(
respond(res, req, 404, ERROR.PRODUCT_NOT_FOUND);
return;
}

if (
(product && product.seller.user.banned) ||
product.seller.user.deleted ||
Expand All @@ -65,19 +60,14 @@ route.post(
respond(res, req, 404, "Product is no longer available");
return;
}

const order = await prisma.orders.create({
data: {
buyerId: req.user.buyerProfile.id,
productId: product.id,
quantity: 1,
},
});

await new Promise((f) => setTimeout(f, 2000));

log(req, "CREATE", `Order ${order.id} created for product ${productId}`);

const body = {
amount: product.price * 100, //razorpay processess amount in Paise
currency: "INR",
Expand All @@ -92,10 +82,9 @@ route.post(
notify: {
email: true,
},
callback_url: `${process.env.CLIENT_ORIGIN}/payment`,
callback_url: `${process.env.API_BASE_URL}/payment/validate`,
callback_method: "get",
};

const response = await axios.post(
"https://api.razorpay.com/v1/payment_links/",
body,
Expand All @@ -106,7 +95,7 @@ route.post(
},
}
);

await new Promise((f) => setTimeout(f, 3000));
log(req, "CREATE", `Payment request generated for order ${order.id}`);
respond(res, req, 200, "Payment Link", response.data.short_url);
} catch (exception) {
Expand All @@ -117,62 +106,63 @@ route.post(
}
);

route.get(
"/validate",
isUser,
isNotDeleted,
isUserVerified,
isNotBanned,
isBuyer,
async (req: any, res, next) => {
const querySchema = Joi.string()
.trim()
.required()
.not("undefined")
.not("null");
const { value, error } = Joi.object({
payload: querySchema,
signature: querySchema,
orderId: querySchema,
}).validate(req.query, { convert: true });
if (error) {
console.log(error);
respond(res, req, 400, ERROR.BAD_INPUT);
return;
}

let generatedSignature: string;

route.get("/validate", async (req: any, res, next) => {
const querySchema = Joi.string()
.trim()
.required()
.not("undefined")
.not("null");
const { value, error } = Joi.object({
razorpay_payment_id: querySchema,
razorpay_payment_link_id: querySchema,
razorpay_payment_link_reference_id: querySchema,
razorpay_payment_link_status: querySchema,
razorpay_signature: querySchema,
}).validate(req.query, { convert: true });
if (error) {
console.log(error);
respond(res, req, 400, ERROR.BAD_INPUT);
return;
}
const {
razorpay_payment_id: paymentId,
razorpay_payment_link_id: paymentLinkId,
razorpay_payment_link_reference_id: orderId,
razorpay_payment_link_status: status,
razorpay_signature: signature,
} = value;
const payload = [paymentLinkId, orderId, status, paymentId].join("|");
let generatedSignature: string;
try {
generatedSignature = crypto
.createHmac("sha256", process.env.RAZORPAY_API_TEST_PASSWORD)
.update(payload)
.digest("hex");
} catch (err) {
res.redirect(`${process.env.CLIENT_ORIGIN}/payment?status=failure`);
return;
}
if (generatedSignature === signature) {
try {
generatedSignature = crypto
.createHmac("sha256", process.env.RAZORPAY_API_TEST_PASSWORD)
.update(value.payload)
.digest("hex");
} catch (err) {
respond(res, req, 500, ERROR.INTERNAL_ERROR);
const order = await prisma.orders.update({
where: { id: orderId },
data: { status: true },
include: { buyer: { include: { user: true } } },
});
log(
{ ...req, user: order.buyer.user },
"CREATE",
`Payment recorded for order ${orderId}`
);
res.redirect(`${process.env.CLIENT_ORIGIN}/payment?status=success`);
return;
} catch (exception) {
res.redirect(`${process.env.CLIENT_ORIGIN}/payment?status=failure`);
return;
}

if (generatedSignature === value.signature) {
try {
await prisma.orders.update({
where: { id: value.orderId },
data: { status: true },
});

log(req, "CREATE", `Payment recorded for order ${value.orderId}`);

respond(res, req, 200, "Payment Successful", { status: true });
return;
} catch (exception) {
respond(res, req, 500, ERROR.INTERNAL_ERROR, { status: false });
return;
}
}

respond(res, req, 400, "Payment Not Successful", { status: false });
return;
}
);
res.redirect(`${process.env.CLIENT_ORIGIN}/payment?status=failure`);
return;
});

export default route;

0 comments on commit 36ffd7b

Please sign in to comment.