问题概述: 我面临一个问题,即 Stripe.js 无法加载到我的 React Native 应用程序的 Android WebView 中,导致支付流程无法正常运行。该集成在 iOS 设备上完美运行,但在 Android 上,脚本无法加载。
设置: 我正在尝试在 WebView 中运行以下 HTML 来设置 Stripe 付款方式:
<!DOCTYPE html>
<html>
<head>
<title>Stripe Setup Intent</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://js.stripe.com/v3/"></script>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f5f5f5;
}
.container {
width: 100%;
max-width: 500px;
padding: 20px;
background: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
text-align: center;
overflow-y: auto;
}
h2 { margin-bottom: 20px; }
p { margin-bottom: 40px; }
.spinner {
display: inline-block;
width: 50px;
height: 50px;
border: 3px solid rgba(195, 195, 195, 0.6);
border-radius: 50%;
border-top-color: #636767;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
</style>
</head>
<body>
<div class="container" role="alert">
<h2>Let's setup your payment method</h2>
<p id="status-message">Connecting to Stripe...</p>
<div class="spinner" aria-hidden="true"></div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const stripe = Stripe('<%= stripePublishableKey %>');
const clientSecret = '<%= clientSecret %>';
stripe.confirmAcssDebitSetup(clientSecret, {
payment_method: {
billing_details: {
name: '<%= user.fullName %>',
email: '<%= user.email %>',
},
},
}).then(function(result) {
if (result.error) {
document.querySelector('.container').innerHTML = \`
<p>There was an error setting up your payment method. Please try again.</p>
<p>If the problem persists, please visit the "Contact Us" screen in the app or email us at <a href="mailto:[email protected]">[email protected]</a>.</p>
\`;
} else {
document.querySelector('.container').innerHTML = \`
<p>Your payment method has been successfully set up!</p>
<p>You will be redirected shortly.</p>\`;
}
});
});
window.addEventListener('resize', function() {
if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') {
document.activeElement.scrollIntoView({ behavior: 'smooth' });
}
});
</script>
</body>
</html>
React Native 中的 webview(在 iOS 上工作得很好):
import { View } from 'react-native';
import React from 'react';
import StripeTos from '@Components/StripeTos';
import BackIcon from '@Components/BackIcon';
import { WebView } from 'react-native-webview';
import { styles } from './styles';
import { height, width } from '@Utils/dimensions';
interface Props {
isVisible: boolean;
close: () => void;
htmlStr: string;
}
const StripeWebview = ({ isVisible = false, close, htmlStr = '' }: Props) => {
return (
<View>
<StripeTos
close={close}
onSubmit={() => {}}
open={isVisible}
isWebView
isSwipable={false}
avoidKeyboard={false}
containerStyle={{
width: width(100),
height: height(90),
borderWidth: 0,
backgroundColor: 'white',
}}>
<View style={styles.container}>
<View style={styles.backBtn}>
<BackIcon onPress={close} />
</View>
{isVisible && (
<WebView
source={{ html: htmlStr }}
style={{
flex: 1,
}}
scalesPageToFit={true}
javaScriptEnabled={true}
domStorageEnabled={true}
mixedContentMode="always"
onMessage={event => {
console.log(event.nativeEvent.data);
}}
onError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
console.warn('WebView error: ', nativeEvent);
}}
onHttpError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
console.warn('WebView HTTP error: ', nativeEvent);
}}
/>
)}
</View>
</StripeTos>
</View>
);
};
export default StripeWebview;
问题: Stripe.js 脚本无法在 Android WebView 中专门加载。相反,我只看到“正在连接到 Stripe...”和旋转器,基本上是以下部分(即使等待一个小时后):
<div class="container" role="alert">
<h2>Let's setup your payment method</h2>
<p id="status-message">Connecting to Stripe...</p>
<div class="spinner" aria-hidden="true"></div>
</div>
相同的设置在使用 WebView 的 iOS 设备上运行得非常好。
我注意到这是 stripe.js 脚本加载部分卡住的地方,所以我测试了其他几个脚本,看看它是否可以加载它们。看起来它可以在 Android WebView 中很好地加载 jQuery 脚本,但 Lodash 似乎也无法加载。
我尝试过的: 用户代理测试:我尝试更改 userAgent 以模拟 iOS Safari 浏览器和其他现代浏览器,但问题仍然存在。
外部脚本测试: jQuery 在 Android WebView 中加载没有问题。 Lodash 和 Stripe.js 加载失败,说明可能与 WebView 中处理特定脚本的方式有关。
WebView配置:我已确保WebView设置正确配置,包括: javaScriptEnabled:true domStorageEnabled:true 混合内容模式:“始终”
Promises 和 TLS 1.2:Stripe.js 需要两者,并且设备都支持。
我尝试通过加载不同的 Stripe.js 页面来重现 React Native WebView 上的问题,它对我来说效果很好:https://4242.io/ payment-element
问题很可能出在您的 HTML 代码中。如果问题仍然存在,我建议您联系 Stripe 支持人员了解该问题以及他们可以用来重现问题的示例应用程序 - https://support.stripe.com/?contact=true