我正在开发一个本机应用程序,该应用程序应与网关进行付款,完成付款过程(成功或失败)后,我需要向用户显示警报。为此,我在 WebView
中打开一个链接,然后用 onNavigationStateChange
获取返回的URL,并显示成功或失败消息。>
但是,必须在默认设备浏览器中完成有关安全问题的流程。
当前代码:
const BASEURL = 'https://gatewayURL/?ID=';
let Token = null;
let paymentAccepted = null;
let paymentFactorId = null;
class Gateway extends PureComponent {
static propTypes = {
dispatch: PropTypes.func,
navigation: PropTypes.any,
}
componentWillMount() {
this.props.dispatch(getPaymentStatus());
}
_onLoad(webViewState) {
let url = webViewState.url.toString();
let isResponseValid = url.includes('backFromGateway');
if(isResponseValid){
if(this.props.checkedPaymentStatus != 'checked' ){
setTimeout(() => {
this.props.dispatch(setPaymentStatus('checked'));
let splitedURL = url.split("/");
paymentFactorId = splitedURL[splitedURL.length -2];
if(splitedURL[splitedURL.length - 1] === '0'){
paymentAccepted = true;
this.props.dispatch(setGatewayResponse('done', paymentFactorId));
}
else {
paymentAccepted = false;
this.props.dispatch(setGatewayResponse('rejected', paymentFactorId));
}
this.props.navigation.navigate('BackFromGateway', { title: '' })
}, 1000);
}
}
}
render() {
const { addNewOrderGatewayToken, checkedPaymentStatus } = this.props;
token = addNewOrderGatewayToken;
let view = null;
if(checkedPaymentStatus !== 'checked'){
view = <WebView onNavigationStateChange={this._onLoad.bind(this)} style={styles.container} source={{ uri: `${BASEURL}${token}` }}/>
}
else{
view = <View></View>
}
return (
<View style={styles.container}>
{view}
</View>
);
}
}
有什么主意吗?
谢谢
答案 0 :(得分:8)
如果您可以从网关网站进行回调,那么我建议使用深层链接处理应用程序和浏览器之间的流程。基本上,您的应用程序将打开网关网站进行付款,并且根据付款结果,该网站将使用其深层链接对应用程序进行回调。然后,App将收听链接,取出必要的信息,然后继续进行操作。
您需要做的是:
在您的应用中设置深层链接。您应该按照官方网站(here)上的指南启用它。让我们在此处选择一个随机网址进行链接,例如gatewaylistener
设置从网关到应用程序的必要回调。在您的情况下,由于您需要处理成功付款和失败付款,因此您可以添加2个回调,例如gatewaylistener://success?id={paymentId}
和gatewaylistener://error?id={paymentId}
最后,您需要从该应用程序收听Web浏览器。一种方法是在打开网关的组件内部添加侦听器。
// setup
componentDidMount() {
Linking.getInitialURL().then((url) => {
if (url) {
this.handleOpenURL(url)
}
}).catch(err => {})
Linking.addEventListener('url', this.handleOpenURL)
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL)
}
// open your gateway
async openGateWay = () => {
const { addNewOrderGatewayToken } = this.props
const url = `${BASEURL}${addNewOrderGatewayToken}`
const canOpen = await Linking.canOpenURL(url)
if (canOpen) {
this.props.dispatch(setPaymentStatus('checked'))
Linking.openURL(url)
}
}
// handle gateway callbacks
handleOpenURL = (url) => {
if (isSucceedPayment(url)) { // your condition
// handle success payment
} else {
// handle failure
}
}
答案 1 :(得分:0)
出于身份验证的目的,例如,使用深度链接重定向,您可以将嵌入式浏览器与Android的 Chrome自定义标签和iOS的 SafariViewController 配合使用,选中{{ 3}}组件,以相同的代码支持两个平台(链接已在内部用于检测深度链接重定向)。
从示例文件夹中可以看到,可以使用从应用(适用于Android的AndroidManifest和适用于iOS的Info.plist)配置的自定义深层链接:
getDeepLink (path = '') {
const scheme = 'my-demo'
const prefix = Platform.OS === 'android' ? `${scheme}://demo/` : `${scheme}://`
return prefix + path
}
async tryDeepLinking () {
const redirectToURL = `https://proyecto26.github.io/react-native-inappbrowser/`
const redirectUrl = this.getDeepLink('home')
const url = `${redirectToURL}?redirect_url=${encodeURIComponent(redirectUrl)}`
try {
if (await InAppBrowser.isAvailable()) {
const result = await InAppBrowser.openAuth(url, redirectUrl)
await this.sleep(800)
Alert.alert('Response', JSON.stringify(result))
} else {
// You can use Linking directly for iOS < 9
}
} catch (error) {
Alert.alert('Something’s wrong with the app :(')
}
}