1
+ import React , { useState , useEffect } from 'react' ;
2
+ import { useDispatch , useSelector } from 'react-redux' ;
3
+ import NavBar from '../components/Navbar' ;
4
+ import PageHeading from '../components/PageHeading' ;
5
+ import ProductDetail from '../components/ProductDetail' ;
6
+ import Sidebar from '../components/Sidebar' ;
7
+ import Cart from '../components/Cart' ;
8
+ import { Link } from 'react-router-dom' ;
9
+ import { showCart } from '../redux/actions/cartActions' ;
10
+ import { CardElement , useStripe , useElements } from "@stripe/react-stripe-js" ;
11
+ import axios from 'axios' ;
12
+
13
+
14
+ const PaymentForm = ( { history} ) => {
15
+
16
+ const [ submitted , setSubmitted ] = useState ( false ) ;
17
+ const [ showCardPayment , setShowCardPayment ] = useState ( false ) ;
18
+ const stripe = useStripe ( ) ;
19
+ const elements = useElements ( ) ;
20
+ const dispatch = useDispatch ( ) ;
21
+
22
+ const cardElementOptions = {
23
+ hidePostalCode : true ,
24
+ style : {
25
+ base : {
26
+ color : "#303238" ,
27
+ fontSize : "18px"
28
+ } ,
29
+ invalid : {
30
+ color : "#e5424d" ,
31
+ ":focus" : {
32
+ color : "#303238"
33
+ }
34
+ }
35
+ }
36
+ } ;
37
+
38
+ const shippingAddress = useSelector ( ( state ) => state . cart . shippingAddress ) ;
39
+ const { street1, street2, city, state, zip, country } = shippingAddress ;
40
+
41
+ //Redirect to shipping page if address is not filled
42
+ if ( Object . keys ( shippingAddress ) . length === 0 ) {
43
+ history . push ( "/shipping" ) ;
44
+ }
45
+
46
+ const [ formState , setFormState ] = useState ( {
47
+ values :{ }
48
+ } ) ;
49
+
50
+ const handleChange = ( event ) => {
51
+ setFormState ( formState => ( {
52
+ ...formState ,
53
+ values :{
54
+ ...formState . values ,
55
+ [ event . target . name ] :
56
+ event . target . type === 'checkbox'
57
+ ? event . target . checked
58
+ : event . target . value
59
+ }
60
+
61
+ } ) ) ;
62
+ }
63
+
64
+ let cardElement = null ;
65
+
66
+ const handleSubmit = async ( e ) => {
67
+ e . preventDefault ( ) ;
68
+ setSubmitted ( true ) ;
69
+ if ( ! stripe || ! elements ) {
70
+ // Stripe.js has not loaded yet. Make sure to disable
71
+ // form submission until Stripe.js has loaded.
72
+ return ;
73
+ }
74
+ // Get a reference to a mounted CardElement. Elements knows how
75
+ // to find your CardElement because there can only ever be one of
76
+ // each type of element.
77
+
78
+
79
+ // use stripe.createToken to get a unique token for the card
80
+ const { error, token } = await stripe . createToken ( cardElement ) ;
81
+
82
+ if ( ! error ) {
83
+ // Backend is not implemented yet, but once there isn’t any errors,
84
+ // you can pass the token and payment data to the backend to complete
85
+ // the charge
86
+ axios
87
+ . post ( "checkout/payment" , {
88
+ token : token . id ,
89
+ currency : "EGP" ,
90
+ price : 1000 , // or 10 pounds (10*100). Stripe charges with the smallest price unit allowed
91
+ } )
92
+ . then ( ( resp ) => {
93
+ alert ( "Your payment was successful" ) ;
94
+ } )
95
+ . catch ( ( err ) => {
96
+ console . log ( err ) ;
97
+ } ) ;
98
+ } else {
99
+ console . log ( error ) ;
100
+ }
101
+ }
102
+
103
+ const changePaymentMethod = ( e ) => {
104
+ if ( e . target . value === 'card' ) {
105
+ setShowCardPayment ( true ) ;
106
+ } else {
107
+ setShowCardPayment ( false ) ;
108
+ }
109
+ }
110
+
111
+
112
+ const handleCardError = ( event ) => {
113
+ let displayError = document . getElementById ( 'card-errors' ) ;
114
+ if ( event . error ) {
115
+ displayError . textContent = event . error . message ;
116
+ } else {
117
+ displayError . textContent = '' ;
118
+ }
119
+ }
120
+
121
+ useEffect ( ( ) => {
122
+ dispatch ( showCart ( false ) ) ;
123
+
124
+ if ( showCardPayment ) {
125
+ cardElement = elements . getElement ( CardElement ) ;
126
+ cardElement . addEventListener ( 'change' , handleCardError ) ;
127
+
128
+ return function cleanupListener ( ) {
129
+ cardElement . removeEventListener ( 'change' , handleCardError ) ;
130
+ }
131
+ }
132
+
133
+ } , [ showCardPayment ] ) ;
134
+
135
+ return (
136
+ < >
137
+ < NavBar />
138
+ < PageHeading title = "Home / Payment" />
139
+ < section className = "section section-center" >
140
+ < div className = "container h-100" >
141
+ < div className = "d-flex justify-content-center h-100" >
142
+ < div className = "user_card content-card payment-page-content" >
143
+ < h4 className = "content-heading" > Payment Detail</ h4 >
144
+ < div className = "d-flex justify-content-center form_container auth-page-container payment-page-container" >
145
+ < form onSubmit = { handleSubmit } autoComplete = "off" >
146
+ < div className = "alert-danger" id = "card-errors" >
147
+ </ div >
148
+ < div className = "input-group mt-3" >
149
+ < select className = "form-control form-control-lg" id = "paymentType" onChange = { changePaymentMethod } >
150
+ < option value = "cod" > Cash on Delivery</ option >
151
+ < option value = "card" > Pay with Card</ option >
152
+ </ select >
153
+ </ div >
154
+ {
155
+ showCardPayment ? (
156
+ < div className = "input-group mt-3" >
157
+ < div className = "card-number" >
158
+ < CardElement options = { cardElementOptions } />
159
+ </ div >
160
+ </ div >
161
+ ) :(
162
+ ''
163
+ )
164
+ }
165
+
166
+ < div className = "d-flex justify-content-center mt-3 login_container" >
167
+ < button className = "btn login_btn" > Proceed</ button >
168
+ </ div >
169
+ </ form >
170
+ </ div >
171
+ </ div >
172
+ </ div >
173
+ </ div >
174
+ </ section >
175
+ < Sidebar />
176
+ < Cart />
177
+ </ >
178
+ )
179
+ }
180
+
181
+
182
+ export default PaymentForm ;
0 commit comments