mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-07-06 04:36:30 +00:00
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 2m18s
319 lines
8.7 KiB
TypeScript
319 lines
8.7 KiB
TypeScript
"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<Topup>(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<Payment>;
|
|
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<ApiResponse<Topup>>(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<Topup>(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<Payment>(response, "updatePayment");
|
|
}
|
|
|
|
|
|
export type VerifyTopupPaymentState = {
|
|
transaction?: {
|
|
sourceBank: string;
|
|
trxDate: string;
|
|
};
|
|
message: string;
|
|
success: boolean;
|
|
fieldErrors: Record<string, string>;
|
|
payload?: FormData;
|
|
}
|
|
export async function verifyTopupPayment(
|
|
_prevState: VerifyTopupPaymentState,
|
|
formData: FormData
|
|
): Promise<VerifyTopupPaymentState> {
|
|
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<TopupResponse>(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<User>(response, "getProfile");
|
|
}
|