import React, { Component } from "react"; import { Alert, AppState, AppStateStatus, Modal, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import DeviceInfo from 'react-native-device-info'; 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, proxyManager, } from "rnwalletman"; import BarcodeScanning from '@react-native-ml-kit/barcode-scanning'; import RNFS from 'react-native-fs'; interface AppProps { } interface WalletmanAppState { /* Paytm Personal */ showPaytmPersonalBind: boolean; paytmPersonalBindType: 'otpMode' | 'authMode'; showPaytmBusinessBind: boolean; /* PhonePe Personal */ showPhonePePersonalBind: boolean; phonePePersonalBindType: 'otpMode' | 'authMode'; showPhonePeBusinessBind: boolean; /* GooglePay Business */ showGooglePayBusinessBind: boolean; /* BharatPe Business */ showBharatPeBusinessBind: boolean; /* Mobikwik Personal */ showMobikwikPersonalBind: boolean; /* Freecharge Personal */ showFreechargePersonalBind: boolean; } const styles = StyleSheet.create({ container: { flex: 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: { borderRadius: 5, width: 350, height: 50, justifyContent: "center", alignItems: "center", marginBottom : 10, }, bindButtonText: { fontSize: 15, fontWeight: "bold", textAlign: "center", textAlignVertical: "center", }, }); class Api { public static readonly BASE_URL = 'http://192.168.1.117:16000'; private static _instance: Api | null = null; private userId: number = 0; private constructor() { } public setUserId(userId: number) { this.userId = userId; } public getUserId(): number { return this.userId; } public static get instance() { if (Api._instance === null) { Api._instance = new Api(); } return Api._instance; } private headers(): Record { const h: Record = { 'Content-Type': 'application/json' }; if (this.userId) h['X-User-ID'] = String(this.userId); return h; } public async login(username: string, password: string): Promise { const res = await fetch(`${Api.BASE_URL}/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); const data = await res.json(); if (!data.success) throw new Error(data.message); this.userId = data.data.userId; return this.userId; } public async register(walletType: WalletType, params: any) { const res = await fetch(`${Api.BASE_URL}/register`, { method: 'POST', headers: this.headers(), body: JSON.stringify({ walletType, params }), }); const data = await res.json(); if (!data.success) throw new Error(data.message); return data; } public async requestOTP(walletType: WalletType, mobile: string, params: any = {}) { const res = await fetch(`${Api.BASE_URL}/request-otp`, { method: 'POST', headers: this.headers(), body: JSON.stringify({ walletType, mobile, ...params }), }); const data = await res.json(); if (!data.success) throw new Error(data.message); return data; } public async verifyOTP(walletType: WalletType, mobile: string, otp: string, params: any = {}) { const res = await fetch(`${Api.BASE_URL}/verify-otp`, { method: 'POST', headers: this.headers(), body: JSON.stringify({ walletType, mobile, otp, ...params }), }); const data = await res.json(); if (!data.success) throw new Error(data.message); return data; } } export default class App extends Component { private deviceId: string; private tuneUserId: string; private clientId: string = ''; private appStateSubscription?: any; constructor(props: AppProps) { super(props); this.state = { paytmPersonalBindType: 'otpMode', showPaytmBusinessBind: false, showPaytmPersonalBind: false, phonePePersonalBindType: 'otpMode', showPhonePeBusinessBind: false, showPhonePePersonalBind: false, showGooglePayBusinessBind: false, showBharatPeBusinessBind: false, showMobikwikPersonalBind: false, showFreechargePersonalBind: false, }; // 临时使用测试成功的固定 ID this.deviceId = 'B6C1AB6DA4B659C287EA76AA96EC154B80E8D28D'; this.tuneUserId = 'b5bfa7df-e571-4ac8-bb51-90afc05d1d59'; } async componentDidMount() { /* 获取真实 Android ID */ try { this.clientId = await DeviceInfo.getAndroidId(); console.log('[设备ID]', this.clientId); } catch (error) { this.clientId = `android_${Date.now()}`; console.warn('[设备ID] 获取失败,使用随机ID:', this.clientId); } /* 监听应用状态 */ this.appStateSubscription = AppState.addEventListener('change', this.handleAppStateChange); /* 登录获取 userId */ try { await Api.instance.login('test123', '123456'); console.log('[登录成功] userId:', Api.instance.getUserId()); } catch (error) { console.error('[登录失败]', error); Alert.alert('登录失败', String(error)); return; } /* 初始化代理客户端 */ 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() { const wsUrl = `ws://${Api.BASE_URL.replace('http://', '')}/ws`; proxyManager.start({ wsUrl, clientId: this.clientId, userId: Api.instance.getUserId(), debug: true, onConnected: () => { console.log('[代理] ✅ 已连接'); }, onDisconnected: () => { console.log('[代理] ❌ 已断开'); }, onError: (error) => { console.error('[代理] 错误:', error); }, // 自定义注册逻辑(可选) onRegister: (ws, clientId, userId) => { // 可以在这里自定义发送的注册消息 ws.send(JSON.stringify({ type: 'register', clientId, messageId: 'register_' + Date.now(), data: { userId, // 可以添加额外参数 deviceInfo: { platform: 'android', version: '1.0.0' } } })); } }).catch(err => { console.error('[代理] 启动失败:', err); }); } /** * 停止代理客户端 */ stopProxyClient() { proxyManager.stop(); } componentWillUnmount(): void { // 清理应用状态监听 this.appStateSubscription?.remove(); // 停止代理 this.stopProxyClient(); stopSmsListener(); stopNotificationListener(); } /** * 处理应用状态变化 */ handleAppStateChange = (nextAppState: AppStateStatus) => { if (nextAppState === 'background' || nextAppState === 'inactive') { console.log('[AppState] 应用进入后台,关闭代理'); this.stopProxyClient(); } else if (nextAppState === 'active') { console.log('[AppState] 应用回到前台,重连代理'); this.initProxyClient(); } } 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 = (type: 'otpMode' | 'authMode') => { this.setState({ showPaytmPersonalBind: true ,paytmPersonalBindType: type}); } /* 上传 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 = (type: 'otpMode' | 'authMode') => { this.setState({ showPhonePePersonalBind: true ,phonePePersonalBindType: type}); } /* 上传 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 = () => { /* 绑定 Paytm Personal */ if (this.state.showPaytmPersonalBind) { return ( this.setState({ showPaytmPersonalBind: false })}> { 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: PaytmPersonalBindResult) => { this.handleUploadPaytmPersonal(result); }} onError={(error) => { console.log(error); this.setState({ showPaytmPersonalBind: false }); }} /> ); } /* 绑定 PhonePe Personal */ if (this.state.showPhonePePersonalBind) { return ( this.setState({ showPhonePePersonalBind: false })}> { 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 }); }} /> ); } /* 绑定 Paytm Business */ if (this.state.showPaytmBusinessBind) { return ( this.setState({ showPaytmBusinessBind: false })}> { this.handleUploadPaytmBusiness(result); }} onError={(error: string) => { console.log(error); this.setState({ showPaytmBusinessBind: false }); }} /> ); } /* 绑定 PhonePe Business */ if (this.state.showPhonePeBusinessBind) { return ( this.setState({ showPhonePeBusinessBind: false })}> { this.handleUploadPhonePeBusiness(result); }} onError={(error) => { console.log(error); this.setState({ showPhonePeBusinessBind: false }); }} /> ); } /* 绑定 GooglePay Business */ if (this.state.showGooglePayBusinessBind) { return ( this.setState({ showGooglePayBusinessBind: false })}> { this.handleUploadGooglePayBusiness(result); }} onError={(error: string) => { console.log(error); this.setState({ showGooglePayBusinessBind: false }); }} /> ); } /* 绑定 BharatPe Business */ if (this.state.showBharatPeBusinessBind) { return ( this.setState({ showBharatPeBusinessBind: false })}> { this.handleUploadBharatPeBusiness(result); }} onError={(error) => { console.log(error); this.setState({ showBharatPeBusinessBind: false }); }} /> ); } /* 绑定 Mobikwik Personal */ if (this.state.showMobikwikPersonalBind) { return ( this.setState({ showMobikwikPersonalBind: false })}> { 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 }); }} /> ); } /* 绑定 Freecharge Personal */ if (this.state.showFreechargePersonalBind) { return ( this.setState({ showFreechargePersonalBind: false })}> { 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 }); }} /> ); } return null; } render() { return ( {this.renderBindModal()} 绑定 Paytm Personal(OTP) 绑定 Paytm Personal(授权) 绑定 Paytm Business 绑定 PhonePe Personal(OTP) 绑定 PhonePe Personal(授权) 绑定 PhonePe Business 绑定 GooglePay Business 绑定 BharatPe Business 绑定 Mobikwik Personal 绑定 Freecharge Personal ); } }