105 lines
3.9 KiB
TypeScript
105 lines
3.9 KiB
TypeScript
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
|
import type { NextApiRequest, NextApiResponse } from "next";
|
|
import { withIronSessionApiRoute } from "iron-session/next";
|
|
import { sessionOptions } from "@/lib/session";
|
|
import { Group, User } from "@/interfaces/user";
|
|
import { DurationUnit, Package, Payment } from "@/interfaces/paypal";
|
|
import { v4 } from "uuid";
|
|
import ShortUniqueId from "short-unique-id";
|
|
import axios from "axios";
|
|
import { IntentionResult, PaymentIntention, TransactionResult } from "@/interfaces/paymob";
|
|
import moment from "moment";
|
|
import client from "@/lib/mongodb";
|
|
import { getEntity } from "@/utils/entities.be";
|
|
import { Entity } from "@/interfaces/entity";
|
|
import { getEntityUsers } from "@/utils/users.be";
|
|
import { mapBy } from "@/utils";
|
|
|
|
const db = client.db(process.env.MONGODB_DB);
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
if (req.method === "POST") await post(req, res);
|
|
}
|
|
|
|
async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
const transactionResult = req.body as TransactionResult;
|
|
const authToken = await authenticatePaymob();
|
|
|
|
console.log("WEBHOOK: ", transactionResult);
|
|
if (!checkTransaction(authToken, transactionResult.transaction.order.id)) return res.status(404).json({ ok: false });
|
|
if (!transactionResult.transaction.success) return res.status(400).json({ ok: false });
|
|
|
|
const { userID, duration, duration_unit, entity: entityID } = transactionResult.intention.extras.creation_extras as {
|
|
userID: string;
|
|
duration: number;
|
|
duration_unit: DurationUnit;
|
|
entity: string
|
|
};
|
|
|
|
const user = await db.collection("users").findOne<User>({ id: userID as string });
|
|
|
|
if (!user || !duration || !duration_unit) return res.status(404).json({ ok: false });
|
|
|
|
const subscriptionExpirationDate = user.subscriptionExpirationDate;
|
|
if (!subscriptionExpirationDate) return res.status(200).json({ ok: false });
|
|
|
|
const initialDate = moment(subscriptionExpirationDate).isAfter(moment()) ? moment(subscriptionExpirationDate) : moment();
|
|
|
|
const updatedSubscriptionExpirationDate = moment(initialDate).add(duration, duration_unit).endOf("day").subtract(2, "hours").toISOString();
|
|
|
|
await db.collection("users").updateOne(
|
|
{ id: userID as string },
|
|
{ $set: { subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active" } }
|
|
);
|
|
|
|
await db.collection("paypalpayments").insertOne({
|
|
id: v4(),
|
|
createdAt: new Date().toISOString(),
|
|
currency: transactionResult.transaction.currency,
|
|
orderId: transactionResult.transaction.id,
|
|
status: "COMPLETED",
|
|
subscriptionDuration: duration,
|
|
subscriptionDurationUnit: duration_unit,
|
|
subscriptionExpirationDate: updatedSubscriptionExpirationDate,
|
|
userId: userID,
|
|
value: transactionResult.transaction.amount_cents / 1000,
|
|
});
|
|
|
|
if (entityID) {
|
|
const entity = await getEntity(entityID)
|
|
await db.collection<Entity>("entities").updateOne({ id: entityID }, { $set: { expiryDate: req.body.expiryDate } });
|
|
|
|
const users = await getEntityUsers(entityID, 0, {
|
|
subscriptionExpirationDate: entity?.expiryDate,
|
|
$and: [
|
|
{ type: { $ne: "admin" } },
|
|
{ type: { $ne: "developer" } },
|
|
]
|
|
})
|
|
|
|
await db.collection<User>("users").updateMany({ id: { $in: mapBy(users, 'id') } }, { $set: { subscriptionExpirationDate: req.body.expiryDate } })
|
|
}
|
|
|
|
res.status(200).json({
|
|
ok: true,
|
|
});
|
|
}
|
|
|
|
const authenticatePaymob = async () => {
|
|
const response = await axios.post<{ token: string }>(
|
|
"https://oman.paymob.com/api/auth/tokens",
|
|
{
|
|
api_key: process.env.PAYMOB_API_KEY,
|
|
},
|
|
{ headers: { Authorization: `Bearer ${process.env.PAYMOB_SECRET_KEY}` } },
|
|
);
|
|
|
|
return response.data.token;
|
|
};
|
|
|
|
const checkTransaction = async (token: string, orderID: number) => {
|
|
const response = await axios.post("https://oman.paymob.com/api/ecommerce/orders/transaction_inquiry", { auth_token: token, order_id: orderID });
|
|
|
|
return response.status === 200;
|
|
};
|