diff --git a/app/(tabs)/payments.tsx b/app/(tabs)/payments.tsx
index ae937b1..9823c2f 100644
--- a/app/(tabs)/payments.tsx
+++ b/app/(tabs)/payments.tsx
@@ -72,7 +72,6 @@ interface PaymentHistoryResponse {
}
const formatPaymentDate = (dateString: string) => {
- console.log(dateString.split(",")[0], "datestring");
try {
return dateString.split(",")[0];
} catch {
@@ -82,7 +81,6 @@ const formatPaymentDate = (dateString: string) => {
// Format time for payment history
const formatPaymentTime = (dateString: string) => {
- console.log(dateString, "formattime");
try {
// Expected: "12 Aug 2025, 12:38:23 pm"
const [datePart, timePart] = dateString.split(",");
@@ -452,7 +450,6 @@ export default function PaymentsTabScreen() {
)}
-
);
}
diff --git a/app/payments/payEmi.tsx b/app/payments/payEmi.tsx
index 9cae28c..312cc6e 100644
--- a/app/payments/payEmi.tsx
+++ b/app/payments/payEmi.tsx
@@ -7,12 +7,9 @@ import {
SafeAreaView,
Alert,
Share,
- Clipboard,
Linking,
- ActivityIndicator,
BackHandler,
} from "react-native";
-import { Ionicons } from "@expo/vector-icons";
import * as FileSystem from "expo-file-system";
import * as MediaLibrary from "expo-media-library";
import * as Sharing from "expo-sharing";
@@ -43,23 +40,11 @@ const UpiPaymentScreen = () => {
const { showSnackbar } = useSnackbar();
const insets = useSafeAreaInsets();
- if (!paymentOrder) {
- return (
-
-
-
- Loading payment details...
-
-
- );
- }
useEffect(() => {
- // Set up payment confirmation listener
const handlePaymentConfirmation = (data: any) => {
console.log("Payment confirmation received:", data);
- // Show success message
Alert.alert(
"Payment Successful!",
"Your payment has been confirmed successfully.",
@@ -75,11 +60,9 @@ const UpiPaymentScreen = () => {
);
};
- // Start listening for payment confirmation
onPaymentConfirmation(handlePaymentConfirmation);
setIsListening(true);
- // Handle Android back button
const backAction = () => {
Alert.alert(
"Cancel Payment?",
@@ -120,11 +103,6 @@ const UpiPaymentScreen = () => {
return `₹${amount.toLocaleString("en-IN")}`;
};
- // Extract numeric amount from the amount
- const getNumericAmount = (): string => {
- return paymentOrder.amount.toString();
- };
-
// Check if payment is expired
const isPaymentExpired = (): boolean => {
const expiryDate = new Date(paymentOrder.expiry_date);
@@ -261,23 +239,9 @@ const UpiPaymentScreen = () => {
}
};
- const getStatusColor = (status: string): string => {
- switch (status) {
- case "completed":
- case "success":
- return "#00876F";
- case "failed":
- return "#E74C3C";
- case "processing":
- return "#F39C12";
- default:
- return "#6C757D";
- }
- };
-
return (
-
+
diff --git a/app/payments/selectAmount.tsx b/app/payments/selectAmount.tsx
index cb86af6..442aaba 100644
--- a/app/payments/selectAmount.tsx
+++ b/app/payments/selectAmount.tsx
@@ -19,10 +19,10 @@ import { BASE_URL, payments } from "@/constants/config";
import api from "@/services/axiosClient";
import { setPaymentOrder } from "@/store/paymentSlice";
import { Overlay } from "@/components/common/Overlay";
-import { useRouter } from "expo-router";
+import { useFocusEffect, useRouter } from "expo-router";
import { useSocket } from "@/contexts/SocketContext";
+import { useSnackbar } from "@/contexts/Snackbar";
-// Validation schema
const validationSchema = Yup.object().shape({
paymentType: Yup.string().required("Please select a payment option"),
customAmount: Yup.string().when("paymentType", {
@@ -47,11 +47,12 @@ const validationSchema = Yup.object().shape({
});
const SelectAmountScreen = () => {
- // Fetch due amount from Redux
const dueAmount = useSelector(
(state: RootState) => state.payments?.due_amount || 0
);
+ const { showSnackbar } = useSnackbar();
+
const router = useRouter();
const [isFetching, setIsFetching] = useState(false);
@@ -64,41 +65,72 @@ const SelectAmountScreen = () => {
customAmount: "",
};
+ const existingPaymentOrder = useSelector(
+ (state: RootState) => state.payments?.paymentOrder
+ );
+
const dispatch = useDispatch();
+ useFocusEffect(
+ React.useCallback(() => {
+ console.log(
+ "SelectAmountScreen focused - clearing paymentOrder and remounting"
+ );
+ // Clear the payment order
+ dispatch(setPaymentOrder(null));
+ setIsFetching(false);
+ }, [dispatch])
+ );
+
const handleSubmit = async (values: any) => {
setIsFetching(true);
const paymentAmount =
values.paymentType === "due"
? dueAmount
: parseFloat(values.customAmount);
- console.log(values, "values");
+
try {
- const res = await api.post(`/api/v1/create-order`, {
- amount: paymentAmount,
- });
+ let orderData = existingPaymentOrder;
- console.log(res.data, "response from select amount");
- if (res.data && res.data.success) {
- dispatch(setPaymentOrder(res.data.data));
- try {
- await registerTransaction(res.data.data.transaction_id);
- console.log("Transaction registered successfully");
-
- // Navigate to payment screen
- router.push("/payments/payEmi");
- } catch (socketError) {
- throw socketError;
- }
+ if (
+ existingPaymentOrder &&
+ existingPaymentOrder.amount === paymentAmount
+ ) {
+ console.log(
+ "Order for current amount already exists, using existing order"
+ );
+ orderData = existingPaymentOrder;
} else {
- throw new Error("Failed to create order");
+ console.log("Creating new order for amount:", paymentAmount);
+ const res = await api.post(`/api/v1/create-order`, {
+ amount: paymentAmount,
+ });
+
+ console.log(res.data, "response from select amount");
+
+ if (res.data && res.data.success) {
+ orderData = res.data.data;
+ dispatch(setPaymentOrder(orderData));
+ } else {
+ throw new Error("Failed to create order");
+ }
+ }
+
+ try {
+ await registerTransaction(orderData?.transaction_id);
+ console.log("Transaction registered successfully");
+
+ router.push("/payments/payEmi");
+ } catch (socketError) {
+ console.error("Socket connection failed:", socketError);
+ throw socketError;
}
} catch (err) {
console.error(err, "Error in creating order.");
+ showSnackbar("Something went wrong.", "error");
} finally {
setIsFetching(false);
}
-
console.log("Payment Amount:", paymentAmount);
};
@@ -263,7 +295,6 @@ const SelectAmountScreen = () => {
- {/* Pay Button */}
Promise;
+ registerTransaction: (
+ transactionId: string | null | undefined
+ ) => Promise;
onPaymentConfirmation: (callback: (data: any) => void) => void;
offPaymentConfirmation: () => void;
disconnect: () => void;
@@ -26,25 +28,6 @@ interface SocketProviderProps {
export const SocketProvider: React.FC = ({ children }) => {
const [isConnected, setIsConnected] = useState(false);
- // useEffect(() => {
- // const initSocket = async () => {
- // try {
- // await SocketService.connect();
- // setIsConnected(true);
- // } catch (error) {
- // console.error("Failed to connect socket:", error);
- // setIsConnected(false);
- // }
- // };
-
- // initSocket();
-
- // return () => {
- // SocketService.disconnect();
- // setIsConnected(false);
- // };
- // }, []);
-
const connectSocket = async () => {
try {
await SocketService.connect();
@@ -56,7 +39,9 @@ export const SocketProvider: React.FC = ({ children }) => {
}
};
- const registerTransaction = async (transactionId: string) => {
+ const registerTransaction = async (
+ transactionId: string | null | undefined
+ ) => {
try {
if (!transactionId) {
throw new Error("Transaction Id missing in register transaction");
diff --git a/services/paymentSocket.ts b/services/paymentSocket.ts
index 17f78b5..8c17ab5 100644
--- a/services/paymentSocket.ts
+++ b/services/paymentSocket.ts
@@ -1,5 +1,9 @@
// services/socketService.ts
-import { PAYMENT_SOCKET_BASE_URL, STORAGE_KEYS } from "@/constants/config";
+import {
+ PAYMENT_SOCKET_BASE_URL,
+ payments,
+ STORAGE_KEYS,
+} from "@/constants/config";
import AsyncStorage from "@react-native-async-storage/async-storage";
import io, { Socket } from "socket.io-client";
@@ -66,19 +70,17 @@ class SocketService {
return;
}
- const timeoutMs = 5000;
+ const timeoutSecs = payments.SOCKET_CONNECTION_TIMEOUT_IN_SECS * 1000;
const timeoutId = setTimeout(() => {
socket.off("registration-ack", onRegistrationAck);
reject(new Error("Timeout: No registration-ack received"));
- }, timeoutMs);
+ }, timeoutSecs);
const onRegistrationAck = (data: any) => {
- console.log("inside onRegisterAck");
if (data.transactionId === transactionId) {
clearTimeout(timeoutId);
- // socket.off("registration-ack", onRegistrationAck);
-
+ socket.off("registration-ack", onRegistrationAck);
if (data.success) {
resolve();
} else {
@@ -87,33 +89,30 @@ class SocketService {
}
};
- socket.on("registration-ack", onRegistrationAck);
-
- socket.on("register-transaction", this.onPaymentConfirm);
- socket.onAny((eventName, ...args) => {
- console.log(eventName, "eventname", JSON.stringify(args), "✅✅✅✅✅");
+ //register the transaction with the specific 'transactionId'
+ socket.emit(payments.REGISTER_TRANSACTION_EMIT_EVENT_NAME, {
+ transactionId,
});
-
- socket.emit("register-transaction", { transactionId });
+ socket.on(
+ payments.REGISTER_TRANSACTION_LISTEN_EVENT_NAME,
+ onRegistrationAck
+ );
});
}
- private onPaymentConfirm(eventname: string, ...args: any[]): void {
- console.log(eventname, "eventName", JSON.stringify(args));
- }
-
+ //payment confirmation is received on 'register-transaction' eventName
public onPaymentConfirmation(callback: (data: any) => void): void {
if (!this.socket) {
console.error("Socket not connected");
return;
}
- this.socket.on("register-transaction", callback);
+ this.socket.on(payments.PAYMENT_CONFIRMATION_EVENT_NAME, callback);
}
public offPaymentConfirmation(): void {
if (this.socket) {
- this.socket.off("payment-confirmation");
+ this.socket.off(payments.PAYMENT_CONFIRMATION_EVENT_NAME);
}
}