import React, { Component, useState, useEffect } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator } from 'react-native'; import { WalletType, FreechargePersonalBindResult, MobikwikPersonalBindResult, PaytmPersonalBindResult, PhonePePersonalBindResult, PhonePeBusinessBindResult, BharatPeBusinessBindResult, PaytmBusinessBindResult } from 'rnwalletman'; import { OTPBindUI } from './OTPBindUI'; export class FreeChargeBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: FreechargePersonalBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } export class MobikwikOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: MobikwikPersonalBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } export class PayTmPersonalOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: PaytmPersonalBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } export class BharatPeBusinessOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: BharatPeBusinessBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } export class PaytmBusinessOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: PaytmBusinessBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } function PaytmBusinessForm({ onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug, initialMobile = '' }: { onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: PaytmBusinessBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }) { const [step, setStep] = useState<'credentials' | 'otp'>('credentials'); const [mobile, setMobile] = useState(initialMobile); const [otp, setOtp] = useState(''); const [sessionToken, setSessionToken] = useState(''); const [loading, setLoading] = useState(false); const [errorMsg, setErrorMsg] = useState(''); useEffect(() => { if (initialMobile) setMobile(initialMobile); }, [initialMobile]); const log = (...args: any[]) => { if (isDebug) console.log('[PaytmBusiness]', ...args); }; const handleRequestOTP = async () => { if (!mobile || mobile.length !== 10) { setErrorMsg('请输入10位手机号'); return; } setLoading(true); setErrorMsg(''); try { const res = await onRequestOTP(WalletType.PAYTM_BUSINESS, { mobile }); log('RequestOTP:', res); if (res.success) { setSessionToken(res.data?.sessionToken || ''); setStep('otp'); } else { const msg = res.message || 'Failed to send OTP'; setErrorMsg(msg); onError(msg); } } catch (e) { const msg = e instanceof Error ? e.message : 'Failed to send OTP'; setErrorMsg(msg); onError(msg); } finally { setLoading(false); } }; const handleVerifyOTP = async () => { if (!otp || otp.length !== 6) { setErrorMsg('请输入6位验证码'); return; } setLoading(true); setErrorMsg(''); try { const res = await onVerifyOTP(WalletType.PAYTM_BUSINESS, { mobile, otp, sessionToken }); log('VerifyOTP:', res); if (res.success) { onSuccess({ type: WalletType.PAYTM_BUSINESS, success: true, cookie: res.data?.cookie || '', xCsrfToken: res.data?.xCsrfToken || '', qrData: res.data?.qrData || [] }); } else { setErrorMsg(res.message || 'Failed to verify OTP'); setStep('otp'); } } catch (e) { setErrorMsg(e instanceof Error ? e.message : 'Failed to verify OTP'); setStep('otp'); } finally { setLoading(false); } }; return ( Paytm Business 绑定 {errorMsg ? {errorMsg} : null} {step === 'credentials' && ( <> { setMobile(t); setErrorMsg(''); }} editable={!loading} /> {loading ? : 获取验证码} )} {step === 'otp' && ( <> 验证码已发送至 {mobile} { setOtp(t); setErrorMsg(''); }} editable={!loading} /> {loading ? : 验证并绑定} setStep('credentials')} disabled={loading}> 重新输入手机号 )} ); } const ptStyles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'rgba(0,0,0,0.8)', justifyContent: 'center', alignItems: 'center' }, form: { width: '92%', backgroundColor: '#fff', borderRadius: 20, padding: 28 }, title: { fontSize: 22, fontWeight: '700', textAlign: 'center', color: '#111', marginBottom: 24 }, input: { borderWidth: 1.5, borderColor: '#e0e0e0', borderRadius: 10, paddingHorizontal: 14, paddingVertical: 14, fontSize: 17, color: '#111', marginBottom: 18, backgroundColor: '#fafafa' }, errorText: { color: '#ff3b30', fontSize: 13, marginBottom: 12, textAlign: 'center' }, button: { backgroundColor: '#007AFF', borderRadius: 12, paddingVertical: 16, alignItems: 'center', marginTop: 4 }, buttonDisabled: { backgroundColor: '#a0c4ff' }, buttonText: { color: '#fff', fontSize: 17, fontWeight: '600' }, linkButton: { marginTop: 16, alignItems: 'center' }, linkText: { color: '#007AFF', fontSize: 14 }, hint: { fontSize: 14, color: '#555', marginBottom: 18, textAlign: 'center' }, }); export class PhonePeBusinessOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: PhonePeBusinessBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } } export class PhonePePersonalOTPBind extends Component<{ onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: PhonePePersonalBindResult) => void; onError: (error: string) => void; isDebug: boolean; initialMobile?: string; }> { render() { return ( ); } }