111
This commit is contained in:
@@ -22,3 +22,4 @@ others
|
|||||||
*.lock
|
*.lock
|
||||||
**/fcm-service-account.json
|
**/fcm-service-account.json
|
||||||
**/firebase-adminsdk*.json
|
**/firebase-adminsdk*.json
|
||||||
|
logs/googlepay_business
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import {
|
|||||||
import { saveServerDomain } from '../services/api';
|
import { saveServerDomain } from '../services/api';
|
||||||
|
|
||||||
const PRESETS = [
|
const PRESETS = [
|
||||||
{ label: '192.168.1.117:16000', host: '192.168.1.117', port: '16000' },
|
|
||||||
{ label: 'aa.pfgame.org', host: 'aa.pfgame.org', port: '443' },
|
{ label: 'aa.pfgame.org', host: 'aa.pfgame.org', port: '443' },
|
||||||
|
{ label: '192.168.1.117:16000', host: '192.168.1.117', port: '16000' },
|
||||||
];
|
];
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -62,7 +62,7 @@ export const ServerSettingsModal: React.FC<Props> = ({
|
|||||||
style={styles.textInput}
|
style={styles.textInput}
|
||||||
value={host}
|
value={host}
|
||||||
onChangeText={onHostChange}
|
onChangeText={onHostChange}
|
||||||
placeholder="192.168.1.117"
|
placeholder="aa.pfgame.org"
|
||||||
autoCapitalize="none"
|
autoCapitalize="none"
|
||||||
/>
|
/>
|
||||||
<Text style={styles.inputLabel}>Port</Text>
|
<Text style={styles.inputLabel}>Port</Text>
|
||||||
@@ -70,7 +70,7 @@ export const ServerSettingsModal: React.FC<Props> = ({
|
|||||||
style={[styles.textInput, { marginBottom: 20 }]}
|
style={[styles.textInput, { marginBottom: 20 }]}
|
||||||
value={port}
|
value={port}
|
||||||
onChangeText={onPortChange}
|
onChangeText={onPortChange}
|
||||||
placeholder="16000"
|
placeholder="443"
|
||||||
keyboardType="number-pad"
|
keyboardType="number-pad"
|
||||||
/>
|
/>
|
||||||
<View style={styles.actions}>
|
<View style={styles.actions}>
|
||||||
|
|||||||
+1
-1
Submodule libs/rnwalletman updated: b752bc10e0...f8c6bfea21
+14
-57
@@ -18,7 +18,6 @@ import {
|
|||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import * as Animatable from 'react-native-animatable';
|
import * as Animatable from 'react-native-animatable';
|
||||||
import DeviceInfo from 'react-native-device-info';
|
import DeviceInfo from 'react-native-device-info';
|
||||||
import CookieManager from '@react-native-cookies/cookies';
|
|
||||||
import {
|
import {
|
||||||
GooglePayBusinessBind,
|
GooglePayBusinessBind,
|
||||||
PhonePeBusinessBind,
|
PhonePeBusinessBind,
|
||||||
@@ -65,11 +64,14 @@ import { buildWalletCardId } from '../utils/walletCardId';
|
|||||||
/** ipay patch 期望,bind 与 ProxyService FCM 重绑共用 */
|
/** ipay patch 期望,bind 与 ProxyService FCM 重绑共用 */
|
||||||
const PATCH_EXPECT: PatchConfig = {
|
const PATCH_EXPECT: PatchConfig = {
|
||||||
chType: 'ipay',
|
chType: 'ipay',
|
||||||
paytmChVersion: '3',
|
paytmChVersion: '7',
|
||||||
phonepeChVersion: '2',
|
phonepeChVersion: '2',
|
||||||
mobikwikChVersion: '1',
|
mobikwikChVersion: '1',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** GooglePay Business 绑定时顶部「清除缓存」按钮 */
|
||||||
|
const GOOGLEPAY_BUSINESS_SHOW_CLEAR_CACHE = true;
|
||||||
|
|
||||||
function phonePePatchFailReason(chType?: string, chVersion?: string): string | null {
|
function phonePePatchFailReason(chType?: string, chVersion?: string): string | null {
|
||||||
if (!chType || chType !== PATCH_EXPECT.chType) {
|
if (!chType || chType !== PATCH_EXPECT.chType) {
|
||||||
return 'Patched PhonePe app not installed. Reinstall required';
|
return 'Patched PhonePe app not installed. Reinstall required';
|
||||||
@@ -160,9 +162,6 @@ interface HomeScreenState {
|
|||||||
mobikwikPersonalBindType: 'otpMode' | 'tokenMode';
|
mobikwikPersonalBindType: 'otpMode' | 'tokenMode';
|
||||||
showFreechargePersonalBind: boolean;
|
showFreechargePersonalBind: boolean;
|
||||||
showAmazonPayPersonalBind: boolean;
|
showAmazonPayPersonalBind: boolean;
|
||||||
/** WebView 绑定 remount key(清除 cookie 后递增) */
|
|
||||||
webViewBindKey: number;
|
|
||||||
webViewForceClearCookies: boolean;
|
|
||||||
// proxy
|
// proxy
|
||||||
proxyStatus: 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';
|
proxyStatus: 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';
|
||||||
proxyError?: string;
|
proxyError?: string;
|
||||||
@@ -214,8 +213,6 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
showFreechargePersonalBind: false,
|
showFreechargePersonalBind: false,
|
||||||
freechargePersonalBindType: 'otpMode',
|
freechargePersonalBindType: 'otpMode',
|
||||||
showAmazonPayPersonalBind: false,
|
showAmazonPayPersonalBind: false,
|
||||||
webViewBindKey: 0,
|
|
||||||
webViewForceClearCookies: false,
|
|
||||||
proxyStatus: 'idle',
|
proxyStatus: 'idle',
|
||||||
showServerSettings: false,
|
showServerSettings: false,
|
||||||
settingsHost: '',
|
settingsHost: '',
|
||||||
@@ -512,30 +509,8 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
this.fetchWallets();
|
this.fetchWallets();
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClearWebViewCookies = async () => {
|
|
||||||
try {
|
|
||||||
await CookieManager.clearAll();
|
|
||||||
this.setState((prev) => ({
|
|
||||||
webViewBindKey: prev.webViewBindKey + 1,
|
|
||||||
webViewForceClearCookies: true,
|
|
||||||
}));
|
|
||||||
Alert.alert('已清除', 'WebView 登录状态已清除,请重新登录');
|
|
||||||
} catch (e) {
|
|
||||||
Alert.alert('Error', (e as Error).message || 'Failed to clear cookies');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
renderWebViewBindShell = (content: React.ReactNode) => (
|
renderWebViewBindShell = (content: React.ReactNode) => (
|
||||||
<View style={s.webViewBindContainer}>
|
<View style={s.webViewBindContainer}>{content}</View>
|
||||||
{content}
|
|
||||||
<TouchableOpacity
|
|
||||||
style={s.clearWebCookieBtn}
|
|
||||||
onPress={this.handleClearWebViewCookies}
|
|
||||||
activeOpacity={0.85}
|
|
||||||
>
|
|
||||||
<Text style={s.clearWebCookieBtnText}>清除 Web 登录</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// ---- modals ----
|
// ---- modals ----
|
||||||
@@ -546,8 +521,6 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
showPaytmBusinessBind, showPhonePeBusinessBind, phonePeBusinessBindType, showGooglePayBusinessBind, showBharatPeBusinessBind,
|
showPaytmBusinessBind, showPhonePeBusinessBind, phonePeBusinessBindType, showGooglePayBusinessBind, showBharatPeBusinessBind,
|
||||||
showMobikwikPersonalBind, mobikwikPersonalBindType, showFreechargePersonalBind, freechargePersonalBindType,
|
showMobikwikPersonalBind, mobikwikPersonalBindType, showFreechargePersonalBind, freechargePersonalBindType,
|
||||||
showAmazonPayPersonalBind,
|
showAmazonPayPersonalBind,
|
||||||
webViewBindKey,
|
|
||||||
webViewForceClearCookies,
|
|
||||||
bindPrefillMobile,
|
bindPrefillMobile,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
@@ -566,11 +539,12 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
processString="Processing..."
|
processString="Processing..."
|
||||||
isDebug
|
isDebug
|
||||||
onSuccess={(result: PaytmPersonalBindResult) => {
|
onSuccess={(result: PaytmPersonalBindResult) => {
|
||||||
if (result.chType != chType) {
|
const isLongfafa = result.chType === 'longfafa';
|
||||||
|
if (!isLongfafa && result.chType != chType) {
|
||||||
Alert.alert('Bind Failed', 'Patched Paytm app not installed. Reinstall required');
|
Alert.alert('Bind Failed', 'Patched Paytm app not installed. Reinstall required');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result.chVersion != remoteVersion) {
|
if (!isLongfafa && result.chVersion != remoteVersion) {
|
||||||
Alert.alert('Bind Failed', 'App version outdated. Reinstall required');
|
Alert.alert('Bind Failed', 'App version outdated. Reinstall required');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -765,10 +739,8 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
>
|
>
|
||||||
{this.renderWebViewBindShell(
|
{this.renderWebViewBindShell(
|
||||||
<PhonePeBusinessBind
|
<PhonePeBusinessBind
|
||||||
key={`phonepe-web-${webViewBindKey}`}
|
|
||||||
processString="Processing..."
|
processString="Processing..."
|
||||||
isDebug
|
isDebug
|
||||||
clearCookie={webViewForceClearCookies}
|
|
||||||
onSuccess={this.handleBindSuccess('showPhonePeBusinessBind', WalletType.PHONEPE_BUSINESS, 'PhonePe Business bound successfully') as any}
|
onSuccess={this.handleBindSuccess('showPhonePeBusinessBind', WalletType.PHONEPE_BUSINESS, 'PhonePe Business bound successfully') as any}
|
||||||
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showPhonePeBusinessBind')(); }}
|
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showPhonePeBusinessBind')(); }}
|
||||||
/>,
|
/>,
|
||||||
@@ -785,11 +757,13 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
>
|
>
|
||||||
{this.renderWebViewBindShell(
|
{this.renderWebViewBindShell(
|
||||||
<GooglePayBusinessBind
|
<GooglePayBusinessBind
|
||||||
key={`gpay-web-${webViewBindKey}`}
|
|
||||||
processString="Processing..."
|
processString="Processing..."
|
||||||
isDebug
|
isDebug
|
||||||
clearCookie={webViewForceClearCookies}
|
showClearCacheButton={GOOGLEPAY_BUSINESS_SHOW_CLEAR_CACHE}
|
||||||
onSuccess={this.handleBindSuccess('showGooglePayBusinessBind', WalletType.GOOGLEPAY_BUSINESS, 'GooglePay Business bound successfully') as any}
|
onSuccess={(result: GooglePayBusinessBindResult) => {
|
||||||
|
console.log('GooglePayBusinessBindResult', result);
|
||||||
|
this.handleBindSuccess('showGooglePayBusinessBind', WalletType.GOOGLEPAY_BUSINESS, 'GooglePay Business bound successfully')(result);
|
||||||
|
}}
|
||||||
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showGooglePayBusinessBind')(); }}
|
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showGooglePayBusinessBind')(); }}
|
||||||
/>,
|
/>,
|
||||||
)}
|
)}
|
||||||
@@ -938,10 +912,8 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
>
|
>
|
||||||
{this.renderWebViewBindShell(
|
{this.renderWebViewBindShell(
|
||||||
<AmazonPayPersonalBind
|
<AmazonPayPersonalBind
|
||||||
key={`amazon-web-${webViewBindKey}`}
|
|
||||||
processString="Processing..."
|
processString="Processing..."
|
||||||
isDebug
|
isDebug
|
||||||
clearCookie={webViewForceClearCookies}
|
|
||||||
onSuccess={this.handleBindSuccess('showAmazonPayPersonalBind', WalletType.AMAZONPAY_PERSONAL, 'Amazon Pay bound successfully') as any}
|
onSuccess={this.handleBindSuccess('showAmazonPayPersonalBind', WalletType.AMAZONPAY_PERSONAL, 'Amazon Pay bound successfully') as any}
|
||||||
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showAmazonPayPersonalBind')(); }}
|
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showAmazonPayPersonalBind')(); }}
|
||||||
/>,
|
/>,
|
||||||
@@ -955,7 +927,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
openWalletBind = (key: string, prefillMobile?: string, cardId?: string) => {
|
openWalletBind = (key: string, prefillMobile?: string, cardId?: string) => {
|
||||||
// 若从外部明确指定 cardId 则覆盖,否则保留之前 handleRebind 设的值
|
// 若从外部明确指定 cardId 则覆盖,否则保留之前 handleRebind 设的值
|
||||||
if (cardId !== undefined) this._pendingCardId = cardId;
|
if (cardId !== undefined) this._pendingCardId = cardId;
|
||||||
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '', webViewForceClearCookies: false });
|
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '' });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'paytm_personal_otp':
|
case 'paytm_personal_otp':
|
||||||
@@ -1542,19 +1514,4 @@ const s = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
},
|
},
|
||||||
clearWebCookieBtn: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: Platform.OS === 'ios' ? 48 : 12,
|
|
||||||
right: 12,
|
|
||||||
zIndex: 1000,
|
|
||||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
paddingVertical: 8,
|
|
||||||
borderRadius: 8,
|
|
||||||
},
|
|
||||||
clearWebCookieBtnText: {
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: '600',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
+10
-35
@@ -17,7 +17,6 @@ import {
|
|||||||
openMobikwikPayToBank,
|
openMobikwikPayToBank,
|
||||||
openPhonePePayToBank,
|
openPhonePePayToBank,
|
||||||
openFreechargePayToBank,
|
openFreechargePayToBank,
|
||||||
buildFreechargePayToBankDeeplink,
|
|
||||||
openAmazonPayPayToBank,
|
openAmazonPayPayToBank,
|
||||||
FreechargePersonalBind,
|
FreechargePersonalBind,
|
||||||
FreechargePersonalBindResult,
|
FreechargePersonalBindResult,
|
||||||
@@ -85,6 +84,15 @@ const PAYEES: Payee[] = [
|
|||||||
amount: '3',
|
amount: '3',
|
||||||
comment: '1234',
|
comment: '1234',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'idbi-demo',
|
||||||
|
label: 'IDBI demo',
|
||||||
|
name: 'Test User',
|
||||||
|
account: '8910888450@nyes',
|
||||||
|
ifsc: 'IDIB000K548',
|
||||||
|
amount: '2',
|
||||||
|
comment: 'test',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const PAY_PROVIDERS: { id: PayProvider; label: string; color: string }[] = [
|
const PAY_PROVIDERS: { id: PayProvider; label: string; color: string }[] = [
|
||||||
@@ -145,11 +153,7 @@ export default function TestScreen() {
|
|||||||
const handlePay = async () => {
|
const handlePay = async () => {
|
||||||
try {
|
try {
|
||||||
if (selectedProvider === 'freecharge') {
|
if (selectedProvider === 'freecharge') {
|
||||||
const deeplink = buildFreechargePayToBankDeeplink(
|
console.log('[TestScreen] Freecharge account:', selectedPayee.account);
|
||||||
selectedPayee.account,
|
|
||||||
selectedPayee.ifsc,
|
|
||||||
);
|
|
||||||
console.log('[TestScreen] Freecharge deeplink:', deeplink);
|
|
||||||
}
|
}
|
||||||
const ok = await launchPay(selectedProvider, selectedPayee);
|
const ok = await launchPay(selectedProvider, selectedPayee);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
@@ -256,35 +260,6 @@ export default function TestScreen() {
|
|||||||
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
||||||
<Text style={styles.btnText}>Echo Test</Text>
|
<Text style={styles.btnText}>Echo Test</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
<Modal
|
|
||||||
visible={showFcAuth}
|
|
||||||
transparent
|
|
||||||
animationType="fade"
|
|
||||||
statusBarTranslucent
|
|
||||||
onRequestClose={() => setShowFcAuth(false)}
|
|
||||||
>
|
|
||||||
<View style={styles.modalRoot}>
|
|
||||||
{apiBaseUrl ? (
|
|
||||||
<FreechargePersonalBind
|
|
||||||
apiBaseUrl={apiBaseUrl}
|
|
||||||
isDebug
|
|
||||||
userId={Api.instance.getUserId()}
|
|
||||||
processString="Waiting for Freecharge authorization…"
|
|
||||||
onClose={() => setShowFcAuth(false)}
|
|
||||||
onSuccess={handleFcAuthSuccess}
|
|
||||||
onError={msg => {
|
|
||||||
Alert.alert('Freecharge Auth Failed', msg);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<View style={styles.loadingBox}>
|
|
||||||
<ActivityIndicator size="large" color="#fff" />
|
|
||||||
<Text style={[styles.btnText, { marginTop: 12 }]}>Loading server URL…</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
</Modal>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule servers/walletman updated: 900bb85f5d...2462752a30
+2
-2
@@ -10,12 +10,12 @@ export interface WalletItem {
|
|||||||
otpMode?: boolean;
|
otpMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_DOMAIN = '192.168.1.117:16000';
|
const DEFAULT_DOMAIN = 'aa.pfgame.org';
|
||||||
const STORAGE_KEY = 'server_domain';
|
const STORAGE_KEY = 'server_domain';
|
||||||
const HTTPS_KEY = 'server_https';
|
const HTTPS_KEY = 'server_https';
|
||||||
|
|
||||||
let _domain = DEFAULT_DOMAIN;
|
let _domain = DEFAULT_DOMAIN;
|
||||||
let _useHttps = false;
|
let _useHttps = true;
|
||||||
|
|
||||||
export async function loadServerDomain(): Promise<string> {
|
export async function loadServerDomain(): Promise<string> {
|
||||||
const saved = await AsyncStorage.getItem(STORAGE_KEY);
|
const saved = await AsyncStorage.getItem(STORAGE_KEY);
|
||||||
|
|||||||
Reference in New Issue
Block a user