diff --git a/actions/payment.ts b/actions/payment.ts index 82f97df..eb3950d 100644 --- a/actions/payment.ts +++ b/actions/payment.ts @@ -218,6 +218,84 @@ export async function verifyPayment({ id, method }: UpdatePayment) { return handleApiResponse(response, "updatePayment"); } +export type VerifyDevicePaymentState = { + payment?: Payment; + message: string; + success: boolean; + fieldErrors: Record; + payload?: FormData; +} + +export async function verifyDevicePayment( + _prevState: VerifyDevicePaymentState, + formData: FormData +): Promise { + const session = await getServerSession(authOptions); + + // Get the payment ID and method from the form data + const paymentId = formData.get('paymentId') as string; + const method = formData.get('method') as "TRANSFER" | "WALLET"; + + if (!paymentId) { + return { + message: "Payment ID is required", + success: false, + fieldErrors: { paymentId: "Payment ID is required" }, + }; + } + + if (!method) { + return { + message: "Payment method is required", + success: false, + fieldErrors: { method: "Payment method is required" }, + }; + } + + try { + const response = await fetch( + `${process.env.SARLINK_API_BASE_URL}/api/billing/payment/${paymentId}/verify/`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + Authorization: `Token ${session?.apiToken}`, + }, + body: JSON.stringify({ + method, + }), + }, + ); + + const result = await handleApiResponse(response, "verifyDevicePayment"); + + revalidatePath("/payments/[paymentId]", "page"); + + return { + message: method === "WALLET" + ? "Payment completed successfully using wallet!" + : "Payment verification successful!", + success: true, + fieldErrors: {}, + payment: result, + }; + } catch (error: unknown) { + if (error instanceof Error) { + return { + message: error.message || "Payment verification failed. Please try again.", + success: false, + fieldErrors: {}, + }; + } else { + return { + message: "Payment verification failed.", + success: false, + fieldErrors: {}, + }; + } + } +} + export type VerifyTopupPaymentState = { transaction?: { diff --git a/components/devices-to-pay.tsx b/components/devices-to-pay.tsx index 5b14b8c..cb1bba7 100644 --- a/components/devices-to-pay.tsx +++ b/components/devices-to-pay.tsx @@ -6,9 +6,9 @@ import { Loader2, Wallet, } from "lucide-react"; -import { useState } from "react"; +import { useActionState, useEffect, useState } from "react"; import { toast } from "sonner"; -import { verifyPayment } from "@/actions/payment"; +import { type VerifyDevicePaymentState, verifyDevicePayment } from "@/actions/payment"; import { Table, TableBody, @@ -21,13 +21,32 @@ import type { Payment } from "@/lib/backend-types"; import type { User } from "@/lib/types/user"; import { Button } from "./ui/button"; +const initialState: VerifyDevicePaymentState = { + message: "", + success: false, + fieldErrors: {}, +}; + export default function DevicesToPay({ payment, user, }: { payment?: Payment; user?: User }) { - const [verifyingWalletPayment, setVerifyingWalletPayment] = useState(false); - const [verifyingTransferPayment, setVerifyingTransferPayment] = useState(false); + const [state, formAction, isPending] = useActionState(verifyDevicePayment, initialState); + // Handle toast notifications based on state changes + useEffect(() => { + if (state.success && state.message) { + toast.success("Payment successful!", { + closeButton: true, + description: state.message, + }); + } else if (!state.success && state.message && state.message !== initialState.message) { + toast.error("Payment Verification Failed", { + closeButton: true, + description: state.message, + }); + } + }, [state]); const devices = payment?.devices; if (devices?.length === 0) { @@ -81,53 +100,37 @@ export default function DevicesToPay({ ) : (
{isWalletPayVisible && ( - +
+ + + +
)} - +
+ + + +
)}