import React, { useEffect, useMemo, useState } from 'react'; import { Alert, ActivityIndicator, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { onProxyMessage, proxySendMessage, openPaytmPayToBank, openPaytmPayToBank2, openMobikwikPayToBank, openPhonePePayToBank, openFreechargePayToBank, buildFreechargePayToBankDeeplink, openAmazonPayPayToBank, FreechargePersonalBind, FreechargePersonalBindResult, WalletType, } from 'rnwalletman'; import Api, { loadServerDomain, saveServerDomain } from '../services/api'; const PROD_API = 'https://aa.pfgame.org'; type PayProvider = 'paytm' | 'paytm2' | 'mobikwik' | 'phonepe' | 'freecharge' | 'amazonpay'; type Payee = { id: string; label: string; name: string; account: string; ifsc: string; amount: string; comment: string; }; const PAYEES: Payee[] = [ { id: 'harsh-psib', label: 'Harshpreet · PSIB', name: 'Harshpreet singh', account: '01601000068180', ifsc: 'PSIB0000160', amount: '2', comment: '66666', }, { id: 'harsh-cnrb', label: 'Harshpreet · CNRB', name: 'Harshpreet singh', account: '110140729840', ifsc: 'CNRB0016365', amount: '12', comment: 'payment', }, { id: 'anmol-cnrb', label: 'Anmol · CNRB', name: 'Anmol', account: '5521101002938', ifsc: 'CNRB0005521', amount: '12', comment: 'transfer', }, { id: 'fc-test', label: 'Freecharge test · PSIB', name: 'Test User', account: '8284919464', ifsc: 'PSIB0000160', amount: '2', comment: 'test transfer', }, { id: 'paytm2-demo', label: 'Paytm deeplink demo', name: 'Harshpreet singh', account: '01601000068180', ifsc: 'PSIB0000160', amount: '3', comment: '1234', }, ]; const PAY_PROVIDERS: { id: PayProvider; label: string; color: string }[] = [ { id: 'paytm', label: 'Paytm', color: '#2ecc71' }, { id: 'paytm2', label: 'Paytm DL', color: '#27ae60' }, { id: 'mobikwik', label: 'Mobikwik', color: '#2ecc33' }, { id: 'phonepe', label: 'PhonePe', color: '#5a2d9c' }, { id: 'freecharge', label: 'Freecharge', color: '#5468db' }, { id: 'amazonpay', label: 'Amazon Pay', color: '#ff9900' }, ]; async function launchPay(provider: PayProvider, payee: Payee): Promise { const { name, account, ifsc, amount, comment } = payee; switch (provider) { case 'paytm': return openPaytmPayToBank(name, account, ifsc, amount, comment); case 'paytm2': return openPaytmPayToBank2(name, account, ifsc, amount, comment); case 'mobikwik': return openMobikwikPayToBank(name, account, ifsc, amount); case 'phonepe': return openPhonePePayToBank(name, account, ifsc, amount, comment); case 'freecharge': return openFreechargePayToBank(name, account, ifsc, amount, comment); case 'amazonpay': return openAmazonPayPayToBank(); default: return false; } } export default function TestScreen() { const [selectedPayeeId, setSelectedPayeeId] = useState(PAYEES[0].id); const [selectedProvider, setSelectedProvider] = useState('freecharge'); const [showFcAuth, setShowFcAuth] = useState(false); const [apiBaseUrl, setApiBaseUrl] = useState(''); const [fcAuthResult, setFcAuthResult] = useState(null); const selectedPayee = useMemo( () => PAYEES.find(p => p.id === selectedPayeeId) ?? PAYEES[0], [selectedPayeeId], ); useEffect(() => { (async () => { await saveServerDomain('aa.pfgame.org', true); await loadServerDomain(); setApiBaseUrl(Api.BASE_URL); })(); const sub = onProxyMessage(msg => { if (msg.type === 'echo') { Alert.alert('Echo Response', JSON.stringify(msg.data)); } }); return () => sub.remove(); }, []); const handlePay = async () => { try { if (selectedProvider === 'freecharge') { const deeplink = buildFreechargePayToBankDeeplink( selectedPayee.account, selectedPayee.ifsc, ); console.log('[TestScreen] Freecharge deeplink:', deeplink); } const ok = await launchPay(selectedProvider, selectedPayee); if (!ok) { Alert.alert('Pay', 'Failed to open payment app'); } } catch (e) { Alert.alert('Transfer Failed', String(e)); } }; const handleEcho = () => { proxySendMessage({ type: 'echo', messageId: `echo_${Date.now()}`, data: { text: `hello_${Date.now()}` }, }); }; const handleFcAuthSuccess = async (result: FreechargePersonalBindResult) => { setFcAuthResult(result); setShowFcAuth(false); try { await Api.instance.register( WalletType.FREECHARGE_PERSONAL, { type: WalletType.FREECHARGE_PERSONAL, success: true, mobile: result.mobile, token: result.token, userId: result.userId || result.imsId, extend: { appVersion: result.appVersion || '' }, }, ); Alert.alert('Register OK', 'Freecharge 钱包已注册到服务端'); } catch (e) { Alert.alert('Register failed', String(e)); } }; return ( Server: {apiBaseUrl || PROD_API} 收款人 {PAYEES.map(payee => { const active = payee.id === selectedPayeeId; return ( setSelectedPayeeId(payee.id)} > {payee.label} {payee.name} · {payee.account} · {payee.ifsc} ₹{payee.amount} · {payee.comment} ); })} 支付方式 {PAY_PROVIDERS.map(p => { const active = p.id === selectedProvider; return ( setSelectedProvider(p.id)} > {p.label} ); })} 付款 · {PAY_PROVIDERS.find(p => p.id === selectedProvider)?.label} → {selectedPayee.label} Freecharge Inject 授权 setShowFcAuth(true)} > 打开 Inject 授权(官方 App WebView) {fcAuthResult ? ( 最近授权 mobile: {fcAuthResult.mobile} imsId: {fcAuthResult.imsId} upi: {(fcAuthResult.vpas || []).map(v => v.vpa).join(', ')} ) : null} Echo Test setShowFcAuth(false)} > {apiBaseUrl ? ( setShowFcAuth(false)} onSuccess={handleFcAuthSuccess} onError={msg => { Alert.alert('Freecharge Auth Failed', msg); }} /> ) : ( Loading server URL… )} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f0f0f0', }, content: { padding: 16, paddingBottom: 40, }, serverUrl: { fontSize: 12, color: '#1565c0', marginBottom: 8, fontWeight: '600', }, sectionTitle: { fontSize: 16, fontWeight: '600', color: '#333', marginBottom: 10, marginTop: 8, }, payeeCard: { backgroundColor: '#fff', borderRadius: 10, padding: 14, marginBottom: 8, borderWidth: 2, borderColor: 'transparent', }, payeeCardActive: { borderColor: '#3498db', backgroundColor: '#eef6ff', }, payeeLabel: { fontSize: 15, fontWeight: '600', color: '#333', }, payeeLabelActive: { color: '#1565c0', }, payeeMeta: { fontSize: 12, color: '#666', marginTop: 4, }, providerRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginBottom: 16, }, providerChip: { paddingHorizontal: 12, paddingVertical: 8, borderRadius: 20, borderWidth: 1, borderColor: '#ccc', backgroundColor: '#fff', }, providerChipText: { fontSize: 13, color: '#444', fontWeight: '500', }, providerChipTextActive: { color: '#fff', }, btn: { width: '100%', paddingVertical: 14, borderRadius: 8, alignItems: 'center', marginBottom: 12, }, btnText: { color: '#fff', fontSize: 15, fontWeight: '600', textAlign: 'center', }, resultBox: { backgroundColor: '#fff', borderRadius: 10, padding: 12, marginBottom: 12, }, resultTitle: { fontWeight: '600', marginBottom: 6, color: '#333', }, resultText: { fontSize: 12, color: '#555', marginBottom: 2, }, loadingBox: { flex: 1, backgroundColor: 'rgba(0,0,0,0.7)', justifyContent: 'center', alignItems: 'center', }, modalRoot: { flex: 1, }, });