UNPKG

@coin-voyage/paykit

Version:

Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.

73 lines (72 loc) 2.91 kB
import { PayOrderMode, PayOrderStatus, } from "@coin-voyage/shared/types"; import { useEffect, useMemo, useRef } from "react"; /** * Handles payment lifecycle events of an order, such as started, completed, and bounced. * @param {PayOrder | undefined} order The pay order to monitor. * @param {PaymentLifecycleHandlers} handlers Handlers for payment lifecycle events. * @returns */ export function usePaymentLifecycle(order, handlers) { const sentStart = useRef(false); const sentComplete = useRef(false); const { onPaymentStarted, onPaymentCompleted, onPaymentBounced } = handlers; const orderStatus = order?.status; const isSale = order?.mode === PayOrderMode.SALE; const completedStates = useMemo(() => [PayOrderStatus.COMPLETED, PayOrderStatus.REFUNDED], []); const isStarted = useMemo(() => { if (!orderStatus) return false; const startedStatus = [ ...completedStates, PayOrderStatus.AWAITING_CONFIRMATION, PayOrderStatus.OPTIMISTIC_CONFIRMED, PayOrderStatus.EXECUTING_ORDER, ]; return startedStatus.includes(orderStatus); }, [orderStatus, completedStates]); const isFinalized = useMemo(() => { if (!orderStatus) return false; const finalizedStatus = [...completedStates]; if (isSale) { finalizedStatus.push(PayOrderStatus.OPTIMISTIC_CONFIRMED, PayOrderStatus.EXECUTING_ORDER); } return finalizedStatus.includes(orderStatus); }, [orderStatus, isSale, completedStates]); useEffect(() => { if (sentStart.current || !order?.payment || !isStarted) return; sentStart.current = true; onPaymentStarted?.({ type: "payorder_confirming", payorder_id: order.id, status: order.status, metadata: order.metadata, payment_data: order.payment, }); }, [order, isStarted, onPaymentStarted]); useEffect(() => { if (sentComplete.current || !order?.payment || !isFinalized) return; sentComplete.current = true; if (order.status === PayOrderStatus.REFUNDED) { onPaymentBounced?.({ type: "payorder_refunded", payorder_id: order.id, status: order.status, metadata: order.metadata, refund_address: order.payment.refund_address, refund_tx_hash: order.refund_tx_hash ?? "", }); return; } onPaymentCompleted?.({ type: "payorder_completed", payorder_id: order.id, status: order.status, metadata: order.metadata, payment_data: order.payment, }); }, [order, isFinalized, onPaymentCompleted, onPaymentBounced]); return { isStarted, isFinalized, order }; }