w-lab-app/src/hooks/payment/useSingleCheckout.ts
dev.daminik00 1adac2836b add video
2025-10-28 05:58:51 +01:00

90 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useCallback, useMemo, useState } from "react";
import { performSingleCheckout } from "@/entities/payment/actions";
import { PaymentInfo, SingleCheckoutRequest } from "@/entities/payment/types";
interface UseSingleCheckoutOptions {
returnUrl?: string;
onSuccess?: () => void;
onError?: (error: string) => void;
}
export function useSingleCheckout(options: UseSingleCheckoutOptions = {}) {
const [isLoading, setIsLoading] = useState(false);
const { returnUrl, onSuccess, onError } = options;
const handleSingleCheckout = useCallback(
async (paymentInfo: PaymentInfo) => {
if (isLoading) return;
setIsLoading(true);
let shouldResetLoading = true;
try {
const payload: SingleCheckoutRequest = {
paymentInfo,
pageUrl: typeof window !== "undefined" ? window.location.href : "",
return_url: returnUrl,
};
const response = await performSingleCheckout(payload);
if (response.error) {
onError?.(response.error);
return;
}
if (!response.data) {
onError?.("Payment failed");
return;
}
if ("payment" in response.data) {
const { status, paymentUrl } = response.data.payment;
if (paymentUrl) {
// При редиректе на внешний платеж не сбрасываем isLoading
shouldResetLoading = false;
window.location.replace(paymentUrl);
return;
}
if (status === "paid") {
// При успешной покупке НЕ сбрасываем isLoading
// onSuccess callback сам будет управлять состоянием через isNavigating
shouldResetLoading = false;
await onSuccess?.();
return;
} else {
onError?.("Payment status is not paid");
}
} else {
const errorMessage = response.data.message || "Payment failed";
onError?.(errorMessage);
}
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : "Payment failed";
onError?.(errorMessage);
} finally {
// Сбрасываем isLoading только если не было успешного платежа или редиректа
if (shouldResetLoading) {
setIsLoading(false);
}
}
},
[isLoading, returnUrl, onError, onSuccess]
);
return useMemo(
() => ({
handleSingleCheckout,
isLoading,
}),
[handleSingleCheckout, isLoading]
);
}