"use server"; import { revalidatePath } from "next/cache"; import { getServerSession } from "next-auth"; import { authOptions } from "@/app/auth"; import type { ApiError, ApiResponse, NewPayment, Payment, Topup } from "@/lib/backend-types"; import type { TopupResponse } from "@/lib/types"; import type { User } from "@/lib/types/user"; import { handleApiResponse } from "@/utils/tryCatch"; type GenericGetResponseProps = { offset?: number; limit?: number; page?: number; [key: string]: string | number | undefined; }; export async function createPayment(data: NewPayment) { const session = await getServerSession(authOptions); console.log("data", data); const response = await fetch( `${process.env.SARLINK_API_BASE_URL // }); }/api/billing/payment/`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, body: JSON.stringify(data), }, ); if (!response.ok) { const errorData = (await response.json()) as ApiError; const errorMessage = errorData.message || errorData.detail || "An error occurred."; const error = new Error(errorMessage); (error as ApiError & { details?: ApiError }).details = errorData; // Attach the errorData to the error object throw error; } const payment = (await response.json()) as Payment; revalidatePath("/devices"); return payment; } export async function createTopup(data: { amount: number }) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/topup/`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, body: JSON.stringify(data), }, ); return handleApiResponse(response, "createTopup"); } export async function getPayment({ id }: { id: string }) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/payment/${id}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); if (!response.ok) { const errorData = (await response.json()) as ApiError; const errorMessage = errorData.message || errorData.detail || "An error occurred."; const error = new Error(errorMessage); (error as ApiError & { details?: ApiError }).details = errorData; // Attach the errorData to the error object throw error; } const data = (await response.json()) as Payment; return data; } type GetPaymentProps = { [key: string]: string | number | undefined; // Allow additional properties for flexibility }; export async function getPayments(params: GetPaymentProps) { // Build query string from all defined params const query = Object.entries(params) .filter(([_, value]) => value !== undefined && value !== "") .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) .join("&"); const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/payment/?${query}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); if (!response.ok) { const errorData = (await response.json()) as ApiError; const errorMessage = errorData.message || errorData.detail || "An error occurred."; const error = new Error(errorMessage); (error as ApiError & { details?: ApiError }).details = errorData; // Attach the errorData to the error object throw error; } const data = (await response.json()) as ApiResponse; return data; } export async function getTopups(params: GenericGetResponseProps) { // Build query string from all defined params const query = Object.entries(params) .filter(([_, value]) => value !== undefined && value !== "") .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) .join("&"); const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/topup/?${query}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); return handleApiResponse>(response, "getTopups"); } export async function getTopup({ id }: { id: string }) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/topup/${id}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); return handleApiResponse(response, "getTopup"); } export async function cancelTopup({ id }: { id: string }) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/topup/${id}/delete/`, { method: "DELETE", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); if (!response.ok) { const errorData = (await response.json()) as ApiError; const errorMessage = errorData.message || errorData.detail || "An error occurred."; const error = new Error(errorMessage); (error as ApiError & { details?: ApiError }).details = errorData; // Attach the errorData to the error object throw error; } return { message: "Topup successfully canceled." }; } export async function cancelPayment({ id }: { id: string }) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/payment/${id}/delete/`, { method: "DELETE", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); if (!response.ok) { const errorData = (await response.json()) as ApiError; const errorMessage = errorData.message || errorData.detail || "An error occurred."; const error = new Error(errorMessage); (error as ApiError & { details?: ApiError }).details = errorData; // Attach the errorData to the error object throw error; } return { message: "Payment successfully canceled." }; } type UpdatePayment = { id: string; method: "TRANSFER" | "WALLET"; benefName?: string; accountNo?: string; absAmount?: string; time?: string; }; export async function verifyPayment({ id, method }: UpdatePayment) { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/payment/${id}/verify/`, { method: "PUT", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, body: JSON.stringify({ method, }), }, ); revalidatePath("/payments/[paymentId]", "page"); return handleApiResponse(response, "updatePayment"); } export type VerifyTopupPaymentState = { transaction?: { sourceBank: string; trxDate: string; }; message: string; success: boolean; fieldErrors: Record; payload?: FormData; } export async function verifyTopupPayment( _prevState: VerifyTopupPaymentState, formData: FormData ): Promise { const session = await getServerSession(authOptions); // Get the topup ID from the form data or use a hidden input const topupId = formData.get('topupId') as string; if (!topupId) { return { message: "Topup ID is required", success: false, fieldErrors: { topupId: "Topup ID is required" }, }; } try { const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/billing/topup/${topupId}/verify/`, { method: "PUT", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); const result = await handleApiResponse(response, "verifyTopupPayment"); revalidatePath("/top-ups/[topupId]", "page"); return { message: result.message || "Topup payment verified successfully", success: true, fieldErrors: {}, transaction: result.transaction, }; } catch (error: unknown) { if (error instanceof Error) { return { message: error.message || "Please check your payment details and try again.", success: false, fieldErrors: {}, }; } else { return { message: "Topup verification failed.", success: false, fieldErrors: {}, }; } } } export async function getProfile() { const session = await getServerSession(authOptions); const response = await fetch( `${process.env.SARLINK_API_BASE_URL}/api/auth/profile/`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: `Token ${session?.apiToken}`, }, }, ); return handleApiResponse(response, "getProfile"); }