使用@paypal/react-paypal-js时,移动端onApprove函数不执行问题
React中@paypal/react-paypal-js移动端(iPhone Chrome/Safari)onApprove不执行问题
我在React项目中使用@paypal/react-paypal-js实现支付功能,桌面端运行正常,但在iPhone的Chrome/Safari浏览器里,onApprove函数完全不触发,PayPal按钮一直显示加载动画。相关代码如下:
// Paypal provider import { PayPalScriptProvider } from '@paypal/react-paypal-js'; import { PayPalButtons } from '@paypal/react-paypal-js'; <div style={{ margin: 20 }}> <PayPalButtons style={{ layout: 'vertical', color: 'black', shape: 'rect', label: 'paypal', }} createOrder={async (data, actions) => { const functions = getFunctions(); const paypalCreateOrder = httpsCallable(functions, 'paypalCreateOrder'); paypalCreateOrder(/*Empty*/).then((response: any) => { return response.data.id; }); } }} onApprove={async (data, actions) => { alert('Payment Approved !!!'); // Cloud Function const functions = getFunctions(); const paypalHandleOrder = httpsCallable(functions, 'paypalHandleOrder'); await paypalHandleOrder({ orderId: data.orderID }) .then((response: any) => { _authContext.updatePremiumUntil(); }) .catch((error) => { errorHandling(error, 'Payment error has happened', 'BodyPayPal onApprove', dispatch, setSnackBarMsg); }); dispatch(setSnackBarMsg({ bool: true, msg: 'Payment has been accepted' })); }} onCancel={() => { handleCancel(); }} onError={(error) => { errorHandling(error, 'Payment error has happened', 'BodyPayPal onError', dispatch, setSnackBarMsg); }} /> </div>
可能的原因分析
1. createOrder函数未正确返回订单ID
你的createOrder标记为async函数,但内部使用.then()回调后没有返回Promise,导致PayPal SDK无法获取到订单ID。移动端浏览器的异步处理逻辑更严格,直接卡住后续流程。正确写法应该用await直接获取结果并返回:
createOrder={async (data, actions) => { const functions = getFunctions(); const paypalCreateOrder = httpsCallable(functions, 'paypalCreateOrder'); const response = await paypalCreateOrder(/*Empty*/); return response.data.id; }}
2. 移动端隐私策略限制
iPhone的Safari默认开启智能跟踪预防(ITP),Chrome iOS也采用类似隐私策略,可能阻止PayPal SDK的第三方Cookie或跨域请求,导致支付完成后无法回调onApprove。可以:
- 检查PayPal商家后台的返回域名配置,确保当前域名已添加
- 确认云函数的CORS设置,允许移动端请求正常通过
3. onApprove中的异步操作未正确处理状态
onApprove里的paypalHandleOrder如果在移动端出现超时或未捕获的错误,且错误处理逻辑没有重置按钮加载状态,会导致按钮一直显示加载。建议:
- 在
onApprove开头调用actions.order.get()确认订单状态,避免无效操作 - 确保
errorHandling函数包含重置PayPal按钮加载状态的逻辑
4. SDK版本兼容性问题
@paypal/react-paypal-js的部分版本可能在iOS的WebKit内核(Safari/Chrome)存在兼容性Bug。可以尝试升级到最新稳定版,或者指定兼容的SDK版本:
<PayPalScriptProvider options={{ "client-id": "YOUR_CLIENT_ID", "vault": false, "version": "5.0.0" }}> {/* 你的PayPalButtons组件 */} </PayPalScriptProvider>
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

