import React, { useRef, useEffect } from 'react';
import { View, StyleSheet, TouchableOpacity, Text, Modal, Platform, Linking } from 'react-native';
import { WebView } from 'react-native-webview';
interface PhoenixPaymentNativeProps {
walletAddress: string;
amount: string;
accessToken: string; // Access token from your backend
onClose: () => void;
onComplete: (success: boolean, transactionId?: string, data?: any) => void;
onDone?: () => void; // New callback for handling done events
onOrderCreated?: (data: any) => void; // Callback for handling order creation
theme?: 'light' | 'dark'; // Optional theme parameter
}
export const PhoenixPaymentNative: React.FC<PhoenixPaymentNativeProps> = ({
walletAddress,
amount,
accessToken,
onClose,
onComplete,
onDone,
onOrderCreated,
theme,
}) => {
const webViewRef = useRef<WebView>(null);
// Handle messages from WebView
const handleWebViewMessage = (event: any) => {
try {
const data = JSON.parse(event.nativeEvent.data);
// Handle transaction success message
if (data?.type === 'TRANSACTION_SUCCESS') {
const { amount, token, chain, walletAddress, sendAmount, transactionHash, basescanLink } = data.data;
onComplete(true, transactionHash, {
amount, token, chain, walletAddress, sendAmount, transactionHash, basescanLink
});
}
// Handle order created message
else if (data?.type === 'ORDER_CREATED') {
const { order_id, ...orderData } = data.data;
console.log('Order created:', data.data);
if (onOrderCreated) {
onOrderCreated({ order_id, data: orderData });
}
}
// Handle cancel message
else if (data?.type === 'CANCEL') {
console.log('Payment canceled by user');
onClose();
}
// Handle open explorer URL message
else if (data?.type === 'OPEN_EXPLORER_URL') {
const url = data.url;
console.log('Opening explorer URL:', url);
// Always open in browser using Linking
Linking.canOpenURL(url).then(supported => {
if (supported) {
Linking.openURL(url);
} else {
console.log("Don't know how to open URI: " + url);
}
});
}
// Handle done message
else if (data?.type === 'USER_DONE') {
console.log('Payment process completed');
if (onDone) {
onDone();
} else {
// Default behavior: close the window
onClose();
}
}
} catch (error) {
console.error('Error parsing WebView message:', error);
}
};
// Build WebView URL with all parameters
const getWebViewUrl = () => {
let url = `https://app-partner.phoenix.market/?address=${walletAddress}&amount=${amount}&access_token=${accessToken}`;
if (theme) {
url += `&theme=${theme}`;
}
return url;
};
// Inject JavaScript to listen for postMessage events and forward them to React Native
const injectedJavaScript = `
window.addEventListener('message', function(event) {
if (event.origin === 'https://app-partner.phoenix.market') {
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
}
});
true; // note: this is required, or you'll sometimes get silent failures
`;
return (
<Modal
visible={true}
animationType="slide"
transparent={true}
onRequestClose={onClose}
>
<View style={styles.container}>
<View style={styles.paymentModal}>
<TouchableOpacity
style={styles.closeButton}
onPress={onClose}
accessibilityLabel="Close payment window"
>
<Text style={styles.closeButtonText}>✕</Text>
</TouchableOpacity>
<WebView
ref={webViewRef}
source={{ uri: getWebViewUrl() }}
style={styles.webView}
javaScriptEnabled={true}
domStorageEnabled={true}
originWhitelist={['*']}
injectedJavaScript={injectedJavaScript}
onMessage={handleWebViewMessage}
incognito={false}
thirdPartyCookiesEnabled={true}
allowsInlineMediaPlayback={true}
androidLayerType="hardware"
/>
</View>
</View>
</Modal>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
paymentModal: {
backgroundColor: 'transparent',
borderRadius: 10,
width: 350,
height: 600,
overflow: 'visible',
position: 'relative',
...Platform.select({
ios: {
shadowColor: 'transparent',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0,
shadowRadius: 0,
},
android: {
elevation: 0,
},
}),
},
closeButton: {
position: 'absolute',
top: -15,
right: -15,
zIndex: 10,
backgroundColor: '#333',
width: 30,
height: 30,
borderRadius: 15,
alignItems: 'center',
justifyContent: 'center',
padding: 0,
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 4,
},
android: {
elevation: 4,
},
}),
},
closeButtonText: {
fontSize: 18,
fontWeight: 'bold',
color: 'white',
lineHeight: 18,
textAlign: 'center',
},
webView: {
flex: 1,
borderRadius: 8,
overflow: 'hidden',
backgroundColor: 'transparent',
opacity: 0.99, // Fix for black borders on Android
},
});
export default PhoenixPaymentNative;