bharatpe business 改为 otp 模式 ,去除 web 的抓取
This commit is contained in:
142
App.tsx
142
App.tsx
@@ -1,11 +1,10 @@
|
||||
import React, { Component } from "react";
|
||||
import { Alert, AppState, AppStateStatus, Modal, Text, TouchableOpacity, View } from "react-native";
|
||||
import { Alert, AppState, AppStateStatus, Modal, Text, TextInput, TouchableOpacity, View } from "react-native";
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {
|
||||
PaytmBusinessBind,
|
||||
PhonePeBusinessBind,
|
||||
GooglePayBusinessBind,
|
||||
BharatPeBusinessBind,
|
||||
WalletType,
|
||||
PaytmBusinessBindResult,
|
||||
PhonePeBusinessBindResult,
|
||||
@@ -32,19 +31,23 @@ import {
|
||||
FreeChargeBind,
|
||||
MobikwikOTPBind,
|
||||
PayTmPersonalOTPBind,
|
||||
PhonePePersonalOTPBind
|
||||
PhonePePersonalOTPBind,
|
||||
BharatPeBusinessOTPBind,
|
||||
} from './components/WalletBindComponents';
|
||||
|
||||
import Api from './services/api';
|
||||
import { AppProps, WalletmanAppState } from './types';
|
||||
import { styles } from './styles';
|
||||
import WebView from "react-native-webview";
|
||||
|
||||
export default class App extends Component<AppProps, WalletmanAppState> {
|
||||
private deviceId: string;
|
||||
private tuneUserId: string;
|
||||
private clientId: string = '';
|
||||
private appStateSubscription?: any;
|
||||
|
||||
|
||||
private webViewRef: WebView | null = null;
|
||||
|
||||
constructor(props: AppProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -234,11 +237,9 @@ export default class App extends Component<AppProps, WalletmanAppState> {
|
||||
// BharatPe Business
|
||||
handleUploadBharatPeBusiness = async (result: BharatPeBusinessBindResult) => {
|
||||
try {
|
||||
console.log(result);
|
||||
const response = await Api.instance.register(WalletType.BHARATPE_BUSINESS, result);
|
||||
console.log(response);
|
||||
console.log(JSON.stringify(result));
|
||||
this.setState({ showBharatPeBusinessBind: false });
|
||||
|
||||
Alert.alert('绑定成功', 'BharatPe Business 绑定成功');
|
||||
} catch (error) {
|
||||
Alert.alert('绑定失败', (error as Error).message);
|
||||
this.setState({ showBharatPeBusinessBind: false });
|
||||
@@ -423,9 +424,24 @@ export default class App extends Component<AppProps, WalletmanAppState> {
|
||||
renderBharatPeBusinessBind = () => {
|
||||
return (
|
||||
<Modal visible transparent onRequestClose={() => this.setState({ showBharatPeBusinessBind: false })}>
|
||||
<BharatPeBusinessBind
|
||||
processString="Processing..."
|
||||
<BharatPeBusinessOTPBind
|
||||
isDebug={true}
|
||||
onRequestOTP={async (walletType, params) => {
|
||||
try {
|
||||
return await Api.instance.requestOTP(walletType, params.mobile);
|
||||
} catch (error) {
|
||||
return { success: false, message: (error as Error).message };
|
||||
}
|
||||
}}
|
||||
onVerifyOTP={async (walletType, params) => {
|
||||
try {
|
||||
return await Api.instance.verifyOTP(walletType, params.mobile, params.otp, {
|
||||
sessionId: params.sessionId,
|
||||
});
|
||||
} catch (error) {
|
||||
return { success: false, message: (error as Error).message };
|
||||
}
|
||||
}}
|
||||
onSuccess={this.handleUploadBharatPeBusiness}
|
||||
onError={(error: string) => {
|
||||
Alert.alert('绑定失败', error);
|
||||
@@ -560,7 +576,113 @@ export default class App extends Component<AppProps, WalletmanAppState> {
|
||||
return null;
|
||||
}
|
||||
|
||||
renderWebDemo() {
|
||||
const handleMessage = (event: any) => {
|
||||
try {
|
||||
const data = JSON.parse(event.nativeEvent.data);
|
||||
if (data.type === 'iframe_message') {
|
||||
console.log('[Demo] iframe message:', data.data);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[Demo] Parse error:', e);
|
||||
}
|
||||
};
|
||||
|
||||
const syncToIframe = (fieldId: string, value: string) => {
|
||||
const js = `
|
||||
window.postMessage({
|
||||
type: 'set_field',
|
||||
fieldId: '${fieldId}',
|
||||
value: '${value.replace(/'/g, "\\'")}'
|
||||
}, '*');
|
||||
`;
|
||||
this.webViewRef?.injectJavaScript(js);
|
||||
};
|
||||
|
||||
const clickLogin = () => {
|
||||
const js = `window.postMessage({type: 'click_login'}, '*');`;
|
||||
this.webViewRef?.injectJavaScript(js);
|
||||
};
|
||||
|
||||
const injectedJS = `
|
||||
window.addEventListener('message', function(event) {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({
|
||||
type: 'iframe_message',
|
||||
data: event.data
|
||||
}));
|
||||
});
|
||||
true;
|
||||
`;
|
||||
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<WebView
|
||||
ref={(ref) => { this.webViewRef = ref; }}
|
||||
source={{ uri: 'https://dashboard.paytm.com' }}
|
||||
javaScriptEnabled={true}
|
||||
domStorageEnabled={true}
|
||||
thirdPartyCookiesEnabled={true}
|
||||
sharedCookiesEnabled={true}
|
||||
onMessage={handleMessage}
|
||||
injectedJavaScript={injectedJS}
|
||||
interceptUrlPattern="accounts.paytm.com/oauth-js-sdk/"
|
||||
interceptInjectedScript={`
|
||||
if (!window.__paytmMessageHandler) {
|
||||
window.__paytmMessageHandler = function(event) {
|
||||
if (event.data.type === 'set_field') {
|
||||
const el = document.getElementById(event.data.fieldId);
|
||||
if (el) {
|
||||
el.click();
|
||||
el.focus();
|
||||
el.value = event.data.value;
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
el.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
el.dispatchEvent(new Event('blur', { bubbles: true }));
|
||||
}
|
||||
}
|
||||
if (event.data.type === 'click_login') {
|
||||
const btn = document.getElementById('login_button');
|
||||
if (btn) btn.click();
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', window.__paytmMessageHandler);
|
||||
window.parent.postMessage({type: 'iframe_ready'}, '*');
|
||||
}
|
||||
`}
|
||||
/>
|
||||
|
||||
<View style={{padding: 20, backgroundColor: '#f5f5f5', borderTopWidth: 1, borderTopColor: '#ddd'}}>
|
||||
<Text style={{fontSize: 16, fontWeight: 'bold', marginBottom: 10}}>Test Controls</Text>
|
||||
|
||||
<Text style={{marginTop: 5}}>Mobile:</Text>
|
||||
<TextInput
|
||||
style={{borderWidth: 1, borderColor: '#ccc', padding: 10, borderRadius: 5, backgroundColor: '#fff', marginTop: 5}}
|
||||
onChangeText={(text) => syncToIframe('email_mobile_login', text)}
|
||||
placeholder="Enter mobile number"
|
||||
keyboardType="phone-pad"
|
||||
/>
|
||||
|
||||
<Text style={{marginTop: 10}}>Password:</Text>
|
||||
<TextInput
|
||||
style={{borderWidth: 1, borderColor: '#ccc', padding: 10, borderRadius: 5, backgroundColor: '#fff', marginTop: 5}}
|
||||
onChangeText={(text) => syncToIframe('password_login', text)}
|
||||
placeholder="Enter password"
|
||||
secureTextEntry
|
||||
/>
|
||||
|
||||
<TouchableOpacity
|
||||
style={{marginTop: 15, backgroundColor: '#00BAF2', padding: 15, borderRadius: 5, alignItems: 'center'}}
|
||||
onPress={clickLogin}
|
||||
>
|
||||
<Text style={{color: '#fff', fontSize: 16, fontWeight: 'bold'}}>Login</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
// return this.renderWebDemo();
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{(() => {
|
||||
|
||||
Reference in New Issue
Block a user