PayWaitingContent.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { useEffect, useRef } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { PayOrderStatus } from '@/defines';
  4. import { fetchPayOrderStatus } from '@/services/config';
  5. const POLL_INTERVAL_MS = 2500;
  6. export interface PayWaitingContentProps {
  7. orderId: string;
  8. onClose: () => void;
  9. /** 支付成功时调用(刷新用户数据、提示等),随后会调用 onClose */
  10. onPaymentSuccess?: () => void | Promise<void>;
  11. }
  12. export function PayWaitingContent({ orderId, onClose, onPaymentSuccess }: PayWaitingContentProps) {
  13. const { t } = useTranslation();
  14. const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  15. useEffect(() => {
  16. const poll = () => {
  17. fetchPayOrderStatus({ orderId })
  18. .then(async (res) => {
  19. const state = res?.data?.orderState;
  20. if (state === PayOrderStatus.PAID || state === PayOrderStatus.FAILED) {
  21. if (timerRef.current) {
  22. clearInterval(timerRef.current);
  23. timerRef.current = null;
  24. }
  25. if (state === PayOrderStatus.PAID && onPaymentSuccess) {
  26. await Promise.resolve(onPaymentSuccess());
  27. }
  28. onClose();
  29. }
  30. })
  31. .catch(() => {});
  32. };
  33. poll();
  34. timerRef.current = setInterval(poll, POLL_INTERVAL_MS);
  35. return () => {
  36. if (timerRef.current) {
  37. clearInterval(timerRef.current);
  38. }
  39. };
  40. }, [orderId, onClose, onPaymentSuccess]);
  41. return (
  42. <p className="text-white/90 text-sm leading-[1.43]">
  43. {t('pages.pricing.payFlow.waitingDesc')}
  44. </p>
  45. );
  46. }