Prechádzať zdrojové kódy

fix(alipay): remove safepay UI and convert AppState fallback to immediate polling for instant animation

zbb 1 mesiac pred
rodič
commit
b154d69188

+ 1 - 1
app.json

@@ -12,7 +12,7 @@
       "supportsTablet": false,
       "bundleIdentifier": "com.asios",
       "appleTeamId": "Y9ZVX3FRX6",
-      "buildNumber": "9",
+      "buildNumber": "10",
       "infoPlist": {
         "ITSAppUsesNonExemptEncryption": false,
         "NSPhotoLibraryUsageDescription": "App需要访问您的相册以便您可以上传头像或保存商品分享图片。",

+ 25 - 18
app/award-detail/components/CheckoutModal.tsx

@@ -286,31 +286,38 @@ export const CheckoutModal = forwardRef<CheckoutModalRef, CheckoutModalProps>(
             "change",
             async (nextAppState) => {
               if (nextAppState === "active" && !isResolved) {
-                // Wait a bit to give the SDK a chance to resolve natively first
-                setTimeout(async () => {
-                  if (!isResolved) {
-                    console.log(
-                      "Alipay SDK did not resolve, checking server manually...",
-                    );
-                    try {
-                      const res = await getApplyResult(tradeNo);
-                      if (
-                        res?.paySuccess ||
-                        (res?.inventoryList && res.inventoryList.length > 0)
-                      ) {
-                        isResolved = true;
-                        handleSuccess(tradeNo);
-                      }
-                    } catch (e) {
-                      console.log("Fallback check failed", e);
+                // 瞬间回退没有拿到原生支付结果时,立即开始每秒轮询后端
+                let attempts = 0;
+                const pollInterval = setInterval(async () => {
+                  if (isResolved) {
+                    clearInterval(pollInterval);
+                    return;
+                  }
+                  attempts++;
+                  try {
+                    const res = await getApplyResult(tradeNo);
+                    if (
+                      res?.paySuccess ||
+                      (res?.inventoryList && res.inventoryList.length > 0)
+                    ) {
+                      isResolved = true;
+                      clearInterval(pollInterval);
+                      handleSuccess(tradeNo);
                     }
+                  } catch (e) {
+                    console.log("Fallback poll failed", e);
+                  }
+                  if (attempts >= 5) {
+                    // 5秒后放弃
+                    clearInterval(pollInterval);
                   }
-                }, 3000);
+                }, 1000);
               }
             },
           );
 
           const result = await Alipay.pay(payInfo);
+          if (isResolved) return; // if fallback already worked
           isResolved = true;
           console.log("Alipay Result:", result);
 

+ 2 - 1
app/purse/recharge.tsx

@@ -85,12 +85,13 @@ export default function RechargeScreen() {
                     Alert.alert("提示", "充值已发起,请稍后查看余额");
                     router.replace("/wallet/recharge_record");
                   }
-                }, 3000);
+                }, 500); // 0.5秒后提示充值已发起
               }
             },
           );
 
           const result = await Alipay.pay(payInfo);
+          if (isResolved) return;
           isResolved = true;
           console.log("Alipay Result:", result);
 

+ 9 - 56
app/safepay.tsx

@@ -1,69 +1,22 @@
-import { Colors } from "@/constants/Colors";
-import { useLocalSearchParams, useRouter } from "expo-router";
+import { useRouter } from "expo-router";
 import { useEffect } from "react";
-import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
 
 /**
  * Alipay Callback Handler
  * Handles the "asios://safepay" deep link from Alipay.
- * Automatically goes back to invoke the native SDK's callback handling.
+ * 仅仅作为 deep link 的接收器,没有 UI,瞬间返回上一页。
  */
 export default function AlipayResult() {
   const router = useRouter();
-  const params = useLocalSearchParams();
 
   useEffect(() => {
-    console.log("Alipay callback params:", params);
-
-    // In TestFlight/Release builds, performing a router.back() or router.dismiss() here
-    // forces a React Navigation transition that often unmounts the underlying component
-    // (CheckoutModal) BEFORE the native `Alipay.pay()` Promise has time to resolve and
-    // trigger `handleSuccess`.
-
-    // Instead of forcing a navigation here, we simply act as a passive sink for the deep link
-    // to prevent the "Unmatched Route" warning. We trust the original `Alipay.pay()`
-    // call in CheckoutModal to receive its native completion event and navigate the user
-    // to the result screen (e.g., /happy-spin) which will naturally replace this route.
-
-    // To ensure the user isn't stuck if the payment was cancelled or failed natively,
-    // we provide a manual close button, or rely on them swiping back.
+    // 只要进入这个页面,直接默默退回上一页,不显示任何多余 UI。
+    if (router.canGoBack()) {
+      router.back();
+    } else {
+      router.replace("/");
+    }
   }, []);
 
-  return (
-    <View style={styles.container}>
-      <ActivityIndicator size="large" color={Colors.neonBlue || "#00F3FF"} />
-      <Text style={styles.text}>正在确认支付结果...</Text>
-      <Text
-        style={styles.subtext}
-        onPress={() => {
-          if (router.canGoBack()) router.back();
-          else router.replace("/");
-        }}
-      >
-        如长时间未响应,请点击此处返回
-      </Text>
-    </View>
-  );
+  return null;
 }
-
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-    justifyContent: "center",
-    alignItems: "center",
-    backgroundColor: Colors.darkBg || "#121212",
-  },
-  text: {
-    marginTop: 20,
-    color: Colors.textSecondary || "#aaa",
-    fontSize: 16,
-    fontWeight: "bold",
-  },
-  subtext: {
-    marginTop: 30,
-    color: Colors.neonPink || "#FF007F",
-    fontSize: 14,
-    textDecorationLine: "underline",
-    padding: 10,
-  },
-});

+ 2 - 1
app/store/components/CheckoutModal.tsx

@@ -165,12 +165,13 @@ export default function CheckoutModal({
                     showAlert("支付完成正在核实");
                     onSuccess();
                   }
-                }, 3000);
+                }, 500); // 瞬间回退没有拿到原生支付结果时,0.5秒后默认成功并刷新列表验证
               }
             },
           );
 
           const result = await Alipay.pay(res.payInfo);
+          if (isResolved) return;
           isResolved = true;
           console.log("Alipay Result:", result);
 

+ 25 - 18
app/treasure-hunt/components/CheckoutModal.tsx

@@ -286,31 +286,38 @@ export const CheckoutModal = forwardRef<CheckoutModalRef, CheckoutModalProps>(
             "change",
             async (nextAppState) => {
               if (nextAppState === "active" && !isResolved) {
-                // Wait a bit to give the SDK a chance to resolve natively first
-                setTimeout(async () => {
-                  if (!isResolved) {
-                    console.log(
-                      "Alipay SDK did not resolve, checking server manually...",
-                    );
-                    try {
-                      const res = await getApplyResult(tradeNo);
-                      if (
-                        res?.paySuccess ||
-                        (res?.inventoryList && res.inventoryList.length > 0)
-                      ) {
-                        isResolved = true;
-                        handleSuccess(tradeNo);
-                      }
-                    } catch (e) {
-                      console.log("Fallback check failed", e);
+                // 瞬间回退没有拿到原生支付结果时,立即开始每秒轮询后端
+                let attempts = 0;
+                const pollInterval = setInterval(async () => {
+                  if (isResolved) {
+                    clearInterval(pollInterval);
+                    return;
+                  }
+                  attempts++;
+                  try {
+                    const res = await getApplyResult(tradeNo);
+                    if (
+                      res?.paySuccess ||
+                      (res?.inventoryList && res.inventoryList.length > 0)
+                    ) {
+                      isResolved = true;
+                      clearInterval(pollInterval);
+                      handleSuccess(tradeNo);
                     }
+                  } catch (e) {
+                    console.log("Fallback poll failed", e);
+                  }
+                  if (attempts >= 5) {
+                    // 5秒后放弃
+                    clearInterval(pollInterval);
                   }
-                }, 3000);
+                }, 1000);
               }
             },
           );
 
           const result = await Alipay.pay(payInfo);
+          if (isResolved) return; // if fallback already worked
           isResolved = true;
           console.log("Alipay Result:", result);
 

+ 2 - 1
app/wallet/recharge.tsx

@@ -85,12 +85,13 @@ export default function RechargeScreen() {
                     Alert.alert("提示", "充值已发起,请稍后查看余额");
                     router.replace("/wallet/recharge_record");
                   }
-                }, 3000);
+                }, 500); // 0.5秒后提示充值已发起
               }
             },
           );
 
           const result = await Alipay.pay(payInfo);
+          if (isResolved) return;
           isResolved = true;
           console.log("Alipay Result:", result);