React Native应用在构建模式下访问Stripe支付页面时意外崩溃
解决React Native集成Stripe预览构建模式下闪退问题
核心排查与修复步骤
1. 环境变量注入异常
预览构建模式下,EXPO_PUBLIC_STRIPE_KEY可能未被正确加载:
- 确认构建命令是否正确读取了
.env文件,或通过构建参数传递了环境变量; - 临时添加日志验证密钥是否有效(构建后通过原生控制台查看):
console.log('Stripe密钥:', process.env.EXPO_PUBLIC_STRIPE_KEY);
2. CORS配置限制过严
当前服务端CORS仅允许https://App-production.up.railway.app/,但React Native预览应用的请求源不在此范围内,导致网络请求失败引发闪退:
// 修改服务端CORS配置,调试阶段允许所有来源 app.use(cors({ origin: true }));
3. 金额计算精度问题
服务端金额转换逻辑Math.round(amount * 100) / 10 * 10会导致精度丢失,Stripe要求金额必须是整数(分单位),直接改为:
const amountInCents = Math.round(parseFloat(amount) * 100);
4. 原生层异常未捕获
JS层的try/catch无法捕获所有原生SDK异常,需通过原生工具查看崩溃日志:
- Android:使用
adb logcat *:E查看错误日志; - iOS:通过Xcode控制台获取崩溃堆栈信息。
5. 网络权限缺失
确认预览构建的应用已配置网络访问权限:
- Android:
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />; - iOS:
Info.plist中开启ATS(HTTPS接口无需额外配置)。
代码优化建议
React Native端buy函数优化
const buy = async () => { try { const finalAmount = amount; // 提前校验参数有效性 if (!finalAmount || !quantity || !selectedId) { return Alert.alert("错误", "参数不完整"); } const response = await fetch('https://app-production.up.railway.app/buy', { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ coin: `App - ${priceList[selectedId].time_session}`, quantity: quantity, amount: finalAmount, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ message: "请求失败" })); return Alert.alert("错误", errorData.message); } const data = await response.json(); const initSheet = await stripe.initPaymentSheet({ paymentIntentClientSecret: data.clientSecret, merchantDisplayName: "App", }); if (initSheet.error) { return Alert.alert("初始化支付失败", initSheet.error.message); } const presentSheet = await stripe.presentPaymentSheet(); if (presentSheet.error) { return Alert.alert("支付失败", presentSheet.error.message); } // 先更新本地状态,再处理异步操作 setTotalCoins(prev => prev + finalAmount); setQuantity(1); Alert.alert("支付成功!"); addIncomeTransaction(); const userRef = doc(db, 'users', userID); await updateDoc(userRef, { 'user_billing.balance': totalCoins + finalAmount, 'user_billing.plan_aquisition': PlanAquired, }); } catch (err) { const errorMsg = err instanceof Error ? err.message : "未知错误"; Alert.alert("错误", errorMsg); console.error("支付流程错误:", err); } };
服务端核心逻辑优化
// 修正CORS配置 app.use(cors({ origin: true // 生产环境替换为指定域名 })); // 修正支付金额计算 app.post("/buy", async (req, res) => { try { let { coin, quantity, amount } = req.body; if (!coin || !quantity || !amount) return res.status(400).json({ message: "参数无效,请重试" }); const amountInCents = Math.round(parseFloat(amount) * 100); if (amountInCents <= 0) { return res.status(400).json({ message: "金额必须大于0" }); } const paymentIntent = await stripe.paymentIntents.create({ amount: amountInCents, currency: 'brl', payment_method_types: ["card"], metadata: { coin, quantity, amount }, }); res.json({ message: "初始化支付", clientSecret: paymentIntent.client_secret }); } catch (err) { console.error(err); res.status(500).json({ message: "服务器内部错误" }); } });
内容的提问来源于stack exchange,提问作者LeoMouraIOT
相关产品推荐
相关产品推荐

