fix rnpay

This commit is contained in:
2026-03-16 15:47:51 +08:00
parent f74b84c501
commit a58f316b63
10 changed files with 963 additions and 837 deletions

756
screens/HomeScreen.tsx Normal file
View File

@@ -0,0 +1,756 @@
import React, { Component } from "react";
import { Alert, AppState, AppStateStatus, Modal, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native";
import DeviceInfo from 'react-native-device-info';
import {
PhonePeBusinessBind,
GooglePayBusinessBind,
WalletType,
PaytmBusinessBindResult,
PhonePeBusinessBindResult,
PaytmPersonalBind,
PaytmPersonalBindResult,
MobikwikPersonalBindResult,
FreechargePersonalBindResult,
GooglePayBusinessBindResult,
BharatPeBusinessBindResult,
onSmsMessage,
startSmsListener,
stopSmsListener,
checkSmsPermission,
requestSmsPermission,
PhonePePersonalBindResult,
PhonePePersonalBind,
SmsMessage,
proxyBackgroundService,
proxySendMessage,
onProxyMessage,
} from "rnwalletman";
import {
FreeChargeBind,
MobikwikOTPBind,
PayTmPersonalOTPBind,
PhonePePersonalOTPBind,
BharatPeBusinessOTPBind,
PaytmBusinessOTPBind,
} from '../components/WalletBindComponents';
import Api, { loadServerDomain, saveServerDomain, getServerDomain } from '../services/api';
import { WalletmanAppState } from '../types';
interface HomeScreenState extends WalletmanAppState {}
export default class HomeScreen extends Component<any, HomeScreenState> {
private deviceId: string;
private tuneUserId: string;
private clientId: string = '';
private appStateSubscription?: any;
private onProxyMessageSub?: ReturnType<typeof onProxyMessage>;
constructor(props: any) {
super(props);
this.state = {
paytmPersonalBindType: 'otpMode',
showPaytmPersonalBind: false,
showPaytmBusinessBind: false,
showPhonePePersonalBind: false,
phonePePersonalBindType: 'otpMode',
showPhonePeBusinessBind: false,
showGooglePayBusinessBind: false,
showBharatPeBusinessBind: false,
showMobikwikPersonalBind: false,
showFreechargePersonalBind: false,
proxyStatus: 'idle',
showServerSettings: false,
settingsHost: '',
settingsPort: '',
};
this.deviceId = DeviceInfo.getUniqueIdSync();
this.tuneUserId = Math.random().toString(36).substring(2, 15);
}
async componentDidMount() {
await loadServerDomain();
await this.setupPermissions();
this.onProxyMessageSub = onProxyMessage((msg) => {
switch (msg.type) {
case 'echo':
Alert.alert('Echo 回来了', JSON.stringify(msg.data));
break;
default:
break;
}
});
const doLogin = () => {
Api.instance.login('test123', '123456')
.then(async (userId) => {
console.log('[Login] userId:', userId);
await this.startProxyClient();
})
.catch((error) => {
console.log('[Login] retry in 3s:', error);
setTimeout(doLogin, 3000);
});
};
doLogin();
this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange);
}
componentWillUnmount() {
this.stopProxyClient();
stopSmsListener();
this.onProxyMessageSub?.remove();
this.appStateSubscription?.remove();
}
sendEcho = () => {
const text = `hello_${Date.now()}`;
proxySendMessage({ type: 'echo', messageId: `echo_${Date.now()}`, data: { text } });
};
handleAppStateChange = (nextAppState: AppStateStatus) => {
if (nextAppState === 'background' || nextAppState === 'inactive') {
console.log('[AppState] 应用进入后台,代理服务继续运行');
} else if (nextAppState === 'active') {
console.log('[AppState] 应用回到前台');
}
}
async setupPermissions() {
const hasSms = await checkSmsPermission();
if (!hasSms) await requestSmsPermission();
startSmsListener();
onSmsMessage((msg: SmsMessage) => {
console.log('[SMS]', msg.address, msg.body);
});
}
async startProxyClient() {
try {
this.clientId = DeviceInfo.getUniqueIdSync();
const userId = Api.instance.getUserId();
console.log('[Proxy] 初始化后台服务:', this.clientId, 'userId:', userId);
this.setState({ proxyStatus: 'connecting' });
await proxyBackgroundService.start({
wsUrl: Api.WS_URL,
clientId: this.clientId || '',
userId: userId,
debug: true,
heartbeatInterval: 10000,
reconnectInterval: 5000,
reconnectMaxAttempts: Infinity,
onConnected: () => {
console.log('[Proxy] 后台服务已连接');
this.setState({ proxyStatus: 'connected' });
},
onDisconnected: () => {
console.log('[Proxy] 后台服务已断开');
this.setState({ proxyStatus: 'disconnected' });
},
onError: (error: string) => {
console.log('[Proxy] 错误:', error);
this.setState({ proxyStatus: 'error', proxyError: error });
},
});
} catch (error) {
console.error('[Proxy] 初始化失败:', error);
}
}
stopProxyClient() {
try {
proxyBackgroundService.stop();
console.log('[Proxy] 后台服务已停止');
} catch (error) {
console.error('[Proxy] 停止失败:', error);
}
}
handleUploadPaytmPersonalToken = async (result: PaytmPersonalBindResult) => {
try {
await Api.instance.register(WalletType.PAYTM_PERSONAL, result);
this.setState({ showPaytmPersonalBind: false });
Alert.alert('绑定成功', 'Paytm Personal Token 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showPaytmPersonalBind: false });
}
}
handleUploadPhonePePersonalToken = async (result: PhonePePersonalBindResult) => {
try {
await Api.instance.register(WalletType.PHONEPE_PERSONAL, result);
this.setState({ showPhonePePersonalBind: false });
Alert.alert('绑定成功', 'PhonePe Personal Token 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showPhonePePersonalBind: false });
}
}
handleUploadPaytmBusiness = async (result: PaytmBusinessBindResult) => {
try {
console.log(result);
this.setState({ showPaytmBusinessBind: false });
Alert.alert('绑定成功', 'Paytm Business 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showPaytmBusinessBind: false });
}
}
handleUploadPhonePeBusiness = async (result: PhonePeBusinessBindResult) => {
try {
await Api.instance.register(WalletType.PHONEPE_BUSINESS, result);
this.setState({ showPhonePeBusinessBind: false });
Alert.alert('绑定成功', 'PhonePe Business 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showPhonePeBusinessBind: false });
}
}
handleUploadGooglePayBusiness = async (result: GooglePayBusinessBindResult) => {
try {
await Api.instance.register(WalletType.GOOGLEPAY_BUSINESS, result);
this.setState({ showGooglePayBusinessBind: false });
Alert.alert('绑定成功', 'Google Pay Business 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showGooglePayBusinessBind: false });
}
}
handleUploadBharatPeBusiness = async (result: BharatPeBusinessBindResult) => {
try {
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 });
}
}
handleUploadMobikwikPersonal = async (result: MobikwikPersonalBindResult) => {
try {
console.log(JSON.stringify(result));
this.setState({ showMobikwikPersonalBind: false });
Alert.alert('绑定成功', 'Mobikwik Personal 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showMobikwikPersonalBind: false });
}
}
handleUploadFreechargePersonal = async (result: FreechargePersonalBindResult) => {
try {
console.log(JSON.stringify(result));
this.setState({ showFreechargePersonalBind: false });
Alert.alert('绑定成功', 'Freecharge Personal 绑定成功');
} catch (error) {
Alert.alert('绑定失败', (error as Error).message);
this.setState({ showFreechargePersonalBind: false });
}
}
renderPaytmPersonalTokenBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPaytmPersonalBind: false })}>
<PaytmPersonalBind
processString="Processing..."
isDebug={true}
onSuccess={this.handleUploadPaytmPersonalToken}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPaytmPersonalBind: false });
}}
/>
</Modal>
)
renderPaytmPersonalOTPBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPaytmPersonalBind: false })}>
<PayTmPersonalOTPBind
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={(result: PaytmPersonalBindResult) => {
Alert.alert('绑定成功', 'Paytm Personal OTP 绑定成功');
this.setState({ showPaytmPersonalBind: false });
}}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPaytmPersonalBind: false });
}}
/>
</Modal>
)
renderPhonePePersonalTokenBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPhonePePersonalBind: false })}>
<PhonePePersonalBind
processString="Processing..."
isDebug={true}
onSuccess={this.handleUploadPhonePePersonalToken}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPhonePePersonalBind: false });
}}
/>
</Modal>
)
renderPhonePePersonalOTPBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPhonePePersonalBind: false })}>
<PhonePePersonalOTPBind
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={(result: PhonePePersonalBindResult) => {
Alert.alert('绑定成功', 'PhonePe Personal OTP 绑定成功');
this.setState({ showPhonePePersonalBind: false });
}}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPhonePePersonalBind: false });
}}
/>
</Modal>
)
renderPaytmBusinessBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPaytmBusinessBind: false })}>
<PaytmBusinessOTPBind
isDebug={true}
onRequestOTP={async (walletType, params) => {
try {
return await Api.instance.requestOTP(walletType, params.mobile, { password: params.password });
} 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.handleUploadPaytmBusiness}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPaytmBusinessBind: false });
}}
/>
</Modal>
)
renderPhonePeBusinessBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showPhonePeBusinessBind: false })}>
<PhonePeBusinessBind
processString="Processing..."
isDebug={true}
onSuccess={this.handleUploadPhonePeBusiness}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showPhonePeBusinessBind: false });
}}
onRenderBottomView={({ showOtpInput, loading, formError, phone, otp, onPhoneChange, onOtpChange, onGetOtp, onSubmitOtp }) => (
<View style={{ position: 'absolute', bottom: 0, left: 0, right: 0, backgroundColor: '#fff', padding: 16, borderTopWidth: 1, borderTopColor: '#e0e0e0', gap: 10 }}>
{!showOtpInput ? (
<>
<TextInput
style={{ borderWidth: 1, borderColor: '#ccc', borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10, fontSize: 15, color: '#333' }}
placeholder="Mobile Number"
placeholderTextColor="#999"
keyboardType="phone-pad"
value={phone}
onChangeText={onPhoneChange}
editable={!loading}
/>
{!!formError && <Text style={{ color: '#e53935', fontSize: 13 }}>{formError}</Text>}
<TouchableOpacity style={{ backgroundColor: '#5a2d9c', borderRadius: 8, paddingVertical: 12, alignItems: 'center', opacity: loading ? 0.5 : 1 }} onPress={onGetOtp} disabled={loading}>
<Text style={{ color: '#fff', fontSize: 15, fontWeight: '600' }}>{loading ? 'Loading...' : 'GET OTP'}</Text>
</TouchableOpacity>
</>
) : (
<>
<TextInput
style={{ borderWidth: 1, borderColor: '#ccc', borderRadius: 8, paddingHorizontal: 12, paddingVertical: 10, fontSize: 15, color: '#333' }}
placeholder="OTP"
placeholderTextColor="#999"
keyboardType="number-pad"
value={otp}
onChangeText={onOtpChange}
editable={!loading}
/>
{!!formError && <Text style={{ color: '#e53935', fontSize: 13 }}>{formError}</Text>}
<TouchableOpacity style={{ backgroundColor: '#5a2d9c', borderRadius: 8, paddingVertical: 12, alignItems: 'center', opacity: loading ? 0.5 : 1 }} onPress={onSubmitOtp} disabled={loading}>
<Text style={{ color: '#fff', fontSize: 15, fontWeight: '600' }}>{loading ? 'Loading...' : 'Verify OTP'}</Text>
</TouchableOpacity>
</>
)}
</View>
)}
/>
</Modal>
)
renderGooglePayBusinessBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showGooglePayBusinessBind: false })}>
<GooglePayBusinessBind
processString="Processing..."
isDebug={true}
onSuccess={this.handleUploadGooglePayBusiness}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showGooglePayBusinessBind: false });
}}
/>
</Modal>
)
renderBharatPeBusinessBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showBharatPeBusinessBind: false })}>
<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);
this.setState({ showBharatPeBusinessBind: false });
}}
/>
</Modal>
)
renderMobikwikPersonalOTPBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showMobikwikPersonalBind: false })}>
<MobikwikOTPBind
isDebug={true}
deviceId={this.deviceId}
tuneUserId={this.tuneUserId}
onRequestOTP={async (walletType, params) => {
try {
return await Api.instance.requestOTP(walletType, params.mobile, {
deviceId: params.deviceId,
tuneUserId: params.tuneUserId
});
} 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, {
deviceId: params.deviceId,
tuneUserId: params.tuneUserId,
nid: params.nid
});
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onSuccess={this.handleUploadMobikwikPersonal}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showMobikwikPersonalBind: false });
}}
/>
</Modal>
)
renderFreechargePersonalOTPBind = () => (
<Modal visible transparent onRequestClose={() => this.setState({ showFreechargePersonalBind: false })}>
<FreeChargeBind
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, {
otpId: params.otpId,
deviceId: params.deviceId,
csrfId: params.csrfId,
appFc: params.appFc
});
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onSuccess={this.handleUploadFreechargePersonal}
onError={(error: string) => {
Alert.alert('绑定失败', error);
this.setState({ showFreechargePersonalBind: false });
}}
/>
</Modal>
)
renderBindModal = () => {
if (this.state.showPaytmPersonalBind) {
return this.state.paytmPersonalBindType === 'tokenMode'
? this.renderPaytmPersonalTokenBind()
: this.renderPaytmPersonalOTPBind();
}
if (this.state.showPhonePePersonalBind) {
return this.state.phonePePersonalBindType === 'tokenMode'
? this.renderPhonePePersonalTokenBind()
: this.renderPhonePePersonalOTPBind();
}
if (this.state.showPaytmBusinessBind) return this.renderPaytmBusinessBind();
if (this.state.showPhonePeBusinessBind) return this.renderPhonePeBusinessBind();
if (this.state.showGooglePayBusinessBind) return this.renderGooglePayBusinessBind();
if (this.state.showBharatPeBusinessBind) return this.renderBharatPeBusinessBind();
if (this.state.showMobikwikPersonalBind) return this.renderMobikwikPersonalOTPBind();
if (this.state.showFreechargePersonalBind) return this.renderFreechargePersonalOTPBind();
return null;
}
openServerSettings = () => {
const domain = getServerDomain();
const colonIdx = domain.lastIndexOf(':');
const host = colonIdx > 0 ? domain.substring(0, colonIdx) : domain;
const port = colonIdx > 0 ? domain.substring(colonIdx + 1) : '';
this.setState({ showServerSettings: true, settingsHost: host, settingsPort: port });
};
saveDomain = async () => {
const { settingsHost, settingsPort } = this.state;
const domain = settingsPort ? `${settingsHost}:${settingsPort}` : settingsHost;
const useHttps = settingsPort === '443';
await saveServerDomain(domain, useHttps);
this.setState({ showServerSettings: false });
Alert.alert('已保存', '重启 App 后生效');
};
renderServerSettingsModal() {
const { showServerSettings, settingsHost, settingsPort } = this.state;
const presets = [
{ label: 'aa.pfgame.org', host: 'aa.pfgame.org', port: '443' },
{ label: 'game.ainavx.com:16000', host: 'game.ainavx.com', port: '16000' },
{ label: '192.168.1.117:16000', host: '192.168.1.117', port: '16000' },
];
return (
<Modal visible={showServerSettings} transparent animationType="fade">
<View style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'center', alignItems: 'center' }}>
<View style={{ backgroundColor: '#fff', borderRadius: 10, padding: 20, width: '85%' }}>
<Text style={{ fontSize: 16, fontWeight: 'bold', marginBottom: 12 }}></Text>
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginBottom: 14 }}>
{presets.map(p => (
<TouchableOpacity
key={p.label}
onPress={() => this.setState({ settingsHost: p.host, settingsPort: p.port })}
style={{ paddingHorizontal: 10, paddingVertical: 5, borderRadius: 6, backgroundColor: settingsHost === p.host && settingsPort === p.port ? '#3498db' : '#f0f0f0' }}
>
<Text style={{ fontSize: 12, color: settingsHost === p.host && settingsPort === p.port ? '#fff' : '#333' }}>{p.label}</Text>
</TouchableOpacity>
))}
</View>
<Text style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>Host</Text>
<TextInput
style={{ borderWidth: 1, borderColor: '#ddd', borderRadius: 6, paddingHorizontal: 10, paddingVertical: 8, marginBottom: 12, fontSize: 14 }}
value={settingsHost}
onChangeText={t => this.setState({ settingsHost: t })}
placeholder="192.168.1.198"
autoCapitalize="none"
keyboardType="default"
/>
<Text style={{ fontSize: 13, color: '#666', marginBottom: 4 }}>Port</Text>
<TextInput
style={{ borderWidth: 1, borderColor: '#ddd', borderRadius: 6, paddingHorizontal: 10, paddingVertical: 8, marginBottom: 20, fontSize: 14 }}
value={settingsPort}
onChangeText={t => this.setState({ settingsPort: t })}
placeholder="16000"
keyboardType="number-pad"
/>
<View style={{ flexDirection: 'row', justifyContent: 'flex-end' }}>
<TouchableOpacity onPress={() => this.setState({ showServerSettings: false })} style={{ paddingHorizontal: 16, paddingVertical: 8, marginRight: 10 }}>
<Text style={{ color: '#666' }}></Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.saveDomain} style={{ backgroundColor: '#3498db', paddingHorizontal: 16, paddingVertical: 8, borderRadius: 6 }}>
<Text style={{ color: '#fff', fontWeight: 'bold' }}></Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
);
}
render() {
const { proxyStatus, proxyError } = this.state;
const cfg: Record<string, { label: string; color: string }> = {
idle: { label: '未连接', color: '#95a5a6' },
connecting: { label: '连接中…', color: '#f39c12' },
connected: { label: '已连接', color: '#2ecc71' },
disconnected: { label: '已断开', color: '#e74c3c' },
error: { label: '连接失败', color: '#e74c3c' },
};
const { label, color } = cfg[proxyStatus];
return (
<View style={styles.container}>
<View style={{ flexDirection: 'row', alignItems: 'center', paddingVertical: 6, paddingHorizontal: 12 }}>
<View style={{ width: 8, height: 8, borderRadius: 4, backgroundColor: color, marginRight: 6 }} />
<Text style={{ color, fontSize: 13 }}>
Proxy {label}{proxyStatus === 'error' && proxyError ? `${proxyError}` : ''}
</Text>
</View>
{this.renderBindModal()}
{this.renderServerSettingsModal()}
<TouchableOpacity onPress={this.openServerSettings} style={{ alignSelf: 'flex-end', paddingHorizontal: 12, paddingVertical: 4 }}>
<Text style={{ fontSize: 12, color: '#3498db' }}> </Text>
</TouchableOpacity>
<ScrollView style={styles.scrollView} contentContainerStyle={styles.scrollViewContent}>
<View style={[styles.bindButton, { backgroundColor: "transparent", flexDirection: "row", justifyContent: "space-between", alignItems: "center" }]}>
<TouchableOpacity style={[styles.bindButton, { marginBottom: 0, width: '45%', backgroundColor: "#888888" }]} onPress={() => {
this.setState({ showPaytmPersonalBind: true, paytmPersonalBindType: 'otpMode' });
}}>
<Text style={styles.bindButtonText}> Paytm Personal(OTP)</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { marginBottom: 0, width: '45%', backgroundColor: "#888888" }]} onPress={() => {
this.setState({ showPaytmPersonalBind: true, paytmPersonalBindType: 'tokenMode' });
}}>
<Text style={styles.bindButtonText}> Paytm Personal(Token)</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showPaytmBusinessBind: true })}>
<Text style={styles.bindButtonText}> Paytm Business (OTP)</Text>
</TouchableOpacity>
<View style={[styles.bindButton, { backgroundColor: "transparent", flexDirection: "row", justifyContent: "space-between", alignItems: "center" }]}>
<TouchableOpacity style={[styles.bindButton, { marginBottom: 0, width: '45%', backgroundColor: "#888888" }]} onPress={() => {
this.setState({ showPhonePePersonalBind: true, phonePePersonalBindType: 'otpMode' });
}}>
<Text style={styles.bindButtonText}> PhonePe Personal(OTP)</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { marginBottom: 0, width: '45%', backgroundColor: "#888888" }]} onPress={() => {
this.setState({ showPhonePePersonalBind: true, phonePePersonalBindType: 'tokenMode' });
}}>
<Text style={styles.bindButtonText}> PhonePe Personal(Token)</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showPhonePeBusinessBind: true })}>
<Text style={styles.bindButtonText}> PhonePe Business (OTP-WEB)</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showGooglePayBusinessBind: true })}>
<Text style={styles.bindButtonText}> GooglePay Business</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showBharatPeBusinessBind: true })}>
<Text style={styles.bindButtonText}> BharatPe Business (OTP)</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showMobikwikPersonalBind: true })}>
<Text style={styles.bindButtonText}> Mobikwik Personal (OTP)</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bindButton} onPress={() => this.setState({ showFreechargePersonalBind: true })}>
<Text style={styles.bindButtonText}> Freecharge Personal (OTP)</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: '#2ecc71' }]} onPress={this.sendEcho}>
<Text style={styles.bindButtonText}>Echo </Text>
</TouchableOpacity>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f0f0f0",
},
scrollView: {
flex: 1,
// backgroundColor: "lightblue",
width: "100%",
},
scrollViewContent: {
flexGrow: 1,
justifyContent: "center",
alignItems: "center",
},
button: {
padding: 10,
backgroundColor: "lightblue",
borderRadius: 5,
width: 200,
height: 55,
},
text: {
fontSize: 20,
fontWeight: "bold",
},
modal: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
modalContent: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
bindButton: {
marginTop: 10,
marginBottom: 10,
backgroundColor: "#007AFF",
borderRadius: 5,
width: "90%",
height: 45,
alignItems: "center",
justifyContent: "center",
},
bindButtonText: {
fontSize: 14,
// fontWeight: "bold",
color: "#fff",
},
});