import React, { useState, useEffect } from "react"; import { View, Text, TouchableOpacity, StyleSheet, ScrollView, Image, Alert, ActivityIndicator, StatusBar, SafeAreaView, } from "react-native"; import { payApi, PaymentMethodsResponse } from "../../services/api/payApi"; import fontSize from "../../utils/fontsizeUtils"; import BackIcon from "../../components/BackIcon"; import { useNavigation, NavigationProp } from "@react-navigation/native"; import widthUtils from "../../utils/widthUtils"; import useOrderStore from "../../store/order"; import useCreateOrderStore from "../../store/createOrder"; import { useRoute, RouteProp } from "@react-navigation/native"; import useUserStore from "../../store/user"; import { createOrderDataType } from "../../types/createOrder"; import useBurialPointStore from "../../store/burialPoint"; import { getBurialPointData } from "../../store/burialPoint"; import { ordersApi, OrderData, CreateOrderRequest, Order, } from "../../services/api/orders"; import { useTranslation } from "react-i18next"; // Define route params type type PaymentMethodRouteParams = { freight_forwarder_address_id?: number; }; // Define the root navigation params type RootStackParamList = { PreviewOrder: { data: Order; payMethod: string; currency: string; amount: number; }; Pay: { order_id: string }; ShippingFee: { freight_forwarder_address_id?: number }; PaymentMethod: { freight_forwarder_address_id?: number }; PreviewAddress: undefined; AddressList: undefined; // Add other routes as needed }; interface PaymentOption { id: string; label: string; icon: string; value?: string | string[]; } interface PaymentTab { id: string; label: string; options: PaymentOption[]; } const PaymentMethodItem = ({ option, isSelected, onSelect, selectedCurrency, onSelectCurrency, exchangeRates, totalAmount, convertedAmount, isConverting, }: { option: PaymentOption; isSelected: boolean; onSelect: () => void; selectedCurrency?: string; onSelectCurrency?: (currency: string) => void; exchangeRates?: { usd: number; eur: number; }; totalAmount?: number; convertedAmount?: { converted_amount: number; item_key: string; original_amount: number; }[]; isConverting?: boolean; }) => { const { t } = useTranslation(); return ( {option.icon} {option.label} {Array.isArray(option.value) && option.value.length > 0 && ( {option.value.map((op: string) => ( {op} ))} )} {/* Show currency selector directly under PayPal when selected */} {isSelected && option.label === "Paypal" && selectedCurrency && onSelectCurrency && exchangeRates && totalAmount && ( )} ); }; // Currency selector component interface CurrencySelectorProps { selectedCurrency: string; onSelectCurrency: (currency: string) => void; exchangeRates: { usd: number; eur: number; }; totalAmount: number; convertedAmount?: { converted_amount: number; item_key: string; original_amount: number; }[]; isConverting?: boolean; } const CurrencySelector = ({ selectedCurrency, onSelectCurrency, exchangeRates, totalAmount, convertedAmount = [], isConverting = false, }: CurrencySelectorProps) => { const { t } = useTranslation(); return ( {t("payment.select_currency")} onSelectCurrency("USD")} > USD onSelectCurrency("EUR")} > EUR {!isConverting && ( {selectedCurrency === "USD" ? "$" : "€"} {convertedAmount .reduce((acc, item) => acc + item.converted_amount, 0) .toFixed(2)} )} {isConverting && ( )} ); }; export const PaymentMethod = () => { const { t } = useTranslation(); const [tabs, setTabs] = useState([ { id: "online", label: t("order.payment.online"), options: [], }, { id: "offline", label: t("order.payment.offline"), options: [], }, ]); const [currentTab, setCurrentTab] = useState("online"); const [paymentMethods, setPaymentMethods] = useState(); const [selectedPayment, setSelectedPayment] = useState(null); const navigation = useNavigation>(); const route = useRoute, string>>(); const [expanded, setExpanded] = useState(false); const order = useOrderStore((state) => state.order); const [previewOrder, setPreviewOrder] = useState(); const [loading, setLoading] = useState(false); const { user } = useUserStore(); const [createOrderData, setCreateOrderData] = useState(); const { items, orderData, setOrderData, resetOrder } = useCreateOrderStore(); const [selectedCurrency, setSelectedCurrency] = useState("USD"); const [convertedAmount, setConvertedAmount] = useState< { converted_amount: number; item_key: string; original_amount: number }[] >([]); const [isConverting, setIsConverting] = useState(false); const [createLoading, setCreateLoading] = useState(false); const [exchangeRates] = useState({ usd: 580.0, eur: 655.96, }); const [totalAmount, setTotalAmount] = useState(121.97); const { logPaymentConfirm } = useBurialPointStore(); const toggleExpanded = () => { setExpanded(!expanded); }; const onSelectPayment = (paymentId: string) => { if (paymentId === "Paypal") { setIsConverting(true); const data = { from_currency: user.currency, to_currency: selectedCurrency, amounts: { total_amount: previewOrder?.total_amount || 0, domestic_shipping_fee: createOrderData?.domestic_shipping_fee || 0, shipping_fee: createOrderData?.shipping_fee || 0, }, }; payApi .convertCurrency(data) .then((res) => { setConvertedAmount(res.converted_amounts_list); setIsConverting(false); }) .catch((error) => { console.error("Currency conversion failed:", error); setIsConverting(false); }); } setSelectedPayment(paymentId); }; const onSelectCurrency = (currency: string) => { setSelectedCurrency(currency); setIsConverting(true); const data = { from_currency: user.currency, to_currency: currency, amounts: { total_amount: previewOrder?.total_amount || 0, domestic_shipping_fee: createOrderData?.domestic_shipping_fee || 0, shipping_fee: createOrderData?.shipping_fee || 0, }, }; payApi .convertCurrency(data) .then((res) => { setConvertedAmount(res.converted_amounts_list); setIsConverting(false); }) .catch((error) => { console.error("Currency conversion failed:", error); setIsConverting(false); }); }; const getPaymentMethods = async () => { try { const response = await payApi.getCountryPaymentMethods(); console.log(response); setPaymentMethods(response); // 设置默认支付方式选项 setTabs([ { id: "online", label: t("order.payment.online"), options: response.current_country_methods.map((method) => ({ id: method.key, label: method.key, icon: getPaymentIcon(method.key), value: method.value, })), }, { id: "offline", label: t("order.payment.offline"), options: [], }, ]); } catch (error) { console.error("Failed to get payment methods:", error); } }; const getPaymentIcon = (key: string): string => { switch (key) { case "Brainnel Pay(Mobile Money)": return "💳"; case "Wave": return "💸"; case "Paypal": return "🅿️"; case "Bank Card Payment": return "💳"; default: return "💰"; } }; useEffect(() => { getPaymentMethods(); }, []); useEffect(() => { setLoading(true); if (route.params?.freight_forwarder_address_id) { const data = { country_code: route.params.freight_forwarder_address_id, items: items, }; ordersApi .getOrders(data) .then((res) => { setPreviewOrder(res); setLoading(false); }) .catch(() => { setLoading(false); Alert.alert("Error", "Failed to get preview order"); }); } }, [route.params?.freight_forwarder_address_id]); useEffect(() => { setCreateOrderData({ ...orderData, address_id: orderData.address_id, domestic_shipping_fee: orderData.domestic_shipping_fee, shipping_fee: orderData.shipping_fee, transport_type: orderData.transport_type, currency: user.currency, }); console.log("orderData", orderData); }, [orderData]); const handleSubmit = async () => { if (!selectedPayment) { Alert.alert(t("payment.select_payment")); return; } const items = previewOrder?.items.map((item) => ({ offer_id: String(item.offer_id), cart_item_id: item.cart_item_id, sku_id: String(item.sku_id), product_name: item.product_name, product_name_en: item.product_name_en, product_name_ar: item.product_name_ar, product_name_fr: item.product_name_fr, sku_attributes: item.attributes.map((attr) => ({ attribute_name: attr.attribute_name, attribute_value: attr.value, })), sku_image: item.sku_image_url, quantity: item.quantity, unit_price: item.unit_price, total_price: item.total_price, })) || []; if (createOrderData) { createOrderData.items = items; createOrderData.payment_method = selectedPayment; createOrderData.total_amount = selectedPayment === "Paypal" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : Number( ( (previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) + (orderData?.shipping_fee || 0) ).toFixed(2) ); createOrderData.actual_amount = selectedPayment === "Paypal" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : Number( ( (previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) + (orderData?.shipping_fee || 0) ).toFixed(2) ); createOrderData.currency = selectedPayment === "Paypal" ? selectedCurrency : user.currency; createOrderData.domestic_shipping_fee = selectedPayment === "Paypal" ? convertedAmount.find( (item) => item.item_key === "domestic_shipping_fee" )?.converted_amount || 0 : orderData?.domestic_shipping_fee; createOrderData.shipping_fee = selectedPayment === "Paypal" ? convertedAmount.find( (item) => item.item_key === "shipping_fee" )?.converted_amount || 0 : orderData?.shipping_fee; } setOrderData(createOrderData || {}); const data = { pay_method: selectedPayment, offline_payment: currentTab === "offline" ? 0 : 1, all_price: selectedPayment === "Paypal" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : Number( ( (previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) + (orderData?.shipping_fee || 0) ).toFixed(2) ), all_quantity: previewOrder?.items?.reduce( (acc, item) => acc + item.quantity, 0 ), currency: selectedCurrency, shipping_method: orderData?.transport_type || 0, shipping_price_outside: orderData?.shipping_fee || 0, shipping_price_within: orderData?.domestic_shipping_fee || 0, timestamp: new Date().toISOString(), pay_product: JSON.stringify( previewOrder?.items.map((item) => { return { offer_id: item.offer_id, price: item.unit_price, all_price: convertedAmount.find((item) => item.item_key === "total_amount") ?.converted_amount || 0, currency: previewOrder.currency, sku: item.attributes.map((sku) => { return { sku_id: item.sku_id, value: sku.value, }; }), quantity: item.quantity, product_name: item.product_name, timestamp: new Date(), product_img: item.sku_image_url, }; }) ), }; setCreateLoading(true); ordersApi .createOrder(createOrderData as unknown as CreateOrderRequest) .then((res) => { setCreateLoading(false); logPaymentConfirm(data); // go to payment preview navigation.navigate("PreviewOrder", { data: res, payMethod: selectedPayment, currency: selectedPayment === "Paypal" ? selectedCurrency : user.currency, amount: selectedPayment === "Paypal" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : Number( ( (previewOrder?.total_amount || 0) + (createOrderData?.domestic_shipping_fee || 0) + (createOrderData?.shipping_fee || 0) ).toFixed(2) ), }); }) .catch((error) => { setCreateLoading(false); console.error("Error creating order:", error); Alert.alert("Error", "Failed to create order"); }); }; return ( navigation.goBack()}> {t("payment.select_payment")} {loading ? ( ) : ( 💳 {t("order.select_payment")} {tabs.map((tab) => ( setCurrentTab(tab.id)} > {tab.label} ))} {tabs .find((tab) => tab.id === currentTab) ?.options.map((option) => ( onSelectPayment(option.id)} selectedCurrency={selectedCurrency} onSelectCurrency={onSelectCurrency} exchangeRates={exchangeRates} totalAmount={totalAmount} convertedAmount={convertedAmount} isConverting={isConverting} /> ))} 📦 {t("payment.order_summary")} {t("payment.product_total")}({previewOrder?.items?.length || 0} items) {expanded ? t("payment.hide_details") : t("payment.view_details")} {previewOrder?.items?.map((item) => ( {item.sku_image_url ? ( ) : ( )} {item.product_name} {item.sku_attributes?.map((attribute) => ( {attribute?.attribute_name}:{" "} {attribute?.attribute_value} ))} {t("payment.qty")}: {item.quantity} ${item?.total_price} ))} {t("payment.product_total")} {selectedPayment === "Paypal" ? convertedAmount.find( (item) => item.item_key === "total_amount" )?.converted_amount || 0 : previewOrder?.total_amount || 0}{" "} {selectedPayment === "Paypal" ? selectedCurrency === "USD" ? "USD" : "EUR" : previewOrder?.currency} {t("payment.domestic_shipping")} {selectedPayment === "Paypal" ? convertedAmount.find( (item) => item.item_key === "domestic_shipping_fee" )?.converted_amount || 0 : orderData?.domestic_shipping_fee || 0}{" "} {selectedPayment === "Paypal" ? selectedCurrency === "USD" ? "USD" : "EUR" : previewOrder?.currency} {t("payment.international_shipping")} {selectedPayment === "Paypal" ? convertedAmount.find( (item) => item.item_key === "shipping_fee" )?.converted_amount || 0 : orderData?.shipping_fee || 0}{" "} {selectedPayment === "Paypal" ? selectedCurrency === "USD" ? "USD" : "EUR" : previewOrder?.currency} {/* 实际支付金额 */} {t("payment.total")} {selectedPayment === "Paypal" && selectedCurrency !== user.currency && ( {( (previewOrder?.total_amount || 0) + (createOrderData?.domestic_shipping_fee || 0) + (createOrderData?.shipping_fee || 0) ).toFixed(2)}{" "} {previewOrder?.currency} {convertedAmount .reduce( (acc, item) => acc + item.converted_amount, 0 ) .toFixed(2)} {selectedCurrency === "USD" ? "USD" : "EUR"} )} {selectedPayment === "Paypal" && selectedCurrency === user.currency && ( {convertedAmount .reduce( (acc, item) => acc + item.converted_amount, 0 ) .toFixed(2)} {selectedCurrency === "USD" ? "USD" : "EUR"} )} {selectedPayment !== "Paypal" && ( {( (previewOrder?.total_amount || 0) + (createOrderData?.domestic_shipping_fee || 0) + (createOrderData?.shipping_fee || 0) ).toFixed(2)}{" "} {previewOrder?.currency} )} )} {createLoading ? ( ) : isConverting ? ( {t("payment.converting")} ) : ( {t("payment.submit_order")} )} ); }; const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: "#fff", }, safeAreaContent: { flex: 1, paddingTop: 0, }, container: { flex: 1, backgroundColor: "#fff", }, sectionHeader: { flexDirection: "row", alignItems: "center", marginBottom: 15, paddingHorizontal: 15, }, sectionIcon: { fontSize: fontSize(20), marginRight: 8, }, sectionTitle: { fontSize: fontSize(18), fontWeight: "600", color: "#000", }, tabContainer: { flexDirection: "row", marginBottom: 15, borderBottomWidth: 1, borderBottomColor: "#EEEEEE", paddingHorizontal: 15, }, tabButton: { paddingVertical: 10, paddingHorizontal: 15, marginRight: 10, }, tabButtonActive: { borderBottomWidth: 2, borderBottomColor: "#FF5100", }, tabText: { fontSize: fontSize(16), color: "#666", }, tabTextActive: { color: "#FF5100", fontWeight: "500", }, paymentOptions: { marginBottom: 15, paddingHorizontal: 15, }, paymentOption: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", padding: 15, backgroundColor: "#F8F8F8", borderRadius: 8, marginBottom: 10, }, paymentSelected: { backgroundColor: "#FFF0E8", borderWidth: 1, borderColor: "#FF5100", }, paymentContent: { flex: 1, }, defaultPaymentContainer: { flexDirection: "row", alignItems: "center", }, paymentIcon: { fontSize: fontSize(24), marginRight: 8, }, paymentLabel: { fontSize: fontSize(16), fontWeight: "500", }, operatorContainer: { flexDirection: "row", flexWrap: "wrap", marginTop: 8, }, operatorBox: { backgroundColor: "#fff", paddingVertical: 4, paddingHorizontal: 8, borderRadius: 4, marginRight: 8, marginBottom: 4, }, operatorText: { fontSize: fontSize(12), color: "#666", }, radioButton: { width: 20, height: 20, borderRadius: 10, borderWidth: 1, borderColor: "#CCCCCC", justifyContent: "center", alignItems: "center", }, radioInner: { width: 12, height: 12, borderRadius: 6, backgroundColor: "transparent", }, radioInnerSelected: { backgroundColor: "#FF5100", }, titleContainer: { width: "100%", padding: 15, flexDirection: "row", alignItems: "center", justifyContent: "center", position: "relative", backgroundColor: "#fff", }, backIconContainer: { position: "absolute", left: 15, backgroundColor: "#fff", }, titleHeading: { fontWeight: "600", fontSize: fontSize(18), lineHeight: 22, fontFamily: "PingFang SC", color: "black", }, // Order Summary Styles section: { backgroundColor: "#fff", borderRadius: 8, paddingHorizontal: 15, marginTop: 15, }, section1: { backgroundColor: "#fff", borderRadius: 8, overflow: "hidden", }, sectionHeader1: { flexDirection: "row", alignItems: "center", paddingTop: 12, paddingBottom: 12, borderBottomWidth: 1, borderBottomColor: "#f5f5f5", }, sectionIcon1: { fontSize: fontSize(18), marginRight: 10, color: "#666", }, sectionTitle1: { fontSize: fontSize(15), fontWeight: "500", flex: 1, }, setOrderContent: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingTop: 12, paddingBottom: 12, paddingHorizontal: 12, }, sectionAction: { color: "#ff6000", fontSize: fontSize(13), fontWeight: "500", }, noCouponsMessage: { color: "#888", fontSize: fontSize(13), }, orderItems: { maxHeight: 0, overflow: "hidden", }, orderItemsExpanded: { maxHeight: 1000, // Arbitrary large number to accommodate all items }, orderItem: { flexDirection: "row", padding: 16, borderBottomWidth: 1, borderBottomColor: "#f5f5f5", }, itemImage: { width: widthUtils(70, 70).width, height: widthUtils(70, 70).height, borderRadius: 6, marginRight: 12, borderWidth: 1, borderColor: "#eee", }, itemImagePlaceholder: { width: widthUtils(70, 70).width, height: widthUtils(70, 70).height, borderRadius: 6, marginRight: 12, borderWidth: 1, borderColor: "#eee", backgroundColor: "#f1f1f1", }, itemDetails: { flex: 1, }, itemName: { fontSize: fontSize(14), lineHeight: 18, }, itemVariant: { fontSize: fontSize(12), color: "#666", backgroundColor: "#f7f7f7", paddingVertical: 3, paddingHorizontal: 6, borderRadius: 4, marginTop: 6, alignSelf: "flex-start", }, itemQuantity: { fontSize: fontSize(12), color: "#666", marginTop: 4, }, itemPrices: { alignItems: "flex-end", fontSize: fontSize(13), color: "#555", }, itemPrice: { fontWeight: "600", color: "#ff6000", fontSize: fontSize(15), marginBottom: 5, }, priceBox: { borderRadius: 10, marginTop: 15, paddingHorizontal: 15, }, priceBox1: { justifyContent: "space-between", flexDirection: "row", alignItems: "center", padding: 12, borderBottomWidth: 1, borderBottomColor: "#f5f5f5", }, actualPaymentBox: { padding: 12, borderRadius: 6, backgroundColor: "#fff8f4", marginTop: 15, marginHorizontal: 15, marginBottom: 20, }, actualPaymentBox1: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#fff", }, submitButtonContainer: { paddingRight: 11, paddingLeft: 11, marginTop: 20, marginBottom: 20, }, primaryButtonStyle: { width: "100%", height: 50, justifyContent: "center", alignItems: "center", fontWeight: "600", fontSize: fontSize(16), lineHeight: 22, fontFamily: "PingFang SC", color: "white", backgroundColor: "#002fa7", borderWidth: 0, borderRadius: 25, }, buttonText: { color: "white", fontWeight: "600", fontSize: fontSize(16), lineHeight: 22, fontFamily: "PingFang SC", }, selectedCountryText: { padding: 0, margin: 0, fontWeight: "500", fontSize: fontSize(16), lineHeight: 22, fontFamily: "PingFang SC", color: "#646472", }, disabledButtonStyle: { backgroundColor: "#ccc", }, currencySelectorContainer: { padding: 15, backgroundColor: "#f9f9f9", borderRadius: 8, marginTop: 5, marginBottom: 15, }, currencySelectorTitle: { fontSize: fontSize(16), fontWeight: "600", color: "#000", marginBottom: 15, }, currencyOptions: { flexDirection: "row", marginBottom: 15, }, currencyOption: { flex: 1, padding: 15, borderWidth: 1, borderColor: "#DDDDDD", borderRadius: 4, marginRight: 10, alignItems: "center", justifyContent: "center", }, selectedCurrencyOption: { borderColor: "#002fa7", backgroundColor: "#fff", }, currencyText: { fontSize: fontSize(16), fontWeight: "500", color: "#000", }, exchangeRateContainer: { marginBottom: 15, }, exchangeRateText: { fontSize: fontSize(14), color: "#666", marginBottom: 5, }, totalContainer: { marginTop: 10, borderTopWidth: 1, borderTopColor: "#EEEEEE", paddingTop: 10, flexDirection: "row", alignItems: "center", }, totalText: { fontSize: fontSize(16), fontWeight: "600", color: "#ff6000", }, loadingIndicator: { marginLeft: 10, }, header: { flexDirection: "row", alignItems: "center", justifyContent: "center", padding: 10, position: "relative", }, backButton: { padding: 5, position: "absolute", left: 10, zIndex: 1, }, headerTitle: { fontSize: fontSize(20), fontWeight: "600", textAlign: "center", }, paymentContainer: { padding: 15, }, tabs: { flexDirection: "row", marginBottom: 15, }, tab: { paddingVertical: 10, paddingHorizontal: 15, marginRight: 10, }, tabActive: { borderBottomWidth: 2, borderBottomColor: "#FF5100", }, bottomBar: { padding: 15, borderTopWidth: 1, borderTopColor: "#f5f5f5", }, submitButton: { width: "100%", height: 50, justifyContent: "center", alignItems: "center", backgroundColor: "#FF5100", borderRadius: 25, }, submitButtonText: { color: "white", fontSize: fontSize(16), fontWeight: "600", }, disabledButton: { backgroundColor: '#ccc', }, scrollContent: { flex: 1, }, mainContent: { flex: 1, }, sectionContainer: { padding: 15, }, sectionHeaderBottom: { flexDirection: "row", alignItems: "center", marginBottom: 15, }, sectionIconBottom: { fontSize: fontSize(20), marginRight: 8, }, sectionTitleBottom: { fontSize: fontSize(18), fontWeight: "600", color: "#000", }, tabsContainer: { flexDirection: "row", marginBottom: 15, }, tabBottom: { paddingVertical: 10, paddingHorizontal: 15, marginRight: 10, }, activeTab: { borderBottomWidth: 2, borderBottomColor: "#FF5100", }, activeTabText: { color: "#FF5100", fontWeight: "500", }, tabContent: { marginBottom: 15, }, });