"use server"; import prisma from "@/lib/db"; import type { PaymentType } from "@/lib/types"; import { formatMacAddress } from "@/lib/utils"; import type { Prisma } from "@prisma/client"; import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; import { addDevicesToGroup } from "./omada-actions"; export async function createPayment(data: PaymentType) { 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, }; }), }, }, }); redirect(`/payments/${payment.id}`); } type VerifyPaymentType = { userId: string; paymentId?: string; benefName: string; accountNo?: string; absAmount: string; time: string; type?: "TRANSFER" | "WALLET"; }; type PaymentWithDevices = Prisma.PaymentGetPayload<{ include: { devices: true; }; }>; 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(); } const expiryDate = new Date(); expiryDate.setMonth(expiryDate.getMonth() + payment.numberOfMonths); await prisma.$transaction([ prisma.payment.update({ where: { id: payment.id }, data: { paid: true, paidAt: new Date(), method: "WALLET", devices: { updateMany: payment.devices.map((device) => ({ where: { id: device.id }, data: { isActive: true, expiryDate: expiryDate, }, })), }, }, }), 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; }; }; async function verifyExternalPayment( data: VerifyPaymentType, payment: PaymentWithDevices | null, ): Promise { console.log("payment verify data ->", data); 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(); console.log(json); if (!payment) { throw new Error("Payment verification failed or payment not found"); } if (json.success) { const expiryDate = new Date(); expiryDate.setMonth(expiryDate.getMonth() + payment.numberOfMonths); await prisma.payment.update({ where: { id: payment.id }, data: { paid: true, paidAt: new Date(), method: "TRANSFER", devices: { updateMany: payment.devices.map((device) => ({ where: { id: device.id }, data: { isActive: true, expiryDate: expiryDate, }, })), }, }, }); } 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") { console.log("WALLET"); await processWalletPayment(user, payment, Number(data.absAmount)); redirect("/payments"); } if (data.type === "TRANSFER") { console.log({ data, payment }); const verificationResult = await verifyExternalPayment(data, payment); await updateDevices(payment); revalidatePath("/payment[paymentId]"); return verificationResult; } } catch (error) { console.error("Payment verification failed:", error); throw error; // Re-throw to handle at a higher level } } export async function addDevicesToOmada() { console.log("hi"); }