Skip to content

Commit 01deb86

Browse files
author
WebDeveloperGuide
committed
Basic payment method structure added.
1 parent 671af09 commit 01deb86

File tree

8 files changed

+277
-154
lines changed

8 files changed

+277
-154
lines changed

web_panel/package-lock.json

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web_panel/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"@stripe/react-stripe-js": "^1.7.0",
7+
"@stripe/stripe-js": "^1.25.0",
68
"@testing-library/jest-dom": "^5.16.2",
79
"@testing-library/react": "^12.1.4",
810
"@testing-library/user-event": "^13.5.0",
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
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;

web_panel/src/index.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,4 +1003,25 @@ a, a:hover {
10031003

10041004
.input-group-address{
10051005
width: 150px;
1006+
}
1007+
1008+
.card-number{
1009+
width: 100%;
1010+
}
1011+
1012+
.StripeElement {
1013+
border: 1px solid #ced4da;
1014+
padding: 0.5rem 1rem;
1015+
font-size: 1.25rem;
1016+
line-height: 1.5;
1017+
border-radius: 0.3rem;
1018+
width: 400px;
1019+
}
1020+
1021+
.payment-page-content{
1022+
min-width:470px;
1023+
}
1024+
1025+
.payment-page-content .form-control{
1026+
min-width:400px;
10061027
}

0 commit comments

Comments
 (0)