From 2abf8c230a17f9dc3adbb3dfc3706f23f383c483 Mon Sep 17 00:00:00 2001 From: unknown <2871013501@qq.com> Date: Sun, 25 May 2025 22:00:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20-=20=E6=B7=BB=E5=8A=A0=E5=9B=BD=E5=AE=B6?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=92=8C=E7=94=B5=E8=AF=9D=E5=8F=B7=E7=A0=81?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BalanceScreen/PhoneNumberInputModal.tsx | 17 +- app/screens/BalanceScreen/RechargeScreen.tsx | 9 +- app/screens/previewOrder/PaymentMethod.tsx | 204 +++++++++++- app/screens/previewOrder/perviewOrder.tsx | 306 +++++++++++++++--- app/screens/productStatus/OrderDatails.tsx | 101 +++++- 5 files changed, 581 insertions(+), 56 deletions(-) diff --git a/app/screens/BalanceScreen/PhoneNumberInputModal.tsx b/app/screens/BalanceScreen/PhoneNumberInputModal.tsx index 512a812..e7fbe31 100644 --- a/app/screens/BalanceScreen/PhoneNumberInputModal.tsx +++ b/app/screens/BalanceScreen/PhoneNumberInputModal.tsx @@ -131,7 +131,18 @@ const PhoneNumberInputModal = ({ - {paymentParams?.currency !== "FCFA" && ( + {paymentParams?.payment_method === "wave" && ( + + + Montant converti: + + + {paymentParams?.amount.toFixed(2)} FCFA + + + )} + + {paymentParams?.currency !== "FCFA" && paymentParams?.payment_method !== "wave" && ( {t('balance.phone_modal.converted_amount')} @@ -212,7 +223,9 @@ const PhoneNumberInputModal = ({ ) : ( {t('balance.phone_modal.pay')}{" "} - {paymentParams?.currency === "FCFA" + {paymentParams?.payment_method === "wave" + ? paymentParams.amount.toFixed(2) + " FCFA" + : paymentParams?.currency === "FCFA" ? paymentParams.originalAmount.toLocaleString() + " " + paymentParams.currency diff --git a/app/screens/BalanceScreen/RechargeScreen.tsx b/app/screens/BalanceScreen/RechargeScreen.tsx index 2905e11..4d80db3 100644 --- a/app/screens/BalanceScreen/RechargeScreen.tsx +++ b/app/screens/BalanceScreen/RechargeScreen.tsx @@ -273,8 +273,8 @@ const RechargeScreen = ({ onClose }: RechargeScreenProps) => { // 如果没有转换结果,使用原始金额作为备用 params.amount = parseFloat(selectedPrice.replace(/,/g, "")); } - // 更新显示标签为FCFA - params.selectedPriceLabel = params.amount + " FCFA"; + // selectedPriceLabel 保持显示原始美元金额 + // params.selectedPriceLabel 已经在上面设置为原始金额,不需要修改 } } else if (selectedOperator === "balance") { params.payment_method = "Balance"; @@ -296,6 +296,9 @@ const RechargeScreen = ({ onClose }: RechargeScreenProps) => { // 保存支付参数 setPaymentParams(params); + + console.log(params); + setShowPhoneModal(true); } }; @@ -914,7 +917,7 @@ const RechargeScreen = ({ onClose }: RechargeScreenProps) => { (item) => item.item_key === "total_amount" ) ?.converted_amount.toFixed(2)}{" "} - FCFA + {currentCurrency} ) : null} diff --git a/app/screens/previewOrder/PaymentMethod.tsx b/app/screens/previewOrder/PaymentMethod.tsx index fa1214c..b18a725 100644 --- a/app/screens/previewOrder/PaymentMethod.tsx +++ b/app/screens/previewOrder/PaymentMethod.tsx @@ -77,6 +77,7 @@ const PaymentMethodItem = ({ convertedAmount, isConverting, isPaypalExpanded, + isWaveExpanded, }: { option: PaymentOption; isSelected: boolean; @@ -95,6 +96,7 @@ const PaymentMethodItem = ({ }[]; isConverting?: boolean; isPaypalExpanded?: boolean; + isWaveExpanded?: boolean; }) => { const { t } = useTranslation(); const { user } = useUserStore(); @@ -231,6 +233,60 @@ const PaymentMethodItem = ({ )} + + {/* Show Wave expanded view */} + {isSelected && + option.key === "wave" && + isWaveExpanded && + convertedAmount && + convertedAmount.length > 0 && ( + + + + {t("order.select_currency") || "Select Currency"} + + + + + FCFA + + + + + {/* Display converted amount */} + {isConverting ? ( + + + + {t("order.converting") || "Converting..."} + + + ) : ( + + + {t("order.equivalent_amount") || "Equivalent Amount:"} + + + {convertedAmount + .reduce((acc, item) => acc + item.converted_amount, 0) + .toFixed(2)}{" "} + FCFA + + + )} + + + )} ); }; @@ -275,15 +331,22 @@ export const PaymentMethod = () => { }); const [totalAmount, setTotalAmount] = useState(121.97); const { logPaymentConfirm } = useBurialPointStore(); + const [isWaveExpanded, setIsWaveExpanded] = useState(false); + const toggleExpanded = () => { setIsPaypalExpanded(!isPaypalExpanded); }; + const onSelectPayment = (paymentId: string) => { if (paymentId === selectedPayment) { // If clicking on already selected paypal, toggle expansion if (paymentId === "paypal") { setIsPaypalExpanded(!isPaypalExpanded); } + // If clicking on already selected wave, toggle expansion + if (paymentId === "wave") { + setIsWaveExpanded(!isWaveExpanded); + } return; } @@ -292,11 +355,43 @@ export const PaymentMethod = () => { // Auto-expand paypal when selecting it if (paymentId === "paypal") { setIsPaypalExpanded(true); + setIsWaveExpanded(false); + setIsConverting(true); + + // Reset to USD when selecting PayPal + setSelectedCurrency("USD"); + + const data = { + from_currency: user.currency, + to_currency: "USD", + 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); + }); + } else if (paymentId === "wave") { + // Auto-expand wave when selecting it + setIsWaveExpanded(true); + setIsPaypalExpanded(false); setIsConverting(true); + setSelectedCurrency("FCFA"); + const data = { from_currency: user.currency, - to_currency: selectedCurrency, + to_currency: "FCFA", amounts: { total_amount: previewOrder?.total_amount || 0, domestic_shipping_fee: createOrderData?.domestic_shipping_fee || 0, @@ -315,10 +410,12 @@ export const PaymentMethod = () => { setIsConverting(false); }); } else { - // Close expansion for non-paypal options + // Close expansion for non-paypal and non-wave options setIsPaypalExpanded(false); + setIsWaveExpanded(false); } }; + const onSelectCurrency = (currency: string) => { setSelectedCurrency(currency); setIsConverting(true); @@ -342,6 +439,7 @@ export const PaymentMethod = () => { setIsConverting(false); }); }; + const getPaymentMethods = async () => { try { setLoading(true); @@ -386,6 +484,7 @@ export const PaymentMethod = () => { setLoading(false); } }; + const getPaymentIcon = (key: string): string => { switch (key) { case "Brainnel Pay(Mobile Money)": @@ -400,9 +499,11 @@ export const PaymentMethod = () => { return "💰"; } }; + useEffect(() => { getPaymentMethods(); }, []); + useEffect(() => { setLoading(true); if (route.params?.freight_forwarder_address_id) { @@ -422,6 +523,7 @@ export const PaymentMethod = () => { }); } }, [route.params?.freight_forwarder_address_id]); + useEffect(() => { setCreateOrderData({ ...orderData, @@ -433,6 +535,7 @@ export const PaymentMethod = () => { }); console.log("orderData", orderData); }, [orderData]); + const handleSubmit = async () => { if (!selectedPayment) { Alert.alert(t("payment.select_payment")); @@ -461,6 +564,11 @@ export const PaymentMethod = () => { createOrderData.payment_method = selectedPayment; createOrderData.total_amount = selectedPayment === "paypal" + ? convertedAmount.reduce( + (acc, item) => acc + item.converted_amount, + 0 + ) + : selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 @@ -474,6 +582,11 @@ export const PaymentMethod = () => { ); createOrderData.actual_amount = selectedPayment === "paypal" + ? convertedAmount.reduce( + (acc, item) => acc + item.converted_amount, + 0 + ) + : selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 @@ -486,15 +599,22 @@ export const PaymentMethod = () => { ).toFixed(2) ); createOrderData.currency = - selectedPayment === "paypal" ? selectedCurrency : user.currency; + selectedPayment === "paypal" ? selectedCurrency : selectedPayment === "wave" ? "FCFA" : user.currency; createOrderData.domestic_shipping_fee = selectedPayment === "paypal" + ? convertedAmount.find( + (item) => item.item_key === "domestic_shipping_fee" + )?.converted_amount || 0 + : selectedPayment === "wave" ? 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 + : selectedPayment === "wave" ? convertedAmount.find((item) => item.item_key === "shipping_fee") ?.converted_amount || 0 : orderData?.shipping_fee; @@ -505,6 +625,11 @@ export const PaymentMethod = () => { offline_payment: currentTab === "offline" ? 0 : 1, all_price: selectedPayment === "paypal" + ? convertedAmount.reduce( + (acc, item) => acc + item.converted_amount, + 0 + ) + : selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 @@ -520,7 +645,7 @@ export const PaymentMethod = () => { (acc, item) => acc + item.quantity, 0 ), - currency: selectedCurrency, + currency: selectedPayment === "paypal" ? selectedCurrency : selectedPayment === "wave" ? "FCFA" : user.currency, shipping_method: orderData?.transport_type || 0, shipping_price_outside: orderData?.shipping_fee || 0, shipping_price_within: orderData?.domestic_shipping_fee || 0, @@ -566,9 +691,14 @@ export const PaymentMethod = () => { data: res, payMethod: selectedPayment, currency: - selectedPayment === "paypal" ? selectedCurrency : user.currency, + selectedPayment === "paypal" ? selectedCurrency : selectedPayment === "wave" ? "FCFA" : user.currency, amount: selectedPayment === "paypal" + ? convertedAmount.reduce( + (acc, item) => acc + item.converted_amount, + 0 + ) + : selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 @@ -660,6 +790,7 @@ export const PaymentMethod = () => { convertedAmount={convertedAmount} isConverting={isConverting} isPaypalExpanded={isPaypalExpanded} + isWaveExpanded={isWaveExpanded} /> ))} @@ -734,6 +865,10 @@ export const PaymentMethod = () => { {selectedPayment === "paypal" + ? convertedAmount.find( + (item) => item.item_key === "total_amount" + )?.converted_amount || 0 + : selectedPayment === "wave" ? convertedAmount.find( (item) => item.item_key === "total_amount" )?.converted_amount || 0 @@ -742,6 +877,8 @@ export const PaymentMethod = () => { ? selectedCurrency === "USD" ? "USD" : "EUR" + : selectedPayment === "wave" + ? "FCFA" : previewOrder?.currency} @@ -751,6 +888,10 @@ export const PaymentMethod = () => { {selectedPayment === "paypal" + ? convertedAmount.find( + (item) => item.item_key === "domestic_shipping_fee" + )?.converted_amount || 0 + : selectedPayment === "wave" ? convertedAmount.find( (item) => item.item_key === "domestic_shipping_fee" )?.converted_amount || 0 @@ -759,6 +900,8 @@ export const PaymentMethod = () => { ? selectedCurrency === "USD" ? "USD" : "EUR" + : selectedPayment === "wave" + ? "FCFA" : previewOrder?.currency} @@ -768,6 +911,10 @@ export const PaymentMethod = () => { {selectedPayment === "paypal" + ? convertedAmount.find( + (item) => item.item_key === "shipping_fee" + )?.converted_amount || 0 + : selectedPayment === "wave" ? convertedAmount.find( (item) => item.item_key === "shipping_fee" )?.converted_amount || 0 @@ -776,6 +923,8 @@ export const PaymentMethod = () => { ? selectedCurrency === "USD" ? "USD" : "EUR" + : selectedPayment === "wave" + ? "FCFA" : previewOrder?.currency} @@ -849,7 +998,42 @@ export const PaymentMethod = () => { )} - {selectedPayment !== "paypal" && ( + {selectedPayment === "wave" && ( + + + {( + (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)}{" "} + FCFA + + + )} + {selectedPayment !== "paypal" && selectedPayment !== "wave" && ( { item.item_key === "total_amount"))) || + (selectedPayment === "wave" && (convertedAmount.length === 0 || !convertedAmount.find(item => item.item_key === "total_amount")))) && styles.disabledButton, ]} onPress={handleSubmit} - disabled={!selectedPayment || createLoading || isConverting} + disabled={!selectedPayment || createLoading || isConverting || + (selectedPayment === "paypal" && (convertedAmount.length === 0 || !convertedAmount.find(item => item.item_key === "total_amount"))) || + (selectedPayment === "wave" && (convertedAmount.length === 0 || !convertedAmount.find(item => item.item_key === "total_amount")))} > {createLoading ? ( diff --git a/app/screens/previewOrder/perviewOrder.tsx b/app/screens/previewOrder/perviewOrder.tsx index 2a224d5..e11227d 100644 --- a/app/screens/previewOrder/perviewOrder.tsx +++ b/app/screens/previewOrder/perviewOrder.tsx @@ -12,6 +12,8 @@ import { StatusBar, SafeAreaView, BackHandler, + Modal, + FlatList, } from "react-native"; import useCreateOrderStore from "../../store/createOrder"; import BackIcon from "../../components/BackIcon"; @@ -20,12 +22,15 @@ import { useRoute, RouteProp, useFocusEffect, + CommonActions, } from "@react-navigation/native"; import { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { useState, useEffect } from "react"; import useUserStore from "../../store/user"; import { Order } from "../../services/api/orders"; import { payApi } from "../../services/api/payApi"; +import { settingApi } from "../../services/api/setting"; +import { CountryList } from "../../constants/countries"; import { useTranslation } from "react-i18next"; import fontSize from "../../utils/fontsizeUtils"; import { getBurialPointData } from "../../store/burialPoint"; @@ -42,6 +47,7 @@ type RootStackParamList = { Pay: { payUrl: string; method: string; order_id: string }; OrderDetails: { orderId?: number }; PaymentSuccessScreen: any; + MainTabs: undefined; }; export const PreviewOrder = () => { @@ -50,6 +56,10 @@ export const PreviewOrder = () => { useNavigation>(); const [phoneNumber, setPhoneNumber] = useState(""); const [showPhoneInput, setShowPhoneInput] = useState(false); + const [countryList, setCountryList] = useState([]); + const [selectedCountry, setSelectedCountry] = useState(null); + const [showCountryModal, setShowCountryModal] = useState(false); + const [loadingCountries, setLoadingCountries] = useState(false); const route = useRoute>(); const [loading, setLoading] = useState(false); const { user } = useUserStore(); @@ -61,11 +71,58 @@ export const PreviewOrder = () => { } if (route.params.payMethod === "mobile_money") { setShowPhoneInput(true); + // 获取国家列表 + loadCountryList(); } else { setShowPhoneInput(false); } }, [route.params.payMethod, user.user_id, t]); + // 获取国家列表 + const loadCountryList = async () => { + setLoadingCountries(true); + try { + const response = await settingApi.getSendSmsCountryList(); + if (response && Array.isArray(response)) { + setCountryList(response); + // 如果用户有国家信息,自动选择对应的国家 + if (user?.country_en) { + const userCountry = response.find((country: CountryList) => + country.name_en.toLowerCase() === user.country_en.toLowerCase() + ); + if (userCountry) { + setSelectedCountry(userCountry); + } + } + } + } catch (error) { + console.error('获取国家列表失败:', error); + } finally { + setLoadingCountries(false); + } + }; + + // 格式化电话号码 + const formatPhoneNumber = (phone: string, country: CountryList | null): string => { + if (!phone || !country) return phone; + + // 移除电话号码中的空格、破折号等 + const cleanPhone = phone.replace(/[\s\-\(\)]/g, ''); + + // 如果已经有+号开头,直接返回 + if (cleanPhone.startsWith('+')) { + return cleanPhone; + } + + // 使用 country 字段作为国家代码 + const countryCode = `+${country.country}`; + + // 如果电话号码以0开头,移除0 + const phoneWithoutLeadingZero = cleanPhone.startsWith('0') ? cleanPhone.substring(1) : cleanPhone; + + return `${countryCode}${phoneWithoutLeadingZero}`; + }; + // 处理系统返回键 useFocusEffect( React.useCallback(() => { @@ -85,13 +142,22 @@ export const PreviewOrder = () => { const handleSubmit = () => { if (showPhoneInput && !phoneNumber) { - // Show error or alert if needed - console.log("Phone number is required for Mobile Money"); + Alert.alert(t("error"), t("order.preview.phone_required") || "Phone number is required for Mobile Money"); + return; + } + + if (showPhoneInput && !selectedCountry) { + Alert.alert(t("error"), "请选择国家"); return; } console.log(route.params.currency); + // 格式化电话号码,添加国家前缀 + const formattedPhone = showPhoneInput && phoneNumber + ? formatPhoneNumber(phoneNumber, selectedCountry) + : ''; + const data = { order_id: route.params.data.order_id, method: route.params.payMethod, @@ -99,32 +165,53 @@ export const PreviewOrder = () => { ? route.params.currency : route.params.data.currency, amount: route.params.data.actual_amount, + ...(showPhoneInput && formattedPhone && { + extra: { phone_number: formattedPhone } + }), }; + + console.log('发送的电话号码:', formattedPhone); setLoading(true); payApi .getPayInfo(data) .then((res) => { if (res.success) { - if (route.params.payMethod === "balance") { - if (res.success) { - navigation.navigate("PaymentSuccessScreen", res); - return; - } else { - Alert.alert(t("order.preview.Insufficient_balance")); - } - } + // 记录埋点数据 logPreviewOrder( navigation.getState().routes[navigation.getState().index - 1] ?.name as string ); - console.log(getBurialPointData()); - - navigation.replace("Pay", { - payUrl: res.payment_url, - method: route.params.payMethod, - order_id: route.params.data.order_id.toString(), - }); + console.log("埋点数据: " +getBurialPointData()); + + // 所有成功的支付都跳转到 ProfileScreen + navigation.dispatch( + CommonActions.reset({ + index: 0, + routes: [ + { + name: 'MainTabs', + state: { + routes: [ + { name: 'Home' }, + { name: 'productCollection' }, + { name: 'Chat' }, + { name: 'Cart' }, + { name: 'Profile' }, + ], + index: 4, // Profile tab 的索引 + }, + }, + ], + }) + ); + } else { + // 处理失败情况 + if (route.params.payMethod === "balance") { + Alert.alert(t("order.preview.Insufficient_balance")); + } else { + Alert.alert(t("order.preview.payment_failed")); + } } }) .catch((err) => { @@ -134,12 +221,6 @@ export const PreviewOrder = () => { .finally(() => { setLoading(false); }); - - // navigation.navigate('Pay', { - // orderId: user.user_id, - // payMethod: route.params.payMethod, - - // }) }; return ( @@ -177,13 +258,38 @@ export const PreviewOrder = () => { {t("order.preview.enter_phone")} - + + {/* 电话号码输入行 - 国家选择器在左侧 */} + + {/* 国家代码选择器 */} + setShowCountryModal(true)} + disabled={loadingCountries} + > + + {loadingCountries + ? "..." + : selectedCountry + ? `+${selectedCountry.country}` + : '+86' + } + + + + + {/* 分隔线 */} + + + {/* 电话号码输入框 */} + + )} @@ -280,12 +386,12 @@ export const PreviewOrder = () => { {loading ? ( @@ -298,6 +404,53 @@ export const PreviewOrder = () => { + + {/* 国家选择模态框 */} + setShowCountryModal(false)} + > + + + + 选择国家 + setShowCountryModal(false)} + style={styles.modalCloseButton} + > + + + + + item.country.toString()} + renderItem={({ item }) => ( + { + setSelectedCountry(item); + setShowCountryModal(false); + }} + > + + {item.name_en} (+{item.country}) + + + )} + style={styles.countryList} + /> + + + ); }; @@ -411,11 +564,11 @@ const styles = StyleSheet.create({ color: "#333", }, phoneInput: { - borderWidth: 1, - borderColor: "#ddd", - borderRadius: 5, - padding: 10, + flex: 1, + paddingHorizontal: 12, + paddingVertical: 15, fontSize: fontSize(15), + color: "#333", }, infoRow: { flexDirection: "row", @@ -454,4 +607,85 @@ const styles = StyleSheet.create({ color: "#002fa7", fontFamily: "PingFang SC", }, + phoneInputRow: { + flexDirection: "row", + alignItems: "center", + borderWidth: 1, + borderColor: "#ddd", + borderRadius: 5, + overflow: "hidden", + }, + countryCodeSelector: { + paddingHorizontal: 12, + paddingVertical: 15, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + minWidth: 80, + backgroundColor: "#f8f8f8", + }, + countryCodeText: { + fontSize: fontSize(15), + color: "#333", + fontWeight: "600", + marginRight: 5, + }, + countryCodeArrow: { + fontSize: fontSize(10), + color: "#666", + }, + phoneSeparator: { + width: 1, + height: 30, + backgroundColor: "#ddd", + }, + modalOverlay: { + flex: 1, + backgroundColor: "rgba(0, 0, 0, 0.5)", + justifyContent: "center", + alignItems: "center", + }, + modalContent: { + backgroundColor: "white", + padding: 20, + borderRadius: 20, + width: "80%", + maxHeight: "80%", + }, + modalHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + marginBottom: 10, + }, + modalTitle: { + fontSize: fontSize(18), + fontWeight: "600", + }, + modalCloseButton: { + padding: 5, + }, + modalCloseText: { + fontSize: fontSize(16), + fontWeight: "600", + }, + countryItem: { + padding: 10, + borderWidth: 1, + borderColor: "#ddd", + borderRadius: 5, + }, + selectedCountryItem: { + backgroundColor: "#002fa7", + }, + countryItemText: { + fontSize: fontSize(15), + color: "#333", + }, + countryList: { + flex: 1, + }, + selectedCountryItemText: { + color: "white", + }, }); diff --git a/app/screens/productStatus/OrderDatails.tsx b/app/screens/productStatus/OrderDatails.tsx index e86cf2b..0474720 100644 --- a/app/screens/productStatus/OrderDatails.tsx +++ b/app/screens/productStatus/OrderDatails.tsx @@ -226,6 +226,7 @@ export const OrderDetails = () => { const { user } = useUserStore(); const [isPaymentLoading, setIsPaymentLoading] = useState(false); const [isPaypalExpanded, setIsPaypalExpanded] = useState(false); + const [isWaveExpanded, setIsWaveExpanded] = useState(false); const [paymentParams, setPaymentParams] = useState<{ originalAmount: number; amount: number; @@ -304,6 +305,7 @@ export const OrderDetails = () => { const onSelectPayment = (paymentId: string) => { if (paymentId !== selectedPayment) { setIsPaypalExpanded(false); + setIsWaveExpanded(false); } setSelectedPayment(paymentId); @@ -324,6 +326,32 @@ export const OrderDetails = () => { }, }; + payApi + .convertCurrency(data) + .then((res) => { + setConvertedAmount(res.converted_amounts_list); + setIsConverting(false); + }) + .catch((error) => { + console.error("Currency conversion failed:", error); + setIsConverting(false); + }); + } else if (paymentId === "wave" && paymentId !== selectedPayment) { + setIsWaveExpanded(true); + setIsConverting(true); + + setSelectedCurrency("FCFA"); + + const data = { + from_currency: orderDetails?.currency || "", + to_currency: "FCFA", + amounts: { + total_amount: orderDetails?.total_amount || 0, + domestic_shipping_fee: orderDetails?.domestic_shipping_fee || 0, + shipping_fee: orderDetails?.shipping_fee || 0, + }, + }; + payApi .convertCurrency(data) .then((res) => { @@ -386,28 +414,28 @@ export const OrderDetails = () => { const paymentData = { order_id: orderDetails.order_id, payment_method: selectedPayment, - currency: selectedPayment === "paypal" ? selectedCurrency : user.currency, + currency: selectedPayment === "paypal" ? selectedCurrency : selectedPayment === "wave" ? "FCFA" : user.currency, total_amount: - selectedPayment === "paypal" + selectedPayment === "paypal" || selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : orderDetails?.total_amount || 0, actual_amount: - selectedPayment === "paypal" + selectedPayment === "paypal" || selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 ) : orderDetails?.actual_amount || 0, shipping_fee: - selectedPayment === "paypal" + selectedPayment === "paypal" || selectedPayment === "wave" ? convertedAmount.find((item) => item.item_key === "shipping_fee") ?.converted_amount || 0 : orderDetails?.shipping_fee || 0, domestic_shipping_fee: - selectedPayment === "paypal" + selectedPayment === "paypal" || selectedPayment === "wave" ? convertedAmount.find( (item) => item.item_key === "domestic_shipping_fee" )?.converted_amount || 0 @@ -420,9 +448,9 @@ export const OrderDetails = () => { order_id: orderDetails.order_id, method: selectedPayment, currency: - selectedPayment === "paypal" ? selectedCurrency : user.currency, + selectedPayment === "paypal" ? selectedCurrency : selectedPayment === "wave" ? "FCFA" : user.currency, amount: - selectedPayment === "paypal" + selectedPayment === "paypal" || selectedPayment === "wave" ? convertedAmount.reduce( (acc, item) => acc + item.converted_amount, 0 @@ -550,6 +578,15 @@ export const OrderDetails = () => { return true; } + // 如果选择了Wave支付方式,但还没有转换结果,禁用按钮 + if ( + selectedPayment === "wave" && + (convertedAmount.length === 0 || + !convertedAmount.find((item) => item.item_key === "total_amount")) + ) { + return true; + } + // 其他情况下,启用按钮 return false; }; @@ -1210,6 +1247,56 @@ export const OrderDetails = () => { )} + + {/* Wave Currency Selection */} + {selectedPayment === "wave" && + option.id === "wave" && + isWaveExpanded && ( + + + + {t("order.select_currency") || + "Select Currency"} + + + + + FCFA + + + + + {/* 显示转换后的金额 */} + {isConverting ? ( + + + + {t("order.converting") || "Converting..."} + + + ) : convertedAmount.length > 0 ? ( + + + {t("order.equivalent_amount") || + "Equivalent Amount:"} + + + {convertedAmount + .find( + (item) => + item.item_key === "total_amount" + ) + ?.converted_amount.toFixed(2)}{" "} + FCFA + + + ) : null} + + + )} ))}