2024-12-07 14:09:53 +05:00
|
|
|
"use server";
|
|
|
|
|
|
|
|
import prisma from "@/lib/db";
|
|
|
|
import type { PaymentType } from "@/lib/types";
|
2024-12-21 00:24:29 +05:00
|
|
|
import { formatMacAddress } from "@/lib/utils";
|
2025-01-01 23:48:56 +05:00
|
|
|
import type { Prisma } from "@prisma/client";
|
2024-12-07 14:09:53 +05:00
|
|
|
import { revalidatePath } from "next/cache";
|
2024-12-25 17:21:04 +05:00
|
|
|
import { redirect } from "next/navigation";
|
2024-12-13 11:24:13 +05:00
|
|
|
import { addDevicesToGroup } from "./omada-actions";
|
2024-12-07 14:09:53 +05:00
|
|
|
|
|
|
|
export async function createPayment(data: PaymentType) {
|
2025-01-15 10:35:03 +05:00
|
|
|
console.log("data", data);
|
|
|
|
const payment = await prisma.payment.create({
|
|
|
|
data: {
|
|
|
|
amount: data.amount,
|
|
|
|
numberOfMonths: data.numberOfMonths,
|
|
|
|
paid: data.paid,
|
|
|
|
userId: data.userId,
|
|
|
|
devices: {
|
|
|
|
connect: data.deviceIds.map((id) => {
|
|
|
|
return {
|
|
|
|
id,
|
|
|
|
};
|
|
|
|
}),
|
2024-12-07 14:09:53 +05:00
|
|
|
},
|
2025-01-15 10:35:03 +05:00
|
|
|
},
|
|
|
|
});
|
|
|
|
redirect(`/payments/${payment.id}`);
|
2024-12-07 14:09:53 +05:00
|
|
|
}
|
2024-12-09 22:59:13 +05:00
|
|
|
|
|
|
|
type VerifyPaymentType = {
|
2024-12-25 17:21:04 +05:00
|
|
|
userId: string;
|
2024-12-09 22:59:13 +05:00
|
|
|
paymentId?: string;
|
|
|
|
benefName: string;
|
|
|
|
accountNo?: string;
|
|
|
|
absAmount: string;
|
|
|
|
time: string;
|
2024-12-25 17:21:04 +05:00
|
|
|
type?: "TRANSFER" | "WALLET";
|
2024-12-09 22:59:13 +05:00
|
|
|
};
|
|
|
|
|
2025-01-01 23:48:56 +05:00
|
|
|
type PaymentWithDevices = Prisma.PaymentGetPayload<{
|
|
|
|
include: {
|
|
|
|
devices: true;
|
|
|
|
};
|
|
|
|
}>;
|
2024-12-25 17:21:04 +05:00
|
|
|
|
|
|
|
class InsufficientFundsError extends Error {
|
|
|
|
constructor() {
|
|
|
|
super("Insufficient funds in wallet");
|
|
|
|
this.name = "InsufficientFundsError";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function processWalletPayment(
|
|
|
|
user: { id: string; walletBalance: number } | null,
|
|
|
|
payment: PaymentWithDevices | null,
|
|
|
|
amount: number,
|
|
|
|
) {
|
|
|
|
if (!user || !payment) {
|
|
|
|
throw new Error("User or payment not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
const walletBalance = user.walletBalance ?? 0;
|
|
|
|
if (walletBalance < amount) {
|
|
|
|
throw new InsufficientFundsError();
|
|
|
|
}
|
|
|
|
|
2025-01-01 23:48:56 +05:00
|
|
|
const expiryDate = new Date();
|
|
|
|
expiryDate.setMonth(expiryDate.getMonth() + payment.numberOfMonths);
|
2024-12-25 17:21:04 +05:00
|
|
|
await prisma.$transaction([
|
|
|
|
prisma.payment.update({
|
|
|
|
where: { id: payment.id },
|
|
|
|
data: {
|
|
|
|
paid: true,
|
|
|
|
paidAt: new Date(),
|
2025-01-08 23:04:30 +05:00
|
|
|
method: "WALLET",
|
2024-12-25 17:21:04 +05:00
|
|
|
devices: {
|
2025-01-08 23:04:30 +05:00
|
|
|
updateMany: payment.devices.map((device) => ({
|
|
|
|
where: { id: device.id },
|
|
|
|
data: {
|
|
|
|
isActive: true,
|
|
|
|
expiryDate: expiryDate,
|
|
|
|
},
|
|
|
|
})),
|
2024-12-09 22:59:13 +05:00
|
|
|
},
|
|
|
|
},
|
2024-12-25 17:21:04 +05:00
|
|
|
}),
|
|
|
|
prisma.user.update({
|
|
|
|
where: { id: user.id },
|
|
|
|
data: { walletBalance: walletBalance - amount },
|
|
|
|
}),
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
type VerifyPaymentResponse =
|
|
|
|
| {
|
|
|
|
success: boolean;
|
|
|
|
message: string;
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
success: boolean;
|
|
|
|
message: string;
|
|
|
|
transaction: {
|
|
|
|
ref: string;
|
|
|
|
sourceBank: string;
|
|
|
|
trxDate: string;
|
2024-12-13 11:24:13 +05:00
|
|
|
};
|
2024-12-25 17:21:04 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
async function verifyExternalPayment(
|
|
|
|
data: VerifyPaymentType,
|
|
|
|
payment: PaymentWithDevices | null,
|
|
|
|
): Promise<VerifyPaymentResponse> {
|
2025-01-01 23:48:56 +05:00
|
|
|
console.log("payment verify data ->", data);
|
2024-12-25 17:21:04 +05:00
|
|
|
const response = await fetch(
|
|
|
|
"https://verifypaymentsapi.baraveli.dev/verify-payment",
|
|
|
|
{
|
|
|
|
method: "POST",
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
const json = await response.json();
|
2025-01-01 23:48:56 +05:00
|
|
|
console.log(json);
|
2024-12-25 17:21:04 +05:00
|
|
|
if (!payment) {
|
|
|
|
throw new Error("Payment verification failed or payment not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (json.success) {
|
2025-01-01 23:48:56 +05:00
|
|
|
const expiryDate = new Date();
|
|
|
|
expiryDate.setMonth(expiryDate.getMonth() + payment.numberOfMonths);
|
2024-12-25 17:21:04 +05:00
|
|
|
await prisma.payment.update({
|
|
|
|
where: { id: payment.id },
|
|
|
|
data: {
|
|
|
|
paid: true,
|
|
|
|
paidAt: new Date(),
|
2025-01-08 23:04:30 +05:00
|
|
|
method: "TRANSFER",
|
2024-12-25 17:21:04 +05:00
|
|
|
devices: {
|
2025-01-08 23:04:30 +05:00
|
|
|
updateMany: payment.devices.map((device) => ({
|
|
|
|
where: { id: device.id },
|
|
|
|
data: {
|
|
|
|
isActive: true,
|
|
|
|
expiryDate: expiryDate,
|
|
|
|
},
|
|
|
|
})),
|
2024-12-25 17:21:04 +05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return json;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateDevices(payment: PaymentWithDevices | null) {
|
|
|
|
if (!payment) return;
|
|
|
|
|
|
|
|
const newDevices = payment.devices.map((d) => ({
|
|
|
|
name: d.name,
|
|
|
|
macAddress: formatMacAddress(d.mac),
|
|
|
|
}));
|
|
|
|
|
|
|
|
return await addDevicesToGroup({
|
|
|
|
groupId: process.env.OMADA_GROUP_ID,
|
|
|
|
siteId: process.env.OMADA_SITE_ID,
|
|
|
|
newDevices,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function verifyPayment(data: VerifyPaymentType) {
|
|
|
|
try {
|
|
|
|
const [payment, user] = await Promise.all([
|
|
|
|
prisma.payment.findUnique({
|
|
|
|
where: { id: data.paymentId },
|
|
|
|
include: { devices: true },
|
|
|
|
}),
|
|
|
|
prisma.user.findUnique({
|
|
|
|
where: { id: data.userId },
|
|
|
|
}),
|
|
|
|
]);
|
|
|
|
|
|
|
|
if (data.type === "WALLET") {
|
2025-01-08 23:04:30 +05:00
|
|
|
console.log("WALLET");
|
2024-12-25 17:21:04 +05:00
|
|
|
await processWalletPayment(user, payment, Number(data.absAmount));
|
|
|
|
redirect("/payments");
|
2024-12-09 22:59:13 +05:00
|
|
|
}
|
2025-01-08 23:04:30 +05:00
|
|
|
if (data.type === "TRANSFER") {
|
|
|
|
console.log({ data, payment });
|
|
|
|
const verificationResult = await verifyExternalPayment(data, payment);
|
|
|
|
await updateDevices(payment);
|
2024-12-13 11:24:13 +05:00
|
|
|
|
2025-01-08 23:04:30 +05:00
|
|
|
revalidatePath("/payment[paymentId]");
|
2024-12-21 00:24:29 +05:00
|
|
|
|
2025-01-08 23:04:30 +05:00
|
|
|
return verificationResult;
|
|
|
|
}
|
2024-12-09 22:59:13 +05:00
|
|
|
} catch (error) {
|
2024-12-25 17:21:04 +05:00
|
|
|
console.error("Payment verification failed:", error);
|
|
|
|
throw error; // Re-throw to handle at a higher level
|
2024-12-09 22:59:13 +05:00
|
|
|
}
|
|
|
|
}
|
2024-12-13 11:24:13 +05:00
|
|
|
|
|
|
|
export async function addDevicesToOmada() {
|
|
|
|
console.log("hi");
|
|
|
|
}
|