I am trying to create a stripe checkout project but was stuck when I found that the loadStripe promise was not working fine and I have to change the code window.stripe but this is also not working .
Her is my react code :
import React, { useEffect, useRef } from "react";
import { isAuth } from "../helpers/auth";
import { useNavigate } from "react-router-dom";
import styles from "./Pricing.module.scss";
import ScriptTag from "react-script-tag";
const Stripe = require('stripe')
const stripe = window.Stripe('pk_8734579834958')
export const Pricing = () => {
const buttonValue = useRef();
const navigate = useNavigate();
const setBtnValue = (e) => {
buttonValue.current = e.target.value;
};
const checkoutHandler = async (e) => {
const btnValue = buttonValue.current;
console.log(btnValue);
fetch("http://localhost:5000/api/checkout", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
btnValue,
}),
})
.then((result) => result.json())
.then(({ sessionID }) => stripe.redirectToCheckout({ sessionID }))
.then((result) => {
console.log(result.error.message);
});
};
return (
<div>
<ScriptTag
isHydrating={true}
type="text/javascript"
src="https://js.stripe.com/v3/"
/>
<form onSubmit = {checkoutHandler}>
<button
value= 'price_bdsahfbadshb'
type="submit"
className="btn"
name="product"
onClick={setBtnValue}
>
Upgrade Now
</button>
</div>
)
}
Here is my backend code :
router.post('/checkout' , async(req,res) => {
const product = req.body;
console.log(product);
}
As you want to redirect, just try adding <script src="https://js.stripe.com/v3/"></script> into index.html (if not added) so you will able to use window.Stripe.
and remove line const Stripe = require('stripe')
if you want more clarification, go through its official documentation.
Related
I am facing an issue my user is always showing null in the backend, I don't know why.
I am following an Udemy course my tutor is saying middleware is responsible for user identification. but the problem is I typed the same code as my tutor is typing but his codes are working fine mine not.
I am using Axios from the front end to make request.
This my controller ==>
export const currentUser = async (req, res) => {
try {
const user = await User.findById(req._id).select("-password").exec();
console.log("CURRENT_USER", user); return res.json({ ok: true });
} catch (err) {
console.log(err);
}
};
This is my middleware ==>
import { expressjwt } from "express-jwt";
export const requireSignIn = expressjwt({ getToken: (req, res) => req.cookies.token, secret: process.env.JWT_SECRET, algorithms: ["HS256"], }) ;
This my front end code where I have been making request ===>
import { useEffect, useState, useContext } from "react";
import axios from "axios";
import { useRouter } from "next/router";
import { SyncOutlined } from "#ant-design/icons";
import UserNav from "../nav/userNav";
import { Context } from "../../context";
const UserRoutes = ({ children }) => {
const { state: { user } } = useContext(Context);
// state
const [ok, setOk] = useState(false);
// router
const router = useRouter();
useEffect(() => {
fetchUser();
}, []);
const fetchUser = async () => {
try {
const { data } = await axios.get("/api/current-user");
console.log(data);
if (data.ok) setOk(true);
} catch (err) {
console.log(err);
setOk(false);
router.push("/login");
}
};
return (
<>
{!ok ? (
<SyncOutlined spin className="d-flex justify-content-center display-1 text-primary p-5" />
) : (
<div className="UserNavSec">
<div className="UserNavCol1">
<div className="UserNavCont"><UserNav/></div
</div>
<div className="UserNavCol2"> {children} </div
</div>
)}
</>
);
};
export default UserRoutes;
I am using React in front-end and Node and MongoDB in Back-end. I have created a custom hook from where I am loading the data. The following is the custom hook
import { useEffect, useState } from "react";
const useItems = (id) => {
const [item, setItem] = useState([]);
useEffect(() => {
fetch(`http://localhost:5000/inventory/${id}`)
.then((res) => res.json())
.then((data) => setItem(data));
}, [id]);
return [item];
};
export default useItems;
And this is the component where I am calling the custom hook to load the data.
import React, { useEffect, useState } from "react";
import "./Inventory.css";
import { useParams } from "react-router-dom";
import useItems from "../../hooks/useItems";
const Inventory = () => {
const { id } = useParams();
const [item] = useItems(id);
const quantityDecrease = (newQuantity) => {
let quantity = parseInt(newQuantity) - 1;
const updateQuantity = { quantity };
const url = `http://localhost:5000/inventory/${id}`;
fetch(url, {
method: "PUT",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(updateQuantity),
})
.then((res) => res.json())
.then((data) => {
console.log("success", data);
alert("saved");
});
};
return (
<div>
<div className="col-lg-6">
<p className="inventory-textbox">
<strong>Quantity :</strong> {item.quantity}
</p>
</div>
<button onClick={() => quantityDecrease(item.quantity)}>
Delivered
</button>
</div>
);
};
export default Inventory;
Whenever the Delivered button is clicked the quantityDecrease function is executed and the quantity of the item is decreased by one. Now, my database is working fine. I am being able to update both client and server site but I have to reload the page in order to see the change in the ui. Is there a way I do not have to reload to see the change?
try using the item data as useEffect dependency. it may solve your problem.
On this case I am trying to show the "_id".
I made the code based on this video.
But by just looking at his API I can see that his data is little different, how can I adapt it to work with my API
import "./App.css";
import axios from "axios";
import { useEffect, useState } from "react";
const App = () => {
const [leitura, setLeitura] = useState([]);
const getLeituraData = async () => {
try {
const data = await axios.get(
"https://estufaarduino.herokuapp.com/sistema/leituras"
);
console.log(data.data);
setLeitura(data.data);
} catch (e) {
console.log(e);
}
};
useEffect(() => {
getLeituraData();
}, []);
return (
<div className="App">
{leitura.map((item) => {
return <p>{item._id}</p>;
})}
</div>
);
};
export default App;
Context
I'm building a simple web application using the MERN stack for practice. In the app, logged-in users should be able to add a new blog to the site. However, for some reason my axios post request to the backend is failing and I'm receiving a 401 error. I'm using jsonwebtoken to handle the authentication. Submitting a POST request via Insomnia works fine so I don't believe it's an issue with my endpoint. I'm running backend server locally on my machine on port 3003 and have set up a proxy so there's no issues with cors. This works fine as the blogs from the backend are displays on the frontend once a user has logged in.
I've also checked the headers and can confirm that logged-in users have a valid bearer token.
What could be causing the issue?
Frontend
I can't post any images but here's a link to the frontend view:
https://imgur.com/a/DdUlfg9
App.js
import React, { useState, useEffect } from 'react'
import Blog from './components/Blog'
import blogService from './services/blogs'
import loginService from './services/login'
import LoginForm from './components/loginForm'
import BlogForm from './components/blogForm'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [errorMessage, setErrorMessage] = useState(null)
const [newBlog, setNewBlog] = useState({
title: '',
author: '',
url: ''
})
useEffect(() => {
blogService.getAll().then(blogs =>
setBlogs( blogs )
)
}, [])
useEffect(() => {
const loggedInUser = window.localStorage.getItem("loggedBlogUser")
if(loggedInUser){
const user = JSON.parse(loggedInUser)
setUser(user)
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password
})
window.localStorage.setItem(
'loggedBlogUser', JSON.stringify(user)
)
blogService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception){
setErrorMessage('Wrong credentials')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const handleLogout = async (event) => {
event.preventDefault()
if(user){
window.localStorage.removeItem("loggedBlogUser")
setUser(null)
}
}
const handleBlogField = (event) => {
event.preventDefault()
const {name, value} = event.target
console.log(newBlog.title)
setNewBlog(prevBlog => ({
...prevBlog,
[name] : value
}))
}
const addBlog = async (event) => {
event.preventDefault()
try {
const blog = await blogService.create(newBlog)
console.log("POST REQUEST: ",newBlog)
console.log('lets geddit')
setBlogs(blogs.concat(blog))
} catch (exception){
setErrorMessage('Uh oh, try again :[')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
if(user === null){
return(
<>
{errorMessage}
<h2>Log into application</h2>
<LoginForm handleLogin={handleLogin} setUsername={setUsername} setPassword={setPassword} username={username} password={password}/>
</>
)
}
return (
<div>
<h2>blogs</h2>
{user &&
<div>
<h3>{user.username} logged in</h3>
<button onClick={handleLogout}>Logout</button>
</div>
}
<BlogForm handleSubmission={addBlog} newBlog={newBlog} handleBlogField={setNewBlog}/>
{/* <BlogForm addBlog={addBlog} title={newBlog.title} setTitle={setTitle} setAuthor={setAuthor} author={newBlog.author} url={newBlog.url} setUrl={setUrl}/> */}
{blogs.map(blog =>
<Blog key={blog.id} blog={blog} />
)}
</div>
)
}
export default App
Blogs.js
import axios from 'axios'
const baseUrl = '/api/blogs'
let token = null
//let config
const setToken = (newToken) => {
token = `bearer ${newToken}`
}
const getAll = async () => {
const response = await axios.get(baseUrl)
return response.data
}
const create = async (newObject) => {
const config = {
headers: {
Authorization: token
}
}
const response = await axios.post(baseUrl, newObject, config)
console.log(`RESPONSE: ${newObject}`)
return response.data
}
const blogService = {
getAll, setToken, create
}
export default blogService
Have you configured CORS?, in order to accept your localhost requests?
Im followin a youtube tutorial to do payments but I am stucked at a pace that axios could not post data to server
code
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Abc from './Abc';
import './index.css'
ReactDOM.render(
<Abc/>
,
document.getElementById('root')
);
Abc.js
import React from "react";
import { loadStripe } from "#stripe/stripe-js";
import {
Elements,
CardElement,
useStripe,
useElements
} from "#stripe/react-stripe-js";
import axios from "axios";
const CheckoutForm = ({ success }) => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async event => {
event.preventDefault();
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement)
});
if (!error) {
const { id } = paymentMethod;
try {
const { data } = await axios.post("/api/charge", { id, amount: 1099 });
console.log(data);
success();
} catch (error) {
console.log('error is => ',error);
}
}
};
return (
<form
onSubmit={handleSubmit}
style={{ maxWidth: "400px", margin: "0 auto" }}
>
<h2>Price: $10.99 USD</h2>
<img
src="https://images.ricardocuisine.com/services/recipes/500x675_7700.jpg"
style={{ maxWidth: "50px" }}
alt='abc'
/>
<CardElement />
<button type="submit" disabled={!stripe}>
Pay
</button>
</form>
);
};
// you should use env variables here to not commit this
// but it is a public key anyway, so not as sensitive
const stripePromise = loadStripe("pk_test_51JsQsfBbWBJ638dRkTi29yzu85fW6JAvGzbJo9f5RgOtOogcpKnzCfJo6VJoKGemEW54wxrDebWpM8V6vKJl36mC00K3JPAmHr");
const Abc = () => {
const [status, setStatus] = React.useState("ready");
if (status === "success") {
return <div>Congrats on your empanadas!</div>;
}
return (
<Elements stripe={stripePromise}>
<CheckoutForm
success={() => {
setStatus("success");
}}
/>
</Elements>
);
};
export default Abc;
charge.js
import Stripe from "stripe";
const stripe = new Stripe("sk_test_51JsQsfBbWBJ638dRR3Iryb907XNtHaeVYhtCRp6SDmaiWmQg51ys2wdB3z6HJ8svutnA8HPMp5yEtdxTSParn3uN00Xb3PJd4o");
export default async (req, res) => {
const { id, amount } = req.body;
try {
const payment = await stripe.paymentIntents.create({
amount,
currency: "USD",
description: "Delicious empanadas",
payment_method: id,
confirm: true
});
console.log(payment);
return res.status(200).json({
confirm: "abc123"
});
} catch (error) {
console.log(error);
return res.status(400).json({
message: error.message
});
}
};
but this is giving me error when submitting xhr.js:210 POST http://localhost:3000/api/charge 404 (Not Found)
Hierarchy
any help will be appreciated.I was following https://www.youtube.com/watch?v=WTUYem2IxLA&ab_channel=LeighHalliday tutorial
Assuming you have Next.js set up properly, your api folder needs to be in the /pages directory.
https://nextjs.org/docs/api-routes/introduction