Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { NativeStackScreenProps } from "@react-navigation/native-stack";
- import React, { useRef, useState } from "react";
- import { Linking, StyleSheet, View } from "react-native";
- import { Text } from "react-native-paper";
- import WebView from "react-native-webview";
- import i18n from "src/config/language";
- import { Store, useStore } from "src/store/store";
- import Screen from "../atoms/Screen";
- interface PaymentWebViewParams {
- paymentUrl?: string;
- amount?: number;
- onPaymentSuccess?: () => void;
- onPaymentError?: () => void;
- }
- const Options = {
- options: {
- methods: ["card"],
- methods_disabled: [],
- card_icons: ["mastercard", "visa"],
- fields: false,
- full_screen: false,
- button: true,
- hide_title: true,
- hide_link: true,
- email: false,
- theme: {
- type: "light",
- preset: "reset",
- },
- },
- params: {
- merchant_id: 1549901,
- required_rectoken: "y",
- currency: "GEL",
- amount: 500,
- },
- css_variable: {
- main: "#7d8ff8",
- card_bg: "#353535",
- card_shadow: "#9ADBE8",
- },
- };
- const html = `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Payment</title>
- <link rel="stylesheet" href="https://pay.fondy.eu/latest/checkout-vue/checkout.css">
- <style>
- html, body {
- height: 100%;
- margin: 0;
- padding: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
- }
- #checkout-container {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 16px;
- box-sizing: border-box;
- }
- </style>
- </head>
- <body>
- <div id="checkout-container"></div>
- <script src="https://pay.flitt.com/latest/checkout-vue/checkout.js"></script>
- <script>
- // Payment configuration
- const Options = ${JSON.stringify(Options)};
- // Initialize checkout when DOM is ready
- document.addEventListener('DOMContentLoaded', function() {
- if (typeof checkout === 'function') {
- checkout("#checkout-container", Options);
- } else {
- console.error('Checkout function not available');
- }
- });
- // Handle payment success/error callbacks
- window.addEventListener('message', function(event) {
- if (event.data.type === 'payment_success') {
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({
- type: 'payment_success',
- data: event.data
- }));
- } else if (event.data.type === 'payment_error') {
- window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({
- type: 'payment_error',
- data: event.data
- }));
- }
- });
- </script>
- </body>
- </html>
- `;
- export default function PaymentWebView({
- navigation,
- route,
- }: NativeStackScreenProps<any, "PaymentWebView">) {
- const { amount, onPaymentSuccess, onPaymentError } =
- route.params as PaymentWebViewParams & { amount?: number };
- const { setError, setMessage } = useStore((state: Store) => state);
- const webViewRef = useRef(null);
- const [loading, setLoading] = useState(true);
- // Generate dynamic HTML with the payment amount
- const generateHTML = () => {
- return html.replace("amount: 500", `amount: ${amount || 500}`);
- };
- const handleLoadStart = () => {
- setLoading(true);
- };
- const handleLoadEnd = () => {
- setLoading(false);
- };
- const handleError = (syntheticEvent: any) => {
- const { nativeEvent } = syntheticEvent;
- console.warn("WebView error: ", nativeEvent);
- setError(i18n.t("purchaseError"));
- navigation.goBack();
- };
- return (
- <Screen style={styles.container}>
- <View style={styles.webviewContainer}>
- <WebView
- ref={webViewRef}
- // source={{ uri: "https://codepen.io/flitt/pen/BaggpVw" }}
- source={{ html: generateHTML(), baseUrl: "https://google.com" }}
- style={styles.webview}
- onLoadStart={handleLoadStart}
- onLoadEnd={handleLoadEnd}
- onError={handleError}
- // onMessage={handleMessage}
- javaScriptEnabled={true}
- domStorageEnabled={true}
- startInLoadingState={true}
- scalesPageToFit={true}
- sharedCookiesEnabled
- thirdPartyCookiesEnabled
- allowsBackForwardNavigationGestures={true}
- injectedJavaScript={`(function() {
- const open = window.open;
- window.open = function(url) {
- window.ReactNativeWebView.postMessage(JSON.stringify({ t:'OPEN', url }));
- return null;
- };
- document.addEventListener('click', function(e){
- const a = e.target.closest('a[target="_blank"]');
- if (a && a.href) { e.preventDefault();
- window.ReactNativeWebView.postMessage(JSON.stringify({ t:'OPEN', url:a.href }));
- }
- }, true);
- })();
- true;`}
- setSupportMultipleWindows
- onCreateWindow={(e) => {
- Linking.openURL(e.nativeEvent.targetUrl);
- return false;
- }}
- onMessage={(e) => {
- try {
- const m = JSON.parse(e.nativeEvent.data);
- if (m.t === "OPEN" && m.url) Linking.openURL(m.url);
- } catch {}
- }}
- />
- </View>
- {loading && (
- <View style={styles.loadingContainer}>
- <Text style={styles.loadingText}>{i18n.t("loading")}</Text>
- </View>
- )}
- </Screen>
- );
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- header: {
- padding: 16,
- borderBottomWidth: 1,
- borderBottomColor: "#E5E5E5",
- backgroundColor: "#FFFFFF",
- },
- headerText: {
- fontSize: 18,
- fontWeight: "600",
- color: "#20232B",
- textAlign: "center",
- },
- webviewContainer: {
- flex: 1,
- },
- webview: {
- flex: 1,
- },
- loadingContainer: {
- position: "absolute",
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- justifyContent: "center",
- alignItems: "center",
- backgroundColor: "rgba(255, 255, 255, 0.8)",
- },
- loadingText: {
- fontSize: 16,
- color: "#636B74",
- },
- });
Advertisement
Add Comment
Please, Sign In to add comment