71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
import { PaymentStatus, PaymePaymentResponse } from './types';
|
|
import {
|
|
calculateTotal,
|
|
createPaymePayment,
|
|
generateOrderId,
|
|
redirectToPayme,
|
|
toTiyin,
|
|
} from './utils';
|
|
import { PAYME_CONFIG } from './constant';
|
|
|
|
interface UsePaymentOptions {
|
|
hasCertificate: boolean;
|
|
onSuccess?: (response: PaymePaymentResponse) => void;
|
|
onError?: (error: Error) => void;
|
|
}
|
|
|
|
interface UsePaymentReturn {
|
|
status: PaymentStatus;
|
|
error: string | null;
|
|
totalAmount: number;
|
|
handlePaymePayment: () => Promise<void>;
|
|
resetError: () => void;
|
|
}
|
|
|
|
export const usePayment = ({
|
|
hasCertificate,
|
|
onSuccess,
|
|
onError,
|
|
}: UsePaymentOptions): UsePaymentReturn => {
|
|
const [status, setStatus] = useState<PaymentStatus>('idle');
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const totalAmount = calculateTotal(hasCertificate);
|
|
|
|
const handlePaymePayment = useCallback(async () => {
|
|
setStatus('loading');
|
|
setError(null);
|
|
|
|
const orderId = generateOrderId();
|
|
|
|
try {
|
|
const response = await createPaymePayment({
|
|
amount: toTiyin(totalAmount),
|
|
orderId,
|
|
description: `Service fee${hasCertificate ? ' + Certificate' : ''}`,
|
|
returnUrl: PAYME_CONFIG.RETURN_URL,
|
|
});
|
|
|
|
setStatus('success');
|
|
onSuccess?.(response);
|
|
redirectToPayme(response.redirectUrl);
|
|
} catch (err) {
|
|
const paymentError =
|
|
err instanceof Error
|
|
? err
|
|
: new Error('Payment failed. Please try again.');
|
|
setStatus('error');
|
|
setError(paymentError.message);
|
|
onError?.(paymentError);
|
|
}
|
|
}, [totalAmount, hasCertificate, onSuccess, onError]);
|
|
|
|
const resetError = useCallback(() => {
|
|
setError(null);
|
|
setStatus('idle');
|
|
}, []);
|
|
|
|
return { status, error, totalAmount, handlePaymePayment, resetError };
|
|
};
|