Files
rnpay/App.tsx
2026-01-30 10:40:25 +08:00

857 lines
33 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { Component } from "react";
import { Alert, Modal, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import {
PaytmBusinessBind,
PhonePeBusinessBind,
GooglePayBusinessBind,
BharatPeBusinessBind,
WalletType,
PaytmBusinessBindResult,
PhonePeBusinessBindResult,
PaytmPersonalBind,
PaytmPersonalBindResult,
MobikwikPersonalBind,
MobikwikPersonalBindResult,
FreechargePersonalBind,
FreechargePersonalBindResult,
GooglePayBusinessBindResult,
BharatPeBusinessBindResult,
paytmPay,
onSmsMessage,
onNotificationMessage,
getAllSms,
getAllNotifications,
startSmsListener,
startNotificationListener,
stopSmsListener,
stopNotificationListener,
checkSmsPermission,
checkNotificationPermission,
openNotificationSettings,
requestSmsPermission,
PhonePePersonalBindResult,
PhonePePersonalBind,
SmsMessage,
NotificationMessage,
TcpProxy,
} from "rnwalletman";
import BarcodeScanning from '@react-native-ml-kit/barcode-scanning';
import RNFS from 'react-native-fs';
interface AppProps {
}
interface AppState {
showPaytmBusinessBind: boolean;
showPaytmPersonalBind: boolean;
showPhonePePersonalBind: boolean;
showPhonePeBusinessBind: boolean;
showGooglePayBusinessBind: boolean;
showBharatPeBusinessBind: boolean;
showMobikwikPersonalBind: boolean;
showFreechargePersonalBind: boolean;
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
button: {
padding: 10,
backgroundColor: "lightblue",
borderRadius: 5,
width: 200,
height: 50,
},
text: {
fontSize: 20,
fontWeight: "bold",
},
modal: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
modalContent: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
bindButton: {
padding: 10,
borderRadius: 5,
width: 250,
height: 40,
justifyContent: "center",
alignItems: "center",
margin: 10,
},
bindButtonText: {
fontSize: 15,
fontWeight: "bold",
},
});
class Api {
public static readonly BASE_URL = 'http://192.168.1.155:16000';
private static _instance: Api | null = null;
private ws: WebSocket | null = null;
private messageCallbacks = new Map<string, (data: any) => void>();
private constructor() {
}
public static get instance() {
if (Api._instance === null) {
Api._instance = new Api();
}
return Api._instance;
}
public setWebSocket(ws: WebSocket, serverUrl: string) {
this.ws = ws;
// 处理消息
ws.onmessage = (event) => {
try {
const msg = JSON.parse(event.data);
// 处理响应消息
if (msg.type === 'response' && msg.messageId) {
const callback = this.messageCallbacks.get(msg.messageId);
if (callback) {
callback(msg.data);
this.messageCallbacks.delete(msg.messageId);
}
}
// 处理代理请求
if (msg.type === 'proxyRequest') {
console.log('[代理] 收到代理请求:', msg.data);
const { host, port } = msg.data;
// 创建TCP连接
TcpProxy.createProxy(
msg.messageId,
host,
port,
// onData: TCP收到数据 → 发送到服务器
(data: string) => {
ws.send(JSON.stringify({
type: 'proxyData',
messageId: msg.messageId,
data: { data }
}));
},
// onClose: TCP关闭 → 通知服务器
() => {
ws.send(JSON.stringify({
type: 'proxyClose',
messageId: msg.messageId
}));
},
// onError: TCP错误 → 通知服务器
(error: string) => {
ws.send(JSON.stringify({
type: 'proxyClose',
messageId: msg.messageId
}));
}
).then(success => {
if (success) {
ws.send(JSON.stringify({
type: 'proxyReady',
messageId: msg.messageId
}));
}
}).catch(err => {
ws.send(JSON.stringify({
type: 'proxyClose',
messageId: msg.messageId
}));
});
}
// 处理代理数据(服务器 → TCP
if (msg.type === 'proxyData' && msg.data?.data) {
if (TcpProxy && typeof TcpProxy.writeProxy === 'function') {
TcpProxy.writeProxy(msg.messageId, msg.data.data).then(success => {
if (!success) {
ws.send(JSON.stringify({
type: 'proxyClose',
messageId: msg.messageId
}));
}
}).catch(err => {
ws.send(JSON.stringify({
type: 'proxyClose',
messageId: msg.messageId
}));
});
}
}
// 处理代理关闭
if (msg.type === 'proxyClose') {
TcpProxy.closeProxy(msg.messageId)
.catch(err => console.error('[代理] 关闭失败:', err));
}
} catch (error) {
console.error('[API] 解析消息失败:', error, event.data);
}
};
}
private sendMessage(type: string, data: any): Promise<any> {
return new Promise((resolve, reject) => {
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
reject(new Error('WebSocket未连接'));
return;
}
const messageId = `msg_${Date.now()}_${Math.random()}`;
// 设置回调
this.messageCallbacks.set(messageId, (responseData) => {
if (responseData.success) {
resolve(responseData);
} else {
reject(new Error(responseData.message));
}
});
// 发送消息
this.ws.send(JSON.stringify({
type,
messageId,
data
}));
// 超时处理
setTimeout(() => {
if (this.messageCallbacks.has(messageId)) {
this.messageCallbacks.delete(messageId);
reject(new Error('请求超时'));
}
}, 30000);
});
}
public async register(walletType: WalletType, params: any) {
return this.sendMessage('registerWallet', {
walletType,
params
});
}
public async requestOTP(walletType: WalletType, mobile: string, params: any = {}) {
return this.sendMessage('requestOTP', {
walletType,
mobile,
...params
});
}
public async verifyOTP(walletType: WalletType, mobile: string, otp: string, params: any = {}) {
return this.sendMessage('verifyOTP', {
walletType,
mobile,
otp,
...params
});
}
}
export default class App extends Component<AppProps, AppState> {
private deviceId: string;
private tuneUserId: string;
private clientId: string;
constructor(props: AppProps) {
super(props);
this.state = {
showPaytmBusinessBind: false,
showPaytmPersonalBind: false,
showPhonePeBusinessBind: false,
showPhonePePersonalBind: false,
showGooglePayBusinessBind: false,
showBharatPeBusinessBind: false,
showMobikwikPersonalBind: false,
showFreechargePersonalBind: false,
};
// 临时使用测试成功的固定 ID
this.deviceId = 'B6C1AB6DA4B659C287EA76AA96EC154B80E8D28D';
this.tuneUserId = 'b5bfa7df-e571-4ac8-bb51-90afc05d1d59';
this.clientId = `android_${Date.now()}`;
}
async componentDidMount() {
/* 初始化代理客户端 */
await this.initProxyClient();
/* 权限申请 */
let smsPermission = await checkSmsPermission();
let notificationPermission = await checkNotificationPermission();
if (!smsPermission) {
const granted = await requestSmsPermission();
smsPermission = await checkSmsPermission();
console.log('smsPermission:', smsPermission);
if (!smsPermission) {
Alert.alert('需要短信权限', '请在系统设置中授予短信权限');
}
}
if (!notificationPermission) {
Alert.alert(
'需要通知监听权限',
'点击确定后将打开设置页面,请找到本应用并授予通知访问权限',
[
{
text: '确定',
onPress: () => openNotificationSettings()
},
{ text: '取消' }
]
);
return;
}
// 启动监听
startSmsListener();
startNotificationListener();
onSmsMessage((message: SmsMessage) => {
console.log('[SMS]', message);
});
onNotificationMessage((notification: NotificationMessage) => {
console.log('[Notification]', notification);
});
if (smsPermission) {
getAllSms().then((sms: SmsMessage[]) => {
console.log('[所有短信]', sms.length, '条');
}).catch(err => console.error('[获取短信失败]', err));
}
if (notificationPermission) {
getAllNotifications().then((notifications: NotificationMessage[]) => {
console.log('[所有通知]', notifications.length, '条');
}).catch(err => console.error('[获取通知失败]', err));
}
}
private wsHeartbeatTimer?: NodeJS.Timeout;
/**
* 初始化代理客户端
*/
async initProxyClient() {
try {
const serverUrl = `ws://${Api.BASE_URL.replace('http://', '')}/ws`;
console.log(`[WebSocket] 连接服务器: ${serverUrl}, 客户端ID: ${this.clientId}`);
// 创建WebSocket连接
const ws = new WebSocket(serverUrl);
ws.onopen = () => {
console.log('[WebSocket] ✅ 已连接');
// 注册客户端
ws.send(JSON.stringify({
type: 'register',
clientId: this.clientId,
messageId: 'register_' + Date.now()
}));
// 设置给API使用传入serverUrl用于代理
Api.instance.setWebSocket(ws, serverUrl);
// 启动心跳
this.startHeartbeat(ws);
};
ws.onerror = (error) => {
console.error('[WebSocket] 错误:', error);
};
ws.onclose = () => {
console.log('[WebSocket] 连接关闭');
this.stopHeartbeat();
// 3秒后重连
setTimeout(() => this.initProxyClient(), 3000);
};
} catch (error) {
console.error('[WebSocket] 连接失败:', error);
}
}
/**
* 启动心跳
*/
startHeartbeat(ws: WebSocket) {
this.stopHeartbeat();
this.wsHeartbeatTimer = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
type: 'ping',
messageId: 'ping_' + Date.now(),
clientId: this.clientId
}));
}
}, 20000); // 每20秒发送一次心跳
}
/**
* 停止心跳
*/
stopHeartbeat() {
if (this.wsHeartbeatTimer) {
clearInterval(this.wsHeartbeatTimer);
this.wsHeartbeatTimer = undefined;
}
}
componentWillUnmount(): void {
// 停止心跳
this.stopHeartbeat();
stopSmsListener();
stopNotificationListener();
}
decodeQRFromUrl = async (url: string) => {
const localPath = `${RNFS.CachesDirectoryPath}/temp_qr_${Date.now()}.jpg`;
try {
// 1. 下载图片
await RNFS.downloadFile({ fromUrl: url, toFile: localPath }).promise;
// 2. 识别二维码
const barcodes = await BarcodeScanning.scan(`file://${localPath}`);
if (barcodes.length > 0) {
return barcodes[0].value;
}
} catch (e) {
console.error(e);
return null;
}
};
/* 绑定 Paytm Personal */
handlePaytmPersonalBind = () => {
this.setState({ showPaytmPersonalBind: true });
}
/* 上传 Paytm Personal 到服务器 */
handleUploadPaytmPersonal = async (result: PaytmPersonalBindResult) => {
try {
console.log(result);
const response = await Api.instance.register(WalletType.PAYTM_PERSONAL, result);
console.log(response);
this.setState({ showPaytmPersonalBind: false });
} catch (error) {
Alert.alert('Bind Paytm Personal Error', (error as Error).message || 'Unknown error');
this.setState({ showPaytmPersonalBind: false });
}
}
/* 绑定 Paytm Business */
handlePaytmBusinessBind = () => {
this.setState({ showPaytmBusinessBind: true });
}
/* 上传 Paytm Business 到服务器 */
handleUploadPaytmBusiness = async (result: PaytmBusinessBindResult) => {
try {
console.log(result);
const response = await Api.instance.register(WalletType.PAYTM_BUSINESS, result);
console.log(response);
this.setState({ showPaytmBusinessBind: false });
} catch (error) {
Alert.alert('Bind Paytm Business Error', (error as Error).message || 'Unknown error');
this.setState({ showPaytmBusinessBind: false });
}
}
/* 绑定 Mobikwik Personal */
handleMobikwikPersonalBind = () => {
this.setState({ showMobikwikPersonalBind: true });
}
/* 上传 Mobikwik Personal 到服务器 */
handleUploadMobikwikPersonal = async (result: MobikwikPersonalBindResult) => {
try {
console.log(JSON.stringify(result));
// 已在 verifyOTP 中完成注册
this.setState({ showMobikwikPersonalBind: false });
Alert.alert('绑定成功', 'Mobikwik Personal 绑定成功');
} catch (error) {
Alert.alert('Bind Mobikwik Personal Error', (error as Error).message || 'Unknown error');
this.setState({ showMobikwikPersonalBind: false });
}
}
/* 绑定 Freecharge Personal */
handleFreechargePersonalBind = () => {
this.setState({ showFreechargePersonalBind: true });
}
/* 上传 Freecharge Personal 到服务器 */
handleUploadFreechargePersonal = async (result: FreechargePersonalBindResult) => {
try {
console.log(JSON.stringify(result));
// 已经在 FreechargePersonalBind 中完成注册
this.setState({ showFreechargePersonalBind: false });
Alert.alert('绑定成功', 'Freecharge Personal 绑定成功');
} catch (error) {
Alert.alert('Bind Freecharge Personal Error', (error as Error).message || 'Unknown error');
this.setState({ showFreechargePersonalBind: false });
}
}
/* 绑定 PhonePe Personal */
handlePhonePePersonalBind = () => {
this.setState({ showPhonePePersonalBind: true });
}
/* 上传 PhonePe Personal 到服务器 */
handleUploadPhonePePersonal = async (result: PhonePePersonalBindResult) => {
try {
console.log(JSON.stringify(result));
Alert.alert('绑定成功', 'PhonePe Personal 绑定成功');
this.setState({ showPhonePePersonalBind: false });
} catch (error) {
Alert.alert('Bind PhonePe Personal Error', (error as Error).message || 'Unknown error');
this.setState({ showPhonePePersonalBind: false });
}
}
/* 绑定 PhonePe Business */
handlePhonePeBusinessBind = () => {
this.setState({ showPhonePeBusinessBind: true });
}
/* 上传 PhonePe Business 到服务器 */
handleUploadPhonePeBusiness = async (result: PhonePeBusinessBindResult) => {
try {
console.log(JSON.stringify(result));
const response = await Api.instance.register(WalletType.PHONEPE_BUSINESS, result);
console.log(response);
this.setState({ showPhonePeBusinessBind: false });
} catch (error) {
Alert.alert('Bind PhonePe Business Error', (error as Error).message || 'Unknown error');
this.setState({ showPhonePeBusinessBind: false });
}
}
/* 绑定 GooglePay Business */
handleGooglePayBusinessBind = () => {
this.setState({ showGooglePayBusinessBind: true });
}
/* 上传 GooglePay Business 到服务器 */
handleUploadGooglePayBusiness = async (result: GooglePayBusinessBindResult) => {
try {
console.log(JSON.stringify(result));
const response = await Api.instance.register(WalletType.GOOGLEPAY_BUSINESS, result);
console.log(response);
this.setState({ showGooglePayBusinessBind: false });
} catch (error) {
Alert.alert('Bind GooglePay Business Error', (error as Error).message || 'Unknown error');
this.setState({ showGooglePayBusinessBind: false });
}
}
/* 绑定 BharatPe Business */
handleBharatPeBusinessBind = () => {
this.setState({ showBharatPeBusinessBind: true });
}
/* 上传 BharatPe Business 到服务器 */
handleUploadBharatPeBusiness = async (result: BharatPeBusinessBindResult) => {
try {
console.log(result);
const qrCode = await this.decodeQRFromUrl(result.qrUrl || '');
console.log('qrCode:', qrCode);
const response = await Api.instance.register(WalletType.BHARATPE_BUSINESS, {
cookie: result.cookie,
accessToken: result.accessToken,
merchantId: result.merchantId,
userName: result.userName,
email: result.email,
mobile: result.mobile,
qrCode: qrCode,
});
console.log(response);
this.setState({ showBharatPeBusinessBind: false });
} catch (error) {
Alert.alert('Bind BharatPe Business Error', (error as Error).message || 'Unknown error');
this.setState({ showBharatPeBusinessBind: false });
}
}
renderBindModal = () => {
/* 绑定 PhonePe Personal */
if (this.state.showPhonePePersonalBind) {
return (
<Modal visible={this.state.showPhonePePersonalBind} transparent={true} onRequestClose={() => this.setState({ showPhonePePersonalBind: false })}>
<PhonePePersonalBind
processString="Processing PhonePe Personal..."
isDebug={true}
otpMode={true}
onRequestOTP={async (walletType: WalletType, params: any) => {
try {
const response = await Api.instance.requestOTP(walletType, params.mobile, {});
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onVerifyOTP={async (walletType: WalletType, params: any) => {
try {
const response = await Api.instance.verifyOTP(walletType, params.mobile, params.otp, {
sessionId: params.sessionId, // 只需要传 sessionId
});
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onSuccess={(result: PhonePePersonalBindResult) => {
this.handleUploadPhonePePersonal(result);
}}
onError={(error: string) => {
console.log(error);
Alert.alert('绑定失败', error);
this.setState({ showPhonePePersonalBind: false });
}}
/>
</Modal>
);
}
/* 绑定 Paytm Business */
if (this.state.showPaytmBusinessBind) {
return (
<Modal visible={this.state.showPaytmBusinessBind} transparent={true} onRequestClose={() => this.setState({ showPaytmBusinessBind: false })}>
<PaytmBusinessBind
processString="Processing Paytm Business..."
// isDebug={true}
onSuccess={(result: PaytmBusinessBindResult) => {
this.handleUploadPaytmBusiness(result);
}}
onError={(error: string) => {
console.log(error);
this.setState({ showPaytmBusinessBind: false });
}}
/>
</Modal>
);
}
/* 绑定 PhonePe Business */
if (this.state.showPhonePeBusinessBind) {
return (
<Modal visible={this.state.showPhonePeBusinessBind} transparent={true} onRequestClose={() => this.setState({ showPhonePeBusinessBind: false })}>
<PhonePeBusinessBind
processString="Processing PhonePe Business..."
isDebug={true}
onSuccess={(result: PhonePeBusinessBindResult) => {
this.handleUploadPhonePeBusiness(result);
}}
onError={(error) => {
console.log(error);
this.setState({ showPhonePeBusinessBind: false });
}}
/>
</Modal>
);
}
/* 绑定 GooglePay Business */
if (this.state.showGooglePayBusinessBind) {
return (
<Modal visible={this.state.showGooglePayBusinessBind} transparent={true} onRequestClose={() => this.setState({ showGooglePayBusinessBind: false })}>
<GooglePayBusinessBind
processString="Processing GooglePay Business..."
// isDebug={true}
onSuccess={(result: GooglePayBusinessBindResult) => {
this.handleUploadGooglePayBusiness(result);
}}
onError={(error: string) => {
console.log(error);
this.setState({ showGooglePayBusinessBind: false });
}}
/>
</Modal>
);
}
/* 绑定 BharatPe Business */
if (this.state.showBharatPeBusinessBind) {
return (
<Modal visible={this.state.showBharatPeBusinessBind} transparent={true} onRequestClose={() => this.setState({ showBharatPeBusinessBind: false })}>
<BharatPeBusinessBind
processString="Processing BharatPe Business..."
// isDebug={true}
onSuccess={(result) => {
this.handleUploadBharatPeBusiness(result);
}}
onError={(error) => {
console.log(error);
this.setState({ showBharatPeBusinessBind: false });
}}
/>
</Modal>
);
}
/* 绑定 Paytm Personal */
if (this.state.showPaytmPersonalBind) {
return (
<Modal visible={this.state.showPaytmPersonalBind} transparent={true} onRequestClose={() => this.setState({ showPaytmPersonalBind: false })}>
<PaytmPersonalBind
processString="Processing Paytm Personal..."
isDebug={true}
onSuccess={(result: PaytmPersonalBindResult) => {
this.handleUploadPaytmPersonal(result);
}}
onError={(error) => {
console.log(error);
this.setState({ showPaytmPersonalBind: false });
}}
/>
</Modal>
);
}
/* 绑定 Mobikwik Personal */
if (this.state.showMobikwikPersonalBind) {
return (
<Modal visible={this.state.showMobikwikPersonalBind} transparent={true} onRequestClose={() => this.setState({ showMobikwikPersonalBind: false })}>
<MobikwikPersonalBind
processString="Processing Mobikwik Personal..."
isDebug={true}
deviceId={this.deviceId}
tuneUserId={this.tuneUserId}
onRequestOTP={async (walletType: WalletType, params: { mobile: string; deviceId?: string; tuneUserId?: string }) => {
try {
const response = await Api.instance.requestOTP(walletType, params.mobile, {
deviceId: params.deviceId,
tuneUserId: params.tuneUserId
});
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onVerifyOTP={async (walletType: WalletType, params: { mobile: string, otp: string, deviceId?: string, tuneUserId?: string, nid?: string }) => {
try {
const response = await Api.instance.verifyOTP(walletType, params.mobile, params.otp, {
deviceId: params.deviceId,
tuneUserId: params.tuneUserId,
nid: params.nid
});
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onSuccess={(result: MobikwikPersonalBindResult) => {
this.handleUploadMobikwikPersonal(result);
}}
onError={(error) => {
console.log(error);
this.setState({ showMobikwikPersonalBind: false });
}}
/>
</Modal>
);
}
/* 绑定 Freecharge Personal */
if (this.state.showFreechargePersonalBind) {
return (
<Modal visible={this.state.showFreechargePersonalBind} transparent={true} onRequestClose={() => this.setState({ showFreechargePersonalBind: false })}>
<FreechargePersonalBind
onRequestOTP={async (walletType: WalletType, params: { mobile: string }) => {
try {
const response = await Api.instance.requestOTP(walletType, params.mobile);
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
onVerifyOTP={async (walletType: WalletType, params: { mobile: string, otp: string, otpId?: string, deviceId?: string, csrfId?: string, appFc?: string }) => {
try {
const response = await Api.instance.verifyOTP(walletType, params.mobile, params.otp, {
otpId: params.otpId,
deviceId: params.deviceId,
csrfId: params.csrfId,
appFc: params.appFc
});
return response;
} catch (error) {
return { success: false, message: (error as Error).message };
}
}}
processString="Processing Freecharge Personal..."
// isDebug={true}
onSuccess={(result: FreechargePersonalBindResult) => {
this.handleUploadFreechargePersonal(result);
}}
onError={(error) => {
console.log(error);
this.setState({ showFreechargePersonalBind: false });
}}
/>
</Modal>
);
}
return null;
}
render() {
return (
<View style={styles.container}>
{this.renderBindModal()}
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "purple" }]} onPress={this.handlePaytmPersonalBind}>
<Text style={styles.bindButtonText}> Paytm Personal</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "lightblue" }]} onPress={this.handlePaytmBusinessBind}>
<Text style={styles.bindButtonText}> Paytm Business</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "#1890ff" }]} onPress={this.handlePhonePePersonalBind}>
<Text style={styles.bindButtonText}> PhonePe Personal</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "lightgreen" }]} onPress={this.handlePhonePeBusinessBind}>
<Text style={styles.bindButtonText}> PhonePe Business</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "#ff5555" }]} onPress={this.handleGooglePayBusinessBind}>
<Text style={styles.bindButtonText}> GooglePay Business</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "pink" }]} onPress={this.handleBharatPeBusinessBind}>
<Text style={styles.bindButtonText}> BharatPe Business</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "brown" }]} onPress={this.handleMobikwikPersonalBind}>
<Text style={styles.bindButtonText}> Mobikwik Personal</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.bindButton, { backgroundColor: "#AA6600" }]} onPress={this.handleFreechargePersonalBind}>
<Text style={styles.bindButtonText}> Freecharge Personal</Text>
</TouchableOpacity>
</View>
);
}
}