瀏覽代碼

fix(safepay): use AppState to reliably trigger callback on iOS

zbb 1 月之前
父節點
當前提交
326c15b248
共有 1 個文件被更改,包括 29 次插入10 次删除
  1. 29 10
      app/safepay.tsx

+ 29 - 10
app/safepay.tsx

@@ -1,7 +1,13 @@
 import { Colors } from "@/constants/Colors";
 import { useLocalSearchParams, useRouter } from "expo-router";
 import { useEffect } from "react";
-import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
+import {
+    ActivityIndicator,
+    AppState,
+    StyleSheet,
+    Text,
+    View,
+} from "react-native";
 
 /**
  * Alipay Callback Handler
@@ -15,21 +21,34 @@ export default function AlipayResult() {
   useEffect(() => {
     console.log("Alipay callback params:", params);
 
-    // The native SDK (expo-native-alipay) listens for the app verify event
-    // and resolves the Promise in the calling component (Recharge/Checkout).
-    // This route mainly exists to prevent "Unmatched Route" errors.
-    // We simply dismiss it to reveal the underlying screen.
-    const timer = setTimeout(() => {
-      // Use router.dismiss() if available in stack, or back()
+    let hasNavigated = false;
+    let fallbackTimer: ReturnType<typeof setTimeout>;
+
+    const navigateBack = () => {
+      if (hasNavigated) return;
+      hasNavigated = true;
       if (router.canGoBack()) {
         router.back();
       } else {
-        // Fallback if launched directly (unlikely for payment callback)
         router.replace("/");
       }
-    }, 500); // Short delay to allow smooth transition
+    };
+
+    // Listen for AppState changes to know when user actually returns to the app
+    const subscription = AppState.addEventListener("change", (nextAppState) => {
+      if (nextAppState === "active") {
+        // App has returned to foreground. Give a tiny delay for React Native to settle.
+        setTimeout(navigateBack, 500);
+      }
+    });
+
+    // Fallback: if AppState doesn't trigger for some reason, navigate after a max delay (e.g., 2000ms)
+    fallbackTimer = setTimeout(navigateBack, 2000);
 
-    return () => clearTimeout(timer);
+    return () => {
+      subscription.remove();
+      clearTimeout(fallbackTimer);
+    };
   }, []);
 
   return (