Expo集成Stripe时出现Possible Unhandled Promise Rejection网络请求失败问题
解决Expo + Stripe集成中的Network request failure错误
常见原因及排查步骤
1. 本地服务器地址配置问题
- 绝对不能用
localhost作为后端请求地址,Expo模拟器/真机无法直接访问电脑的本地回环地址,必须替换成电脑的局域网IP(比如http://192.168.x.x:3000)。 - 核对前端
handlePayPress里调用后端的API地址,确保和服务器启动的IP、端口完全匹配。
2. CORS跨域配置缺失
- 后端必须配置CORS允许Expo项目访问,否则会被浏览器/设备拦截请求。用
cors包的话,测试阶段可以暂时放开权限:import cors from 'cors'; app.use(cors({ origin: '*' })); // 生产环境务必限制为指定域名
3. 服务器端口或防火墙拦截
- 检查后端监听的端口(比如3000)是否被电脑防火墙、杀毒软件拦截,可临时关闭防火墙测试,或给端口添加放行规则。
- 确认服务器正常运行:
nodemon server.mjs终端不能有报错,需显示类似Listening on port 3000的日志。
4. Stripe密钥配置错误
- 后端必须用测试密钥(
sk_test_开头),前端用对应测试模式的发布密钥(pk_test_开头),混用生产密钥会直接导致请求失败。 - 核对密钥是否复制完整,有没有多余空格或字符。
5. 请求解析或参数问题
- 后端必须添加
express.json()中间件,否则无法解析前端发送的JSON请求体:app.use(express.json()); - 检查前端
handlePayPress中发送的参数(比如amount)是否符合后端要求,比如金额单位是否为分(Stripe要求)。
示例代码修正参考
后端server.mjs核心片段
import express from 'express'; import cors from 'cors'; import Stripe from 'stripe'; const app = express(); const stripe = new Stripe('sk_test_你的测试密钥'); // 配置CORS和请求解析 app.use(cors({ origin: '*' })); app.use(express.json()); // 创建PaymentIntent接口 app.post('/create-payment-intent', async (req, res) => { try { const { amount } = req.body; const paymentIntent = await stripe.paymentIntents.create({ amount: amount, currency: 'usd', }); res.json({ clientSecret: paymentIntent.client_secret }); } catch (error) { res.status(500).json({ error: error.message }); } }); // 启动服务器,打印局域网IP app.listen(3000, () => { console.log('Server running on http://192.168.x.x:3000'); // 替换为你的实际IP });
前端Card.js核心片段
import { StripeProvider, PaymentElement, useStripe, useElements } from '@stripe/stripe-react-native'; import { Button } from 'react-native'; const CardScreen = () => { const stripe = useStripe(); const elements = useElements(); const handlePayPress = async () => { if (!stripe || !elements) return; try { // 用局域网IP请求后端 const response = await fetch('http://192.168.x.x:3000/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: 1000 }), // 10美元,单位为分 }); if (!response.ok) throw new Error('创建支付意向失败'); const { clientSecret } = await response.json(); const { error } = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'expo://your-app-scheme', // 替换为你的Expo应用scheme }, }); error ? console.error('支付错误:', error.message) : console.log('支付成功'); } catch (err) { console.error('请求失败:', err); } }; return ( <StripeProvider publishableKey="pk_test_你的测试密钥"> <PaymentElement /> <Button title="支付" onPress={handlePayPress} /> </StripeProvider> ); }; export default CardScreen;
验证步骤
- 重启后端服务器,确认终端显示的IP和端口正确。
- 确保Expo模拟器/真机和电脑在同一局域网内。
- 替换前端请求地址为电脑实际局域网IP,重新测试支付流程。
内容的提问来源于stack exchange,提问作者lipian
相关产品推荐
相关产品推荐

