import { useModalsManagerContext } from "@/contexts/ModalsManagerContext"; import type { IpaymentStackNavigator } from "@/navigations/Types"; import { type IorangePaymentStarter, getTransactionStatus, getTransactionsData, } from "@/utils/requests/orangePayment"; import ErrorModal from "@components/modals/ErrorModal"; import InformationModal from "@components/modals/InformationModal"; import LoadingModal from "@components/modals/LoadingModal"; import { LOG } from "@logger"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import * as WebBrowser from "expo-web-browser"; import { useState } from "react"; const log = LOG.extend("useOrangeMoney"); const paymentObjectDefault: IorangePaymentStarter = { // biome-ignore lint/style/useNamingConvention: type_paiement: 1, marchand: "1", service: "1", montant: 0, numero: "0707070707", commentaire: "Un commentaire", }; const useOrangeMoney = ( navigation?: NativeStackNavigationProp< IpaymentStackNavigator, "paymentAmountInputScreen", "IpaymentStackNavigator" >, ) => { const queryClient = useQueryClient(); const [isBrowserOpen, setIsBrowserOpen] = useState(false); const { showModal, closeModal } = useModalsManagerContext(); const handlePaymentUsingBrowser = async (url: string) => { setIsBrowserOpen(true); const result = await WebBrowser.openBrowserAsync(url); // setResult(result); log.debug("handlePaymentUsingBrowser | Result ::", result); setIsBrowserOpen(false); }; const orangeTransactionInitializerMutation = useMutation({ mutationFn: (amount: number) => getTransactionsData({ ...paymentObjectDefault, montant: amount, }), onSuccess: (data) => { // return data.payment_url log.debug("orangeTransactionInitializerMutation request success, opening browser..."); queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] }); // await handlePaymentUsingBrowser(data.payment_url); // await transactionsStatusMutation.mutate(data.order_id); // setResult(result); }, onError: (err) => { log.error("orangeTransactionInitializerMutation |", err); }, }); const maxRetry = 3; const retryDelay = 5000; const transactionsStatusMutation = useMutation({ mutationFn: (orderId: string) => getTransactionStatus(orderId), onSuccess: (data) => { log.debug("transactionsStatusMutation request success"); queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] }); return data.status; }, onError: (err) => { log.error("transactionsStatusMutation |", err); queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] }); }, // retry: (failureCount, error) => { // log.warn("transactionsStatusMutation | retrying", failureCount, error); // return failureCount < maxRetry; // }, // retryDelay(_failureCount, _error) { // return retryDelay; // }, }); const openBrowserThenCheckStatus = async (paymentUrl: string, orderId: string) => { try { await handlePaymentUsingBrowser(paymentUrl); log.info("openBrowserThenCheckStatus | Verifying transaction status..."); showModal(); await transactionsStatusMutation.mutateAsync(orderId); closeModal(); navigation?.getParent()?.navigate("paymentResultScreen"); } catch (error) { log.error("openBrowserThenCheckStatus |", error); if (error instanceof Error) { if (error.name === "ORANGE_PAYMENT_IN_PROGRESS") { log.warn("openBrowserThenCheckStatus | ORANGE_PAYMENT_IN_PROGRESS"); await showModal( openBrowserThenCheckStatus(paymentUrl, orderId)} />, ); } else if (error.name === "ORANGE_PAYMENT_FAILED") { showModal(); log.error("openBrowserThenCheckStatus | ORANGE_PAYMENT_FAILED"); } } else { log.error("openBrowserThenCheckStatus |", error); closeModal(); throw error; } } }; const orangePaymentTransactionHandler = async (amount: number) => { try { showModal(); const { payment_url, order_id } = await orangeTransactionInitializerMutation.mutateAsync(amount); log.info("orangePaymentTransactionHandler |", payment_url, order_id); log.info("Opening browser for payment..."); await openBrowserThenCheckStatus(payment_url, order_id); } catch (error) { log.error("makePayment |", error); throw error; } finally { //closeModal(); // just to be ultra sure that the modal is closed } }; return { orangeTransactionInitializerMutation: orangeTransactionInitializerMutation, handlePaymentUsingBrowser, isBrowserOpen, isWaitingForOmPaymentUrl: orangeTransactionInitializerMutation.isPending, isCheckingForTransactionStatus: transactionsStatusMutation.isPending, transactionsStatusMutation, orangePaymentTransactionHandler, }; }; export default useOrangeMoney;