import React, { useState, useEffect } from "react";
import {
View,
Text,
TouchableOpacity,
StyleSheet,
ScrollView,
Image,
Alert,
ActivityIndicator,
} 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 {
ordersApi,
OrderData, CreateOrderRequest,
} from "../../services/api/orders";
// Define route params type
type PaymentMethodRouteParams = {
freight_forwarder_address_id?: number;
};
// Define the root navigation params
type RootStackParamList = {
PreviewOrder: undefined;
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?: number;
isConverting?: boolean;
}) => (
{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?: number;
isConverting?: boolean;
}
const CurrencySelector = ({
selectedCurrency,
onSelectCurrency,
exchangeRates,
totalAmount,
convertedAmount = 0,
isConverting = false,
}: CurrencySelectorProps) => (
Select Currency
onSelectCurrency("USD")}
>
USD
onSelectCurrency("EUR")}
>
EUR
{!isConverting && (
{selectedCurrency === "USD" ? "$" : "€"}{convertedAmount}
)}
{isConverting && (
)}
);
export const PaymentMethod = () => {
const [tabs, setTabs] = useState([
{
id: "online",
label: "Online Payment",
options: [],
},
{
id: "offline",
label: "Offline Payment",
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 } = useCreateOrderStore();
const [selectedCurrency, setSelectedCurrency] = useState("USD");
const [convertedAmount, setConvertedAmount] = useState(0);
const [isConverting, setIsConverting] = useState(false);
const [exchangeRates] = useState({
usd: 580.00,
eur: 655.96
});
const [totalAmount, setTotalAmount] = useState(121.97);
const toggleExpanded = () => {
setExpanded(!expanded);
};
const onSelectPayment = (paymentId: string) => {
if(paymentId === "Paypal"){
setIsConverting(true);
payApi.convertCurrency({
from_currency: user.currency,
to_currency: selectedCurrency,
amount: (
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
),
}).then((res) => {
setConvertedAmount(res.converted_amount);
setIsConverting(false);
}).catch(error => {
console.error("Currency conversion failed:", error);
setIsConverting(false);
});
}
setSelectedPayment(paymentId);
};
const onSelectCurrency = (currency: string) => {
setSelectedCurrency(currency);
// Call the API to convert the currency
setIsConverting(true);
payApi.convertCurrency({
from_currency: user.currency,
to_currency: currency,
amount: (
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
),
}).then((res) => {
setConvertedAmount(res.converted_amount);
setIsConverting(false);
}).catch(error => {
console.error("Currency conversion failed:", error);
setIsConverting(false);
});
};
const getPaymentMethods = async () => {
try {
const response = await payApi.getCountryPaymentMethods();
setPaymentMethods(response);
// 设置默认支付方式选项
setTabs([
{
id: "online",
label: "Online Payment",
options: response.current_country_methods.map((method) => ({
id: method.key,
label: method.key,
icon: getPaymentIcon(method.key),
value: method.value,
})),
},
{
id: "offline",
label: "Offline Payment",
options: [],
},
]);
} catch (error) {
console.error("获取支付方式失败:", 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("请选择支付方式");
return;
}
const items =
previewOrder?.items.map((item) => ({
offer_id: item.offer_id,
cart_item_id: item.cart_item_id,
sku_id: 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 :
Number(((previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0)
+ (orderData?.shipping_fee || 0)).toFixed(2));
createOrderData.actual_amount = Number((previewOrder?.total_amount || 0).toFixed(2));
createOrderData.currency = selectedPayment === 'Paypal' ? selectedCurrency : user.currency;
}
setOrderData(createOrderData || {});
const res = await ordersApi.createOrder(createOrderData as CreateOrderRequest)
console.log(res)
navigation.navigate("PreviewOrder");
};
return (
navigation.goBack()}>
Payment Method
{loading ? (
) : (
💳
Payment Method
{/* 选项卡 */}
{tabs.map((tab) => (
{
console.log(tab.id);
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}
/>
))}
{/* Order Summary Section */}
📦
Order Summary
Products({previewOrder?.items?.length || 0} items)
{expanded ? "Hide Details" : "View Details"}
{previewOrder?.items?.map((item) => (
{item.sku_image_url ? (
) : (
)}
{item.product_name}
{item.sku_attributes?.map((attribute) => (
{attribute?.attribute_name}:{" "}
{attribute?.attribute_value}
))}
Qty: {item.quantity}
${item?.total_price}
))}
商品总价
{previewOrder?.total_amount || 0} {previewOrder?.currency}
中国运费
{createOrderData?.domestic_shipping_fee || 0}{" "}
{previewOrder?.currency}
预计国际运费
{createOrderData?.shipping_fee || 0} {previewOrder?.currency}
{/* 实际支付金额 */}
Total
{
selectedPayment === 'Paypal' && selectedCurrency !== user.currency && (
{(
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
).toFixed(2)}{" "}
{previewOrder?.currency}
{convertedAmount}{selectedCurrency === "USD" ? "USD" : "EUR"}
)
}
{
selectedPayment === 'Paypal' && selectedCurrency === user.currency && (
{(
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
).toFixed(2)}{" "}
{previewOrder?.currency}
)
}
{
selectedPayment !== 'Paypal'&& (
{(
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
).toFixed(2)}{" "}
{previewOrder?.currency}
)
}
创建订单
)}
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
marginTop: 10,
},
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: 20,
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: 16,
lineHeight: 22,
fontFamily: "PingFang SC",
color: "white",
backgroundColor: "#002fa7",
borderWidth: 0,
borderRadius: 25,
},
buttonText: {
color: "white",
fontWeight: "600",
fontSize: 16,
lineHeight: 22,
fontFamily: "PingFang SC",
},
selectedCountryText: {
padding: 0,
margin: 0,
fontWeight: "500",
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,
},
});