Skip to content

Commit

Permalink
add stripe payment
Browse files Browse the repository at this point in the history
  • Loading branch information
admin committed Jan 15, 2023
1 parent 70accd7 commit 4e372d0
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 60 deletions.
31 changes: 18 additions & 13 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import {NavigationContainer} from '@react-navigation/native';
import { NavigationContainer } from '@react-navigation/native';

import {UseLogin} from './src/hook/useLogin';
import { UseLogin } from './src/hook/useLogin';

import {store} from './src/app/store';
import {Provider} from 'react-redux';
import {LogBox} from 'react-native';
import { store } from './src/app/store';
import { Provider } from 'react-redux';
import { LogBox } from 'react-native';
import RouteNavigation from './src/navigations/index';
import { StripeProvider } from '@stripe/stripe-react-native';

LogBox.ignoreAllLogs();

Expand All @@ -22,13 +23,17 @@ const App = () => {
}, 14000);
}, []);
return (
<Provider store={store}>
<NavigationContainer>
<UseLogin>
<RouteNavigation />
</UseLogin>
</NavigationContainer>
</Provider>
<StripeProvider
publishableKey={'pk_test_51LKCh8HBvb3MzaZzQ4r8pyrGRybpjCGLES5RPWbnoifGK9solGIu6cSWWOlCKZIXtdZQedYF5DXxP4KK3cJJ1UwA00flLZaHHy'}
merchantIdentifier="merchant.identifier">
<Provider store={store}>
<NavigationContainer>
<UseLogin>
<RouteNavigation />
</UseLogin>
</NavigationContainer>
</Provider>
</StripeProvider>
);
};

Expand Down
123 changes: 94 additions & 29 deletions src/features/confirm-screen/ConfirmScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import React, {useState} from 'react';
import React, { useState } from 'react';
import {
ActivityIndicator,
Image,
Expand All @@ -9,25 +9,65 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import {Base_Url} from '../../constants/const';
import {useNavigation} from '@react-navigation/native';
import { Base_Url } from '../../constants/const';
import { useNavigation } from '@react-navigation/native';
import Toast from 'react-native-toast-message';
import {useAppSelector} from '../../app/store';
import { useAppSelector } from '../../app/store';
import { BillingDetails, CardField, confirmPayment } from '@stripe/stripe-react-native';
import Loading from '../../components/loading/index'

const ConfirmScreen = ({route}) => {
const {item} = route.params;
const ConfirmScreen = ({ route }) => {
const { item } = route.params;
const dataUserInfor: any = useAppSelector(state => state.LoginSlice.data);
console.log('dataUser', dataUserInfor);

const navigation = useNavigation();
const [loading, setLoading] = useState(false);

const imageDefault =
'https://victoriatourist.com.vn/wp-content/uploads/2020/06/unnamed.png';

const confirmTour = async () => {
try {
setLoading(true);

const fetchPaymentIntentClientSecret = async () => {
const response = await fetch(`http://10.0.2.2:8080/v1/stripe/create-payment-intent`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
currency: 'usd',
amount: item.item.item.price

}),
});
const { clientSecret } = await response.json();

return clientSecret;
};

const handlePayPress = async () => {
setLoading(true);

const billingDetails: BillingDetails = {
email: dataUserInfor.email,
name: dataUserInfor.first_name + ' ' + dataUserInfor.last_name,
phone: dataUserInfor.phone_number
};

// Fetch the intent client secret from the backend
const clientSecretData = await fetchPaymentIntentClientSecret();

// Confirm the payment with the card details
const { paymentIntent, error } = await confirmPayment(clientSecretData, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails,
},
});

if (error) {
console.log('Payment confirmation error', error);
} else if (paymentIntent) {
console.log('Success from promise', paymentIntent);
const tokenNew = await AsyncStorage.getItem('storage_Key');
const obj = {
user_id: dataUserInfor?._id,
Expand All @@ -53,37 +93,38 @@ const ConfirmScreen = ({route}) => {
},
},
);
Toast.show({
type: 'success',
text1: 'Bạn đã đặt Tour thành công 👋',
});

console.log('response data', response)

setTimeout(() => {
navigation.navigate('HomePage' as never);
setLoading(false)
Toast.show({
type: 'success',
text1: 'Bạn đã đặt Tour thành công 👋',
});
setTimeout(() => {
navigation.navigate('HomePage' as never);
}, 1000)
}, 1000);

console.log('responseee', response.data);
setLoading(false);
} catch (error) {
console.log('error', error);
}

// Fetch the intent client secret from the backend.
};

return (
<View style={styles.container}>
<Text style={styles.headerTitle}>Xác nhận đặt Tour</Text>
<View style={{zIndex: 99}}>
<View style={{ zIndex: 99 }}>
<Toast />
</View>
{loading && (
<View style={styles.loading}>
<ActivityIndicator size={'large'} color={'green'} />
</View>
<Loading />
)}
<View style={styles.imageHeader}>
<Image
resizeMode="contain"
source={{uri: imageDefault}}
style={{height: 100}}
source={{ uri: imageDefault }}
style={{ height: 100 }}
/>
</View>

Expand All @@ -93,11 +134,35 @@ const ConfirmScreen = ({route}) => {
<Text>Giá: {item.item.item.price}</Text>
</View>

<View style={{width: '100%', paddingHorizontal: 10}}>
<CardField
postalCodeEnabled={true}
placeholders={{
number: '4242 4242 4242 4242',
}}
cardStyle={{
backgroundColor: '#FFFFFF',
textColor: '#000000',
}}
style={{
width: '100%',
height: 50,
marginVertical: 30,
}}
onCardChange={cardDetails => {
console.log('cardDetails', cardDetails);
}}
onFocus={focusedField => {
console.log('focusField', focusedField);
}}
/>
</View>

<View style={styles.containerClick}>
<TouchableOpacity
style={styles.headerClick}
onPress={() => confirmTour()}>
<Text style={{color: 'white'}}>Xác nhận đặt tour</Text>
onPress={() => handlePayPress()}>
<Text style={{ color: 'white' }}>Xác nhận đặt tour</Text>
</TouchableOpacity>
</View>
</View>
Expand Down Expand Up @@ -136,7 +201,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
marginTop: 10,
},
bold: {fontWeight: 'bold'},
bold: { fontWeight: 'bold' },
headerClick: {
width: 150,
height: 40,
Expand Down
4 changes: 0 additions & 4 deletions src/features/payments/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import PaymentDetail from './payment-detail';

const Payment = () => {
return (
<StripeProvider
publishableKey={''}
merchantIdentifier="merchant.identifier">
<PaymentDetail />
</StripeProvider>
);
};

Expand Down
59 changes: 49 additions & 10 deletions src/features/payments/payment-detail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
import React from 'react';
import {CardField, useStripe} from '@stripe/stripe-react-native';
import {SafeAreaView, Text, TouchableOpacity, View} from 'react-native';
import {setOpenModal} from '../../scheduleOverview/scheduleOverviewSlice';
import {useAppDispatch, useAppSelector} from '../../../app/store';
import { BillingDetails, CardField, StripeProvider, useStripe } from '@stripe/stripe-react-native';
import { SafeAreaView, Text, TouchableOpacity, View } from 'react-native';
import { setOpenModal } from '../../scheduleOverview/scheduleOverviewSlice';
import { useAppDispatch, useAppSelector } from '../../../app/store';
import OrderSuccess from '../../../components/orderSuccess';

const PaymentDetail = () => {
const {confirmPayment} = useStripe();
const { confirmPayment } = useStripe();
const dispatch = useAppDispatch();
const openModal = useAppSelector(
state => state.scheduleOverviewSlice.openModal,
);

const fetchPaymentIntentClientSecret = async () => {
const response = await fetch(`http://10.0.2.2:8080/v1/stripe/create-payment-intent`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
currency: 'usd',

}),
});
const { clientSecret } = await response.json();

return clientSecret;
};

const handlePayPress = async () => {
const billingDetails: BillingDetails = {
email: 'jenny.rosen@example.com',
};

// Fetch the intent client secret from the backend
const clientSecretData = await fetchPaymentIntentClientSecret();

// Confirm the payment with the card details
const { paymentIntent, error } = await confirmPayment(clientSecretData, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails,
},
});

if (error) {
console.log('Payment confirmation error', error);
} else if (paymentIntent) {
console.log('Success from promise', paymentIntent);
}

// Fetch the intent client secret from the backend.
};
return (
<>
<>
<SafeAreaView />
<View
style={{
Expand All @@ -24,7 +64,7 @@ const PaymentDetail = () => {
paddingHorizontal: 16,
marginTop: 70,
}}>
<Text style={{color: '#FF5F24', fontSize: 19}}>MOBILE BANKING</Text>
<Text style={{ color: '#FF5F24', fontSize: 19 }}>MOBILE BANKING</Text>
<CardField
postalCodeEnabled={true}
placeholders={{
Expand All @@ -47,7 +87,7 @@ const PaymentDetail = () => {
}}
/>
<TouchableOpacity
onPress={() => dispatch(setOpenModal(true))}
onPress={() => handlePayPress()}
style={{
width: '100%',
height: 30,
Expand All @@ -56,10 +96,9 @@ const PaymentDetail = () => {
alignItems: 'center',
borderRadius: 6,
}}>
<Text style={{color: 'white'}}>Thanh Toán </Text>
<Text style={{ color: 'white' }}>Thanh Toán </Text>
</TouchableOpacity>
</View>
{openModal && <OrderSuccess />}
</>
);
};
Expand Down
13 changes: 9 additions & 4 deletions src/features/profile/favourite/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,28 @@ import Header from '../../../components/header/Header';
import ListRencentSchedule from '../../recent-schedule-detail/ListRencentSchedule';
import { useAppSelector } from '../../../app/store';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Loading from '../../../components/loading/index';

const Favourite = () => {

const dataUser = useAppSelector((state) => state.LoginSlice.data)

const [data, setData] = useState([]);
const [loading, setLoading] = useState(false)

const getTourFavourite = async () => {
try {
const tokenNew = await AsyncStorage.getItem('storage_Key');

setLoading(true)
const response = await axios.get(`http://10.0.2.2:8080/v1/tour/getTourFavouriteOfAllTour/${dataUser._id}`, {
headers: {
Authorization: `Bearer ${tokenNew}`,
},
})

console.log('response', response.data)
setLoading(false)
setData(response.data)
} catch (error) {

setLoading(false)
}
}

Expand All @@ -35,6 +37,9 @@ const Favourite = () => {
return (
<View>
<Header title="Yêu thích" backOption={false} />
{
loading && <Loading />
}
<ListRencentSchedule passData={data} love={true} />
</View>
);
Expand Down

0 comments on commit 4e372d0

Please sign in to comment.