120 lines
5.2 KiB
TypeScript
120 lines
5.2 KiB
TypeScript
import { Alert, Image, Text, View } from "react-native";
|
|
import CustomButton from "./CustomButton";
|
|
import tw from "twrnc";
|
|
import { useStripe } from "@stripe/stripe-react-native";
|
|
import { useState } from "react";
|
|
import { fetchAPI } from "@/lib/fetch";
|
|
import { PaymentProps } from "@/types/type";
|
|
import { useLocationStore } from "@/store";
|
|
import { useAuth } from "@clerk/clerk-expo";
|
|
import ReactNativeModal from "react-native-modal";
|
|
import { images } from "@/constants";
|
|
import { router } from "expo-router";
|
|
const Payment = ({fullName,email,amount,driverId,rideTime}:PaymentProps) => {
|
|
const [success, setSuccess] = useState(false);
|
|
const {userId} =useAuth();
|
|
const {userAddress,userLatitude,userLongitude,destinationAddress,destinationLatitude,destinationLongitude} = useLocationStore();
|
|
|
|
const { initPaymentSheet, presentPaymentSheet } = useStripe();
|
|
|
|
const initializePaymentSheet = async () => {
|
|
const { error } = await initPaymentSheet({
|
|
merchantDisplayName: "Neel,Inc.",
|
|
intentConfiguration: {
|
|
mode: {
|
|
amount: parseInt(amount)*100,
|
|
currencyCode: "USD",
|
|
},
|
|
confirmHandler: async (paymentMethod,_, intentCreationCallback) => {
|
|
const {paymentIntent,customer} = await fetchAPI("/api/stripe/create",{
|
|
method:"POST",
|
|
headers:{
|
|
"Content-Type": "application/json",
|
|
},
|
|
body:JSON.stringify({
|
|
name:fullName || email.split("@")[0],
|
|
email: email,
|
|
amount: amount,
|
|
paymentMethodId : paymentMethod.id,
|
|
}),
|
|
},
|
|
);
|
|
console.log("create response", paymentIntent);
|
|
if(paymentIntent?.client_secret){
|
|
const {result} = await fetchAPI ("/api/stripe/pay",{
|
|
method:"POST",
|
|
headers:{
|
|
"Content-Type":"application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
payment_method_id:paymentMethod.id,
|
|
payment_intent_id:paymentIntent.id,
|
|
customer_id:customer,
|
|
}),
|
|
});
|
|
console.log("confirm response", result);
|
|
if (result?.client_secret) {
|
|
await fetchAPI("/api/ride/create",{
|
|
method: "POST",
|
|
headers:{
|
|
"Content-Type":"application/json",
|
|
},
|
|
body:JSON.stringify({
|
|
origin_address:userAddress,
|
|
destination_address:destinationAddress,
|
|
origin_latitude:userLatitude,
|
|
origin_longitude:userLongitude,
|
|
destination_latitude:destinationLatitude,
|
|
destination_longitude:destinationLongitude,
|
|
ride_time:rideTime.toFixed(0),
|
|
fare_price:parseInt(amount)*100,
|
|
payment_status:"paid",
|
|
driver_id:driverId,
|
|
user_id:userId,
|
|
}),
|
|
});
|
|
console.log("Passing to intentCreationCallback:", result.client_secret);
|
|
intentCreationCallback({
|
|
clientSecret:result.client_secret,
|
|
})
|
|
} else {
|
|
console.log("❌ Missing client_secret in result:", result);
|
|
}
|
|
}
|
|
|
|
}
|
|
},
|
|
returnURL:'myapp"//book-ride',
|
|
});
|
|
if (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
const openPaymentSheet = async () => {
|
|
await initializePaymentSheet();
|
|
|
|
const { error } = await presentPaymentSheet();
|
|
|
|
if (error) {
|
|
Alert.alert(`Error code: ${error.code}`, error.message);
|
|
}
|
|
else {
|
|
setSuccess(true);
|
|
}
|
|
};
|
|
return (
|
|
<>
|
|
<CustomButton title="Confirm Ride" style={tw`my-10`} onPress={openPaymentSheet} />
|
|
<ReactNativeModal isVisible={success} onBackButtonPress={()=>setSuccess(false)} >
|
|
<View style={tw`flex flex-col items-center justify-center bg-white p-7 rounded-2xl`} >
|
|
<Image source={images.check} style={tw`w-28 h-28 mt-5`} />
|
|
<Text style={tw`text-2xl text-center font-JakartaBold mt-5`}>Ride Booked!</Text>
|
|
<Text style={tw`text-md text-general-200 font-JakartaMedium`} >Thank you for your booking. Your reservation has been placed. Please proceed with your trip! </Text>
|
|
<CustomButton title="Back Home" onPress={()=>{setSuccess(false)
|
|
router.push("/(root)/(tabs)/home")}} style={tw`mt-5`} />
|
|
</View>
|
|
</ReactNativeModal>
|
|
</>
|
|
)
|
|
};
|
|
export default Payment; |